我刚刚开始使用四元数,但是让一个简单的 FPS 相机使用四元数正常工作时遇到了一些烦人的困难。
基本上,每当我尝试移动鼠标时,我在屏幕上绘制的三角形就会变得疯狂,并且在屏幕上的移动速度比我看到的要快。移动键(wsad)按预期工作,直到我移动鼠标,然后一切都搞砸了。我认为问题出在轮换上,但过去几天我一直在倾注这个问题,但无济于事。
这是正在发生的事情的视频:四元数测试视频
- 要查看鼠标输入,请从头开始观看。
- 要查看键盘输入(前进、后退等),请跳至 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();
}
}
这是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);
}
}
另外,在我调用render()
相机之前,我运行了这段代码:
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
两者tick(..)
和render()
在我的主游戏循环中的每一帧都被调用。类中有一些函数CameraSceneNode
接受运动方向和摄像机旋转的变化(即改变movement_
缓冲区或xRot_
和yRot_
)。
如果这不是足够的信息,我很抱歉。一些函数(如fillMatrix(..)
)是在我上面引用的 3 个 .h/.cpp 文件中定义的。我已经检查过 Quaternion 类几次,在我看来它是正确的。但是话又说回来,我使用的所有代码对我来说都是正确的,所以谁知道:S
我对此完全束手无策。如果有人能解释为什么这不起作用,我将不胜感激!
干杯
贾勒特