Можно ли рассчитать функцию camera.lookAt по углу и оси вращения, учитывая заданную точку и камеру вперед? - PullRequest
2 голосов
/ 18 апреля 2019

Я пытаюсь понять функцию camera.lookAt, созданную в Three.js, и реализовать свою собственную.

Я использую глаз = положение камеры, цель = взгляд цели в точку, и вверх всегда (0, 1, 0). Друг предложил, что очевидным способом поворота камеры, чтобы посмотреть на точку в пространстве, было бы получить желаемое движение вперед путем вычисления цели - глаза и вычисления угла между вектором движения камеры (0, 0, -1) и цель вперед (используя метод atan2, описанный в этих ответах ), и это угол поворота. Я был бы в состоянии найти ось вращения, вычисляя перекрестное произведение вектора вперед и желаемого направления вперед. Я бы использовал функцию типа setFromAxisAngle , чтобы получить результирующий кватернион.

Пытался нарисовать здесь:

enter image description here

Будет ли это работать в теории? При тестировании по каноническому методу lookAt , который использует глаз, вверх и цель и выполняет z = (глаз - цель), x = крест (вверх, z), y = крест (x, z) - (также, почему это глаз - цель вместо цели - глаз?) - Я вижу маленький (<0,1 различия). </p>

1 Ответ

1 голос
/ 18 апреля 2019

Лично я считаю, что реализация метода three.js Matri4.lookAt() несколько сбивает с толку. Это также не тот класс, его нужно поместить в Matrix3. В любом случае, более ясную реализацию можно найти в MathGeoLib, библиотеке C ++ для линейной алгебры и манипулирования геометрией для компьютерной графики.

https://github.com/juj/MathGeoLib/blob/ae6dc5e9b1ec83429af3b3ba17a7d61a046d3400/src/Math/float3x3.h#L167-L198 https://github.com/juj/MathGeoLib/blob/ae6dc5e9b1ec83429af3b3ba17a7d61a046d3400/src/Math/float3x3.cpp#L617-L678

Метод lookAt() должен сначала построить ортонормированный линейный базис A (localRight, localUp, localForward) для локального пространства объекта. Затем он строит ортонормированный линейный базис B (worldRight, worldUp, targetDirection) для желаемой ориентации цели. Основная задача lookAt() состоит в том, чтобы отобразить из базиса A в B. Это делается путем умножения m1 (базис B) на обратное значение m2 (базис A). Поскольку эта матрица ортонормирована, обратное вычисляется простым транспонированием.

m1.makeBasis( worldRight, worldUp, targetDirection );
m2.makeBasis( localRight, localUp, localForward );

this.multiplyMatrices( m1, m2.transpose() );

this ссылки на экземпляр класса матрицы 3x3.

Я предлагаю вам внимательно изучить хорошо документированный код C ++, чтобы понять каждый шаг метода.

...