Почему моя камера вращается вокруг точки с этой математикой? - PullRequest
5 голосов
/ 02 февраля 2012

Моя камера вращается вокруг точки, когда я пытаюсь изменить ориентацию.Если я поверну камеру, скажем, на 30 градусов по оси Y, а камера не будет смотреть на 30 градусов вправо, камера будет вращаться вокруг точки, на которую она смотрела.

o is the camera, A and B are 3D models. The lines show line-of-sight.
This is what I expect:
     A    B
     | > /
     |  /
     | /
     |/
     o

This is what actually happens:
     A    B
     |\
     | \
     |  \
     | > \
          o

Теперь из моегопонимая, что для того, чтобы переместить камеру, я должен перевернуть мир на обратную величину.Поэтому, если я хочу переместиться на +1 по оси Z, я перевожу мир -1 на ось Z.Поскольку я использую кватернионы для представления ориентации, я использую инверсию кватерниона камеры (поскольку ориентации всегда являются единичными кватернионами, я оптимизирую с помощью сопряжения вместо вычисления обратного), чтобы вращать мир на нужную величину.* Вот как я конвертирую кватернион в матрицу, где q - инвертированный кватернион:

[1 - 2 * (q.y * q.y + q.z * q.z)   2 * (q.x * q.y - q.w * q.z)       2 * (q.x * q.z + q.w * q.y)         0]
|2 * (q.x * q.y + q.w * q.z)       1 - 2 * (q.x * q.x + q.z * q.z)   2 * (q.y * q.z - q.w * q.x)         0|
|2 * (q.x * q.z - q.w * q.y)       2 * (q.y * q.z + q.w * q.z)       1 - 2 * (q.x * q.x + q.y * q.y)     0|
[0                                 0                                 0                                   1]

После этого я устанавливаю компонент перевода матрицы:

[...   ...   ...  -x]
|...   ...   ...  -y|
|...   ...   ...  -z|
[0     0     0     1]

Инаконец, я умножаю это на стек матрицы представления модели, а затем отрисовываю все мои объекты.Я уверен, что эта математика верна, но она не дает ожидаемых результатов.Очевидно, что прямой и правый векторы являются проблемой, поэтому мой единственный вопрос - почему они ошибаются и как их следует устанавливать, если я хочу получить ожидаемые результаты.Спасибо.

РЕДАКТИРОВАТЬ: Я нашел решение из класс камеры этого парня кватерниона .Сначала я строю матрицу вращения, как раньше, но затем я беру векторы столбцов матрицы из первого, второго и третьего столбцов (xa, ya и za соответственно).Затем я устанавливаю трансляционную составляющую матрицы следующим образом:

[...  ...  ...  -xa.dotProduct(cameraPos)]
|...  ...  ...  -ya.dotProduct(cameraPos)|
|...  ...  ...  -za.dotProduct(cameraPos)|
[...  ...  ...  ...                      ]

Затем полученная матрица может быть умножена на стек матриц вида модели, и она отлично работает.

Ответы [ 2 ]

1 голос
/ 02 февраля 2012

РЕДАКТИРОВАТЬ: Я нашел решение из класса камеры кватерниона этого парня.Сначала я строю матрицу вращения, как раньше, но затем я беру векторы столбцов матрицы из первого, второго и третьего столбцов (xa, ya и za соответственно).Затем я устанавливаю трансляционный компонент матрицы следующим образом:

[...  ...  ...  -xa.dotProduct(cameraPos)]
|...  ...  ...  -ya.dotProduct(cameraPos)|
|...  ...  ...  -za.dotProduct(cameraPos)|
[...  ...  ...  ...                      ]

Затем полученная матрица может быть умножена на стек матриц вида модели, и она отлично работает.

Да,это именно то, что я бы предложил, только немного по-другому.Вы должны понимать, что в OpenGL нет камеры, но вместо этого вы просто перемещаете мир в противоположном направлении, поэтому вам нужно найти матрицу обратного преобразования.

Камера просто вращается и движется.Это делает вещи очень простыми.Обратная сторона трансляции - это точно такой же вектор с противоположным знаком, а инверсия матрицы вращения - это ее транспонирование (обмен столбцов и строк).Теперь посмотрим на матрицу однородного преобразования, как их использует OpenGL:

R t
0 1

Верхний левый 3 × 3 - это вращательная часть, самый правый столбец - вектор перевода.Я думаю, что остальные вы уже сами поняли.

0 голосов
/ 02 февраля 2012

Если честно, попытка найти матрицу для умножения на матрицу представления модуля действительно сложна и очень подвержена ошибкам.Здесь много путаницы и особых случаев.Например, если вы смотрите на 90 градусов вверх, две ваши оси становятся одинаковыми.Логическая проблема заключается в следующем: если вы откидываете голову назад и проходите через верхнюю точку, ваш вектор роста должен быть инвертирован, верно?Но что, если вы пропустите это на 0,0001 градус?тогда вы должны повернуть голову вокруг этой точки, чтобы ваш вектор роста все еще работал.

На мой взгляд, лучший способ - подойти к проблеме с другой точки зрения.Предположим, есть два случая:

  • Перевернуть невозможно:
    • Сохраните точку для местоположения вашей камеры и широту / долготу для направления.С помощью простых операций sin / cos вы можете получить вектор направления.Ваш верхний вектор (0, 1, 0)
    • Поворот - это просто изменение широты и долготы
  • Возможен перевернутый вниз:
    • Кроме камерыместоположение, сохраняйте оба вертикальных и целевых вектора.
    • При повороте вычислите вправо = цель x вверх, а затем измените цель на x * right + y * up
    • Затем необходимо нормализовать целевой вектор ивычислить новый.Тем не менее, множество дел для обработки.

После всего этого вы просто звоните gluLookAt.

...