根据摄像机位置查找前向矢量

Find Forward Vector Based on Camera Location

对于我正在进行的项目,我试图让用户根据他们在屏幕上滑动的方向旋转立方体。我有这个工作,除了立方体旋转的方向。

例如,我的前向向量从 ( 0, 0, -1 ) 开始。但是,一旦我将立方体沿某个方向旋转 90 度,前向矢量就会发生变化。这是我期望发生的事情,但对我正在做的事情提出了挑战。

我设置了代码来确定相机的方向,方法是像这样检查相机是否向前...

GLKVector3 forward = [ m_camera getForwardVector ];
if ( fabsf( forward.x ) > fabsf( forward.z ) ) {
    // Need forward vector to be in x-direction
    // Rotate cube around axis ( 0.0f, 0.0f, 1.0f );
} else {
    // Need forward vector to be in z-direction
    // Rotate cube around axis ( 1.0f, 0.0f, 0.0f );
}

我想做的是围绕指定的轴旋转立方体。但是,在多次旋转立方体后,矢量位置与世界位置不同,因此由于矢量位置发生变化,它无法正确旋转。

我的立方体旋转存储在四元数中。那么有没有一种方法可以根据相机的观看位置来确定哪个向量是"forward"向量?

如果有帮助的话,这是我的轮换代码。谢谢!

- ( void ) rotate: ( GLKVector3 ) axis withAngle: ( GLfloat ) angle {
    [ self rotate: GLKQuaternionMakeWithAngleAndVector3Axis( GLKMathDegreesToRadians( angle ), axis ) ];
}

- ( void ) rotate: ( GLKQuaternion ) quat {
    m_rotation = GLKQuaternionNormalize( GLKQuaternionMultiply( m_rotation, quat ) );
}

好的,在阅读了很多有关 Whosebug 的内容后,我想出了一个解决我的问题的方法,我想分享它以防其他人遇到困难。

我在正确的轨道上,但只需要做一些小的改变。首先是旋转方法。在我的项目中,我围绕我的对象局部轴旋转。我把它改成这样绕世界轴旋转。

- ( void ) rotate: ( GLKVector3 ) axis withAngle: ( GLfloat ) angle {
    // THIS WILL ROTATE AROUND THE WORLD AXIS
    m_rotation = GLKQuaternionMultiply( GLKQuaternionMakeWithAngleAndAxis( GLKMathDegreesToRadians( angle ), axis.x, axis.y, axis.z ), m_rotation );


    // THIS WILL ROTATE AROUD THE LOCAL AXIS
    // m_rotation = GLKQuaternionMultiply( m_rotation, GLKQuaternionMakeWithAngleAndAxis( GLKMathDegreesToRadians( angle ), axis.x, axis.y, axis.z ) );
}

现在,我可以绕世界轴旋转了。然后当我旋转时,我可以像这样使用前向矢量。

GLKVector3 forward = [ m_camera getCurrentViewPosition ];
if ( fabsf( forward.x ) > fabs( forward.z ) ) {
    m_rotateZ = ( forward.x < 0 ) ? -ROTATION_AMOUNT : ROTATION_AMOUNT;
    m_shouldRotateZ = true;
} else {
    m_rotateX = ( forward.z < 0 ) ? ROTATION_AMOUNT : -ROTATION_AMOUNT;
    m_shouldRotateX = true;
}
m_totalRotation = 0;

我检查了向量分量的长度。在 x 较长的地方,前向矢量在 x 方向,因此我可以绕 z 轴旋转。

我希望这可以清除一些东西,并可能在将来帮助某人。如果您有任何问题,请随时发表评论,我会帮助清理更多内容。