四元数旋转不起作用

Jar*_*ett 5 c++ 3d camera rotation quaternions

我刚刚开始使用Quaternions,但是我在使用Quaternions使一个简单的FPS相机正常工作时遇到了一些烦人的困难.

基本上,每当我尝试移动鼠标时,我在屏幕上绘制的三角形变得疯狂,并且在屏幕上移动的速度比我看到的要快.移动键(wsad)按预期工作,UNTIL我移动鼠标,然后它全部搞砸了.我认为问题在于轮换,但过去几天我一直在倾向于这个问题但无济于事.

这是一个正在发生的事情的视频:四元数测试视频

  • 要查看鼠标输入,请从头开始观看.
  • 要查看键盘输入(前进,后退等),请跳至0:51秒.

仅供参考,以下是我正在使用的3个主要类:
Quaternion.h
CameraSceneNode.h
CameraSceneNode.cpp

最相关的部分是tick()(我更新旋转四元数)和render()(我渲染'相机',其中包括旋转和平移场景).

这是tick()方法:

void CameraSceneNode::tick(float32 time) {
    // movement direction
    if (movement_[MOVE_DIR_FORWARD] == 1)
        pos_ += rotation_ * vmath::Vector3f(0, 0, -moveSpeed_ * time);

    if (movement_[MOVE_DIR_BACKWARD] == 1)
        pos_ += rotation_ * vmath::Vector3f(0, 0, moveSpeed_ * time);

    if (movement_[MOVE_DIR_LEFT] == 1)
        pos_ += rotation_ * vmath::Vector3f(-moveSpeed_ * time, 0, 0);

    if (movement_[MOVE_DIR_RIGHT] == 1)
        pos_ += rotation_ * vmath::Vector3f(moveSpeed_ * time, 0, 0);

    // rotation
    if (xRot_ != 0) {
        Quaternion quatRotation = Quaternion();
        quatRotation.buildFromAxisAngle(1, 0, 0, (xRot_ * time * rotSpeed_) *         math::DEGTORAD);
        //quatRotation.normalize();
        rotation_ = rotation_ * quatRotation;
        xRot_ = 0;
        rotation_.normalize();
    }
    if (yRot_ != 0) {
        Quaternion quatRotation = Quaternion();
        quatRotation.buildFromAxisAngle(0, 1, 0, (yRot_ * time * rotSpeed_) *         math::DEGTORAD);
        //quatRotation.normalize();
        rotation_ = quatRotation * rotation_;
        yRot_ = 0;
        rotation_.normalize();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是render()方法:

void CameraSceneNode::render() {
    if (isActive()) {
        float32 matrix[16];
        rotation_.fillMatrix(matrix);

        glMultMatrixf(&matrix[0]);

        //glRotatef(rotYTest, 0, 1, 0);
        //glRotatef(rotXTest, 1, 0, 0);

        glTranslatef(-pos_.x, -pos_.y, -pos_.z);
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,在我打电话render()给相机之前,我运行了这段代码:

glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Run Code Online (Sandbox Code Playgroud)

这两个tick(..)render()被称为从我的游戏主循环每一帧.有在功能CameraSceneNode类接受在移动方向和照相机旋转(即改变即改变movement_缓冲器或xRot_yRot_).

如果这还不够,我很抱歉.一些功能(如fillMatrix(..))在我上面引用的3 .h/.cpp文件中定义.我已经多次检查了Quaternion类,它看起来像是正确的.但话说回来,我使用的所有代码对我来说都是正确的,所以谁知道:S

这完全是我的智慧结束.如果有人能说清楚为什么这不起作用,我会非常感激!!

干杯

贾勒特

小智 6

从它的外观来看,你逐渐累积你的每一个刻度(rotation_ = quatRotation*rotation_;),这首先是有意义的,因为你所做的只是稍微调整旋转,因此它应该是安全的旋转到已经存在的程度,对吧?

但是,每次旋转(通过你正在做的事情),你实际上每次都会稍微改变旋转轴,这就是你看到这种不稳定行为的原因.

我建议的是跟踪整个X/Y旋转,在鼠标移动时递增或递减,然后每次直接计算旋转而不是累积旋转.因此,如果您在X中旋转了1度15次,那么您当前的代码基本上是"在X中旋转1度,在X中添加旋转1度等".我建议的是跟踪单个旋转因子X,并且当它改变时设置旋转直接"旋转13度,旋转14度,旋转15度等".

从你的视频来看,旋转看起来也太大了,所以你可能希望将最终旋转比例调整为10或50(或其他).

我可能会离开,但我在3D编码冒险中遇到过类似的事情,这是我最好的建议.如果这不是问题,因为您正在处理相机旋转,您可能需要使用矩阵反转.更糟糕的是,看看模型视图矩阵是否有某些旋转,看它是否符合你的期望(痛苦,但也是一个有价值的调试练习).