DirectX: преобразование координат (screen->world)
| |
IG_Rich | Дата: Воскресенье, 22 Мая 2016, 16:13 | Сообщение # 1 |
уже был
Сейчас нет на сайте
| День добры, товарищи! Возникла проблема с обработкой мыши: требуется преобразовать их из координат экрана,в мировые координаты. Для начала создание матриц: C++
Код //проекция D3DXMatrixOrthoLH(&matProj, 1024, 768, 1, 5000); g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj); //вида D3DXVECTOR3 pEye(2000.0f, 2000.0f, 2000.0f), pAt(0.0f, 0.0f, 0.0f), pUp(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&matView, &pEye, &pAt, &pUp); g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView); Мировая матрица единичная и ничего не делает. Координаты мыши получаю относительно левого верхнего угла экрана, его координаты от нуля до ширины экрана(по x),и от нуля до высоты(по y). При нажатии ЛКМ требуется переместить камеру в точку нажатия, то есть вектор pAt примет значение того,куда мы кликнули,ну а pEye сместится вместе с ним. Поиски по куче статей и ресурсов ничего не дали, всё равно не могу понять как правильно преобразовывать. Пытался через D3DXVec3Unproject: C++
Код D3DXMATRIX view, proj, world; D3DXVECTOR3 p1; g_pD3DDevice->GetTransform(D3DTS_PROJECTION, &proj); g_pD3DDevice->GetTransform(D3DTS_VIEW, &view); g_pD3DDevice->GetTransform(D3DTS_WORLD, &world); D3DVIEWPORT9 pViewport = { 0, 0, 100, 100, 0.0f, 1.0f }; g_pD3DDevice->GetViewport(&pViewport); D3DXVec3Unproject(&p1, &D3DXVECTOR3(g_MouseXPos, g_MouseYPos, 0), &pViewport, &proj, &view, &world); но то-же не получается. Что вообще эта функция возвращает?Вектор из нашего экрана в точку куда кликнули(в мире),в мировых координатах? Так-же пытался сам через скудные знания в геометрии и линейной алгебре вычислить вектора,в итоге получилось что-то вроде: C++
Код //destination - положение курсора мыши относительно лев.верхнего угла temp.x=(destination.x-WNDWIDTH/2); temp.y=(destination.y-WNDHEIGHT/2); temp.z = 0; result.x = pAt.x - temp.x / sqrt(2) + temp.y; result.y = 0; result.z = pAt.z+temp.x / sqrt(2) + temp.y; В итоге все почти верно,лишь с небольшой погрешностью, что говорит о том, что вероятно я напутал что то с коэффициентами. Прошу вашей компетентной помощи.
|
|
| |
Archido | Дата: Вторник, 24 Мая 2016, 12:38 | Сообщение # 2 |
Сэнсэй
Сейчас нет на сайте
| IG_Rich, Цитата IG_Rich ( ![Ссылка на цитируемый текст](/.s/img/fr/ic/11/lastpost.gif) ) но то-же не получается. Что вообще эта функция возвращает?Вектор из нашего экрана в точку куда кликнули(в мире),в мировых координатах? Да, именно вектор в мировых координатах. Чтобы получить позицию, в которую нужно переместить камеру, требуется еще получить координату глубины(z) - считать пересечение луча с геометрией и искать ближайшую точку пересечения, либо прочитать ее напрямую из depth буфера.
C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
|
|
| |
falcoware | Дата: Вторник, 24 Мая 2016, 12:42 | Сообщение # 3 |
старожил
Сейчас нет на сайте
| IG_Rich,
Код void CScene::Screen2World(int x, int y, point3d &ptRes) { if(!IniSet.b3DPerpectiveOrtho){ ptRes.x = IniSet.ptCamPos.x + 2.f * IniSet.fOrthoX * (float(x - nScreenSzX * 0.5f) / ((float)nScreenSzX)); ptRes.y = IniSet.ptCamPos.y - 2.f * IniSet.fOrthoY * (float(y - nScreenSzY * 0.5f) / ((float)nScreenSzY)); ptRes.z = IniSet.ptCamTarget.z; }else{ float fx, fy; point3d vz; sub_vectors(&vz.x, &IniSet.ptCamTarget.x, &IniSet.ptCamPos.x); float fLen = vec_length(&vz.x);
float d = fLen * m_fCameraAngle;
x -= nScreenSzX / 2; y -= nScreenSzY / 2;
fx = - d * x / ((float)nScreenSzX * 0.5f) * pixel_sz; fy = - d * y / ((float)nScreenSzY * 0.5f);
point3d vy = { 0.f, 1.f, 0.f }; point3d vx; norm_vect(&vz.x);
cross_prod(&vx.x, &vy.x, &vz.x); norm_vect(&vx.x);
cross_prod(&vy.x, &vz.x, &vx.x);
scale_vect(&vy.x, &vy.x, fy); scale_vect(&vx.x, &vx.x, fx);
add_vectors(&ptRes.x, &IniSet.ptCamTarget.x, &vy.x); add_vectors(&ptRes.x, &ptRes.x, &vx.x); } }
|
|
| |
|