4

所以我目前使用四元数来存储和修改我的 OpenGL 场景中对象的方向,以及相机的方向。当直接旋转这些对象时(即说我想围绕 Z 轴旋转相机 Z 量,或者我想围绕 X 轴旋转对象 X,然后沿其局部 Z 轴平移它 T),我有没问题,所以我只能假设我的基本轮换代码是正确的。

但是,我现在正在尝试实现一个功能,使我的相机在空间中的任意点轨道上运行,并且很难做到这一点。到目前为止,这是我想出的,它不起作用(这发生在 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();

最终发生的事情是相机围绕其他点旋转——当然不是物体,但显然也不是它本身,就好像它以螺旋形路径在空间中循环一样。

所以这显然不是让相机围绕一个点运行的方法,但什么是?

4

1 回答 1

4

我将首先在球坐标中对相机进行操作,并根据需要转换为四元数。

鉴于以下假设:

  • 相机没有胶卷
  • 您正在查看的点是 [x, y, z]
  • 你有偏航角,俯仰角
  • [0, 1, 0] 是“向上”

以下是计算一些重要值的方法:

  • 视图向量:v = [vx, vy, vz] = [cos(yaw)*cos(pitch), sin(pitch), -sin(yaw)*cos(pitch)]
  • 相机位置:p = [x, y, z] - r*v
  • 右向量:v 与 [0, 1, 0] 的叉积
  • 上向量:v 与右向量的叉积
  • 您的视图四元数是 [0, vx, vy, vz] (这是具有 0 w 分量的视图向量)

现在在您的模拟中,您可以对俯仰/偏航进行操作,这非常直观。如果要进行插值,请将pitch+yaws前后转换为四元数并进行四元数球面线性插值。

于 2013-03-12T18:45:17.707 回答