PDA

Просмотр полной версии : Реализация метода камеры — lookAt(x,y,z)


gr_crd
17.02.2011, 21:09
Потребовалось реализовать метод lookAt для камеры.
В данный момент управление камерой (поворот) осуществляется
с помощью установки значений свойств rotationX, rotationY, rotationZ

Такое управление камерой не очень удобно, хочется научить камеру
'смотреть' в определенную точку.

т.е. требуется следующее:

/**
*
* @param px координата точки по X
* @param py координата точки по Y
* @param pz координата точки по Z
*/
public function lookAt(px:Number,py:Number,pz:Number):void
{
// требуется получить значения поворота по осям X,Y,Z
resultRotation:V3d; //

resultRotation.x=rx;
resultRotation.y=ry;
resultRotation.z=rz;
//
}


После прочтения соответствующей литературы картина прояснилась,
но на одном этапе осталась загвоздка.

Вот об этом подробнее.

Шаг 1

Камера расположена в точке (0,0,0)
Есть три вектора. Up, Forward, Right.

Forward - куда камера 'смотрит' в данный момент
Up - вектор, направленный вверх от камеры.
Right - вектор, направленный вправо.

В данный момент они совпадают с осями X,Y,Z

Далее, вызываем метод lookAt() , передаем позицию точки Target
Target - точка, на которую должна 'посмотреть' камера.

Результатом вычислений метода должны стать значения поворота
по осям X, Y, Z

http://www.dr-life.idhost.kz/temp/1.png

Шаг 2

Для начала выполним поворот в плоскости ZX вокруг оси Y
В этом шаге такой поворот эквивалентен повороту в 2D

для этого определяю вектор Target2d, затем нормализую.
Насколько я помню, скалярное произведение ( Dot Product )
Fwd и NormalizedTarget2D даст угол между ними.
Это угол a.

http://www.dr-life.idhost.kz/temp/2.png

Шаг 3

Собственно, сам поворот вокруг Y на угол a
Поворот применяется к Right и Forward и мы получаем значение rotationY
( Forward можно не поворачивать а Forward = NormalizedTraget2D, в принципе результат будет аналогичен )

т.е. в данный момент камера уже смотрит на Target2d (7,0,6);

http://www.dr-life.idhost.kz/temp/3.png

Шаг 4

Ок, теперь шаг, на котором и возник вопрос.

Нахожу также NormalizedTarget, далее произведение Fwd,NormalizedTarget
Получаю угол b.

Далее необходимо выполнить поворот вокруг вектора Right на угол b

Зная угол поворота по b вокруг Right, мне нужно узнать
угол поворота вокруг осей X и Z.
Проще говоря, получить значения rotationX, rotationZ.

http://www.dr-life.idhost.kz/temp/4.png

вот такой требуется результат

http://www.dr-life.idhost.kz/temp/5.png

основной вопрос:

Зная угол поворота по b вокруг Right, мне нужно узнать
угол поворота вокруг осей X и Z.
Проще говоря, получить значения rotationX, rotationZ.

Думал насчет вращения Fwd вокруг Right, но непонятно, значит ли это,
что матрицу вращения по Y нужно умножить на матрицу вращения вокруг Right...
опять же, матрица вращения вокруг Right неизвестна...