Эй, ребята, я пытаюсь создать класс Camera, который использует lookAt из библиотеки glm. У меня есть 4 точки, первая — это глаз, это положение камеры в пространстве, вторая — это вид, это точка, на которую смотрит камера, третья — это верх, который устанавливает ориентацию камеры. и четвертая сторона — это перекрестное произведение взгляда — глаз и глаз.
Итак, в итоге я получил базу из 3 векторов, каждый из которых имеет происхождение в глазной точке. Я получил систему координат камеры.
В моем классе камеры я хочу иметь возможность вращаться вокруг системы координат камеры, а не системы координат мира. Итак, что я делаю, это вращаюсь вокруг одной из осей системы координат камеры.
Я создаю класс с начальными значениями следующим образом:
void Observer::initialize(glm::vec3 eye, glm::vec3 look, glm::vec3 upp, glm::vec3 side)
{
this->eye = eye; // (0.0, 0.0, 0.0)
this->look = look; // (0.0, 0.0, -1.0)
this->upp = upp; // (0.0, 1.0, 0.0)
this->side = side; // (1.0, 0.0, 0.0)
}
Например, когда я хочу повернуть систему координат вокруг оси x, я вызываю функцию из glm следующим образом:
void Observer::pitch(GLfloat pitch)
{
glm::mat4 rotate(1.0f);
rotate = glm::rotate(rotate, pitch, side - eye);
look = glm::vec3(rotate * glm::vec4(look, 1.0f));
upp = glm::vec3(rotate * glm::vec4(upp, 1.0f));
}
До сих пор я понимаю, что все мои точки все еще образуют систему координат для камеры, и все векторы перпендикулярны друг другу.
Но затем я использую эти очки, полученные с помощью функции lookAt, для позиционирования камеры в мире.
glm::mat4 view = glm::lookAt(eye, look, upp);
И умножьте эту матрицу на матрицу вида модели из OpenGL
Если я начинаю много вращаться, камера после нескольких вращений «отражает» вращение, как будто я вращаюсь другим способом (я не знаю, как лучше описать то, что действительно происходит, = s).
Я действительно не понимаю, что происходит. Я должен нормализовать векторы после применения поворота? У меня проблема с блокировкой карданного подвеса (я мало знаю о блокировке карданного подвеса)?
Когда вы выполняете инкрементные повороты на векторах, числовые ошибки увеличиваются. Когда ошибка приводит к тому, что векторы «вверх» и «взгляд» указывают почти в одном и том же направлении или напротив друг друга, вычисление преобразования камеры нестабильно, и могут произойти странные вещи. Замок карданный. Изменения длины вызывают разные проблемы.
Решение, которое сработало для меня, состоит в том, чтобы повторно ортогонализировать векторы «вверх» и «смотреть» после каждого поворота. Чтобы сделать это, вычислите их перекрестное произведение L, затем отрегулируйте (действительно замените) вектор роста, пересекая L с помощью lookAt. После всего этого заново нормализуйте как длину, так и длину.
Хотя нормализация-ортогонализация является быстрой операцией, вам не обязательно делать это при каждом движении камеры.
Обратите внимание, что когда вы исправляете векторы, как это, вы фактически выполняете часть вычисления матрицы lookAt, поэтому подумайте о реализации своего собственного, чтобы избежать ненужного перекрестного произведения. Смотрите, например эта предыдущая так статья на эту тему.
Других решений пока нет …