我创建了一个基于四元数的相机,但是当我转动相机时,会出现不需要的滚动。我不想失去使用例如欧拉角的运动自由度,因为有时需要添加滚动。如果我使用欧拉角,那么据我所知,我可以获得万向节锁。
代码:
struct FreeCamera : public BaseCamera {
float pitch = 0, yaw = 0, roll = 0;
void updateView();
private:
glm::quat qCamera;
};
struct FreeCameraController: public BaseCameraController {
float sensitivityPitch = 0.0025f, sensitivityYaw = 0.0025f, sensitivityRoll = 0.0025f;
void mouseMove(const float x, const float y, const float z = 0);
inline void setMousePos(const float x, const float y, const float z = 0) {
lastMousePos = glm::vec3(x, y, z);
}
private:
glm::vec3 lastMousePos = glm::vec3(0.0f);
};
void FreeCamera::updateView() {
// temporary frame quaternion from pitch, yaw, roll
glm::quat qPYR = glm::quat(glm::vec3(pitch, yaw, roll));
// reset values
pitch = yaw = roll = 0;
// update qCamera
qCamera = qPYR * qCamera;
qCamera = glm::normalize(qCamera);
glm::mat4 rotate = glm::mat4_cast(qCamera);
glm::mat4 translate = glm::mat4(1.0f);
translate = glm::translate(translate, -pos);
view = rotate * translate;
}
void FreeCameraController::mouseMove(const float x, const float y, const float z) {
glm::vec3 dCoord = glm::vec3(x, y, z) - lastMousePos;
((FreeCamera*)camera)->yaw = dCoord.x * sensitivityYaw;
((FreeCamera*)camera)->pitch = dCoord.y * sensitivityPitch;
((FreeCamera*)camera)->roll = dCoord.z * sensitivityRoll;
lastMousePos = glm::vec3(x, y, z);
}
是否可以重置不需要的滚动,“稳定”相机?
最佳答案
当你想要阻止滚动(如果它是一辆汽车,可能也会偏航,因为你会让汽车飞起来),你必须通过连接旋转来阻止其中一个轴。您想要实现的是实际的万向节锁定(在专门飞行时使用包含所有旋转的单个四元数来摆脱它)。因此,假设您可以检测车辆是否在地面上:
glm::mat4 rotationMatrix;
// When you want to get rid of any axis rotation, you must lock it
if(onGround)
{
glm::quat yawQ = glm::quat(glm::vec3(0.0f, yaw, 0.0f));
yawQ = glm::normalize(yawQ);
glm::mat4 yawMat = glm::mat4_cast(yawQ);
glm::quat pitch = glm::quat(glm::vec3(pitch, 0.0f, 0.0f));
pitch = glm::normalize(pitch);
glm::mat4 pitchMat = glm::mat4_cast(pitch);
rotationMatrix = pitchMat * yawMat;
}
else
{
//Your computation
rotationMatrix = glm::mat4_cast(yourQuaternion);
}
viewMatrix = rotationMatrix * translationMatrix;
注意,不一定要使用四元数才能达到地面控制效果
关于c++ - 基于四元数的相机不需要的滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57210185/