вторник, 19 апреля 2011 г.

Координаты курсора в 3D

Задача: Определить координаты мыши в 3D пространстве и построить луч для трассировки.

Решение:
Часть 1 Определение координат мыши.


cursor_x, cursor_y - координаты мыши в пространстве окна.
width, height - высота и ширина окна.
matProjection - матрица проекции.
matView - матрица вида.
matWorld - мировая матрица.

Теория:

Получаем координаты мыши в пространстве окна, переводим их в промежуток [-1; 1] затем масштабируем на коэффициенты по х (matProjection._11) и у (matProjection._22).  z устанавливаем в 1.0f (передняя плоскость отсечения равна 1.0f) Для лучшего понимания процесса смотрите аксонометрические преобразования.

Код:

float new_x = (-1.0f + 2.0f * cursor_x  / width) / matProjection._11;
float new_y = (1.0f - 2.0f * cursor_y / height) / matProjection._22;
float new_z = 1.0f;

Часть 2 Строим луч.

Теория:

Переводим полученные координаты в пространство объекта, для этого получаем текущую видовую матрицу и мировую матрицу объекта. Перемножаем их, полученный результат инвертируем. Это и будет матрица трансформации точки в пространство объекта, который собираемся проверять на пересечение с лучом. Преобразуем вектор (new_x, new_y, new_z) с помощью инвертированной матрицы, результат будет вектором направления луча. Точку начала луча установим в позицию х, y, z инвертированной матрицы.

Код:

invMat = Inverse(matWorld * matView);
ray.direction.x = new_x * invMat._11 + new_y * invMat._21 + new_z * invMat._31;
ray.direction.y = new_x * invMat._12 + new_y * invMat._22 + new_z * invMat._32;
ray.direction.z = new_x * invMat._13 + new_y * invMat._23 + new_z * invMat._33; 
ray.position.x = invMat._41;
ray.position.y = invMat._42;
ray.position.z = invMat._43;

0 коммент.:

Отправить комментарий