OpenGL - камера, вращающаяся вокруг точки с кватернионами

Поэтому в настоящее время я использую кватернионы для хранения и изменения ориентации объектов в моей сцене OpenGL, а также ориентации камеры. При прямом вращении этих объектов (т. Е. Говоря, что я хочу повернуть величину Z камеры вокруг оси Z, или я хочу повернуть объект X вокруг оси X, а затем переместить его T вдоль его локальной оси Z), у меня есть нет проблем, поэтому я могу только предположить, что мой основной код вращения верен.

Однако сейчас я пытаюсь реализовать функцию, которая заставит мою камеру вращаться вокруг произвольной точки в пространстве, и мне это довольно сложно. Вот то, что я придумал до сих пор, но это не работает (это происходит в классе Camera).

    //Get the inverse of the orientation, which should represent the orientation 
    //"from" the focal point to the camera
    Quaternion InverseOrient = m_Orientation;
    InverseOrient.Invert();

    ///Rotation
    //Create change quaternions for each axis
    Quaternion xOffset = Quaternion();
    xOffset.FromAxisAngle(xChange * m_TurnSpeed, 1.0, 0.0, 0.0);

    Quaternion yOffset = Quaternion();
    yOffset.FromAxisAngle(yChange * m_TurnSpeed, 0.0, 1.0, 0.0);

    Quaternion zOffset = Quaternion();
    zOffset.FromAxisAngle(zChange * m_TurnSpeed, 0.0, 0.0, 1.0);

    //Multiply the change quats into the inversed orientation quat
    InverseOrient = yOffset * zOffset * xOffset * InverseOrient;

    //Translate according to the focal distance
    //Start with a vector relative to the position being looked at
    sf::Vector3<float> RelativePos(0, 0, -m_FocalDistance);
    //Rotate according to the quaternion
    RelativePos = InverseOrient.MultVect(RelativePos);

    //Add that relative position to the focal point
    m_Position.x = m_FocalPoint->x + RelativePos.x;
    m_Position.y = m_FocalPoint->y + RelativePos.y;
    m_Position.z = m_FocalPoint->z + RelativePos.z;

    //Now set the orientation to the inverse of the quaternion 
    //used to position the camera
    m_Orientation = InverseOrient;
    m_Orientation.Invert();

В конечном итоге происходит то, что камера вращается вокруг какой-то другой точки - конечно, не объекта, но, по-видимому, и самого себя, как если бы она двигалась в пространстве по спирали.

Итак, это явно не способ обращения камеры по орбите вокруг точки, но что это такое?


person GarrickW    schedule 11.01.2013    source источник


Ответы (1)


Я бы сначала оперировал камерой в сферических координатах и ​​при необходимости конвертировал в кватернионы.

Учитывая следующие предположения:

  • У камеры нет рулона
  • Вы смотрите на [x, y, z]
  • У вас есть рыскание, углы тангажа
  • [0, 1, 0] is "up"

Вот как можно рассчитать некоторые важные значения:

  • Вектор обзора: v = [vx, vy, vz] = [cos (рыскание) * cos (шаг), sin (шаг), -sin (рыскание) * cos (шаг)]
  • Расположение камеры: p = [x, y, z] - r * v
  • Правый вектор: произведение v на [0, 1, 0]
  • Вектор вверх: векторное произведение v с правильным вектором
  • Ваш кватернион вида [0, vx, vy, vz] (это вектор вида с 0 w-компонентом)

Теперь в вашей симуляции вы можете работать с тангажом / рысканием, которые довольно интуитивно понятны. Если вы хотите выполнить интерполяцию, преобразуйте до и после шага + рыскания в кватернионы и выполните сферическую линейную интерполяцию кватернионов.

person Jacob Parker    schedule 12.03.2013