(鉴于脑子不好使所以在给自己上压力之前先做个小练习)
用四元数完成view变换
目的是等效替代掉用欧拉角,因为俯仰角范围限制总是让人感觉不爽。
auto& lx = windowState.lastX;
auto& ly = windowState.lastY;
auto& yaw = windowState.yaw;
auto& pitch = windowState.pitch;
auto& right = windowState.cameraRight;
auto& up = windowState.cameraUp;
auto& orientation = windowState.cameraOrientation;
auto& speed = windowState.rotateSpeed;
auto dx = xpos - lx;
auto dy = ypos - ly;
auto dyaw = dx * speed;
auto dpitch = dy * speed;
yaw += dyaw;
pitch += dpitch;
while (yaw <= -180.0f)yaw += 180.0f;
while (yaw >= 180.0f)yaw -= 180.0f;
constexpr float limit = 90.0f - 1e-3;
if (pitch > limit) {
dpitch -= pitch - limit;
pitch = limit;
}
else if (pitch < -limit) {
dpitch += -limit - pitch;
pitch = -limit;
}
auto yawRot = glm::angleAxis(glm::radians(-yaw), up);
right = yawRot * glm::vec3(1.0f, 0.0f, 0.0f);
orientation = glm::angleAxis(glm::radians(-pitch), right)
* yawRot
* glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
windowState.cameraFront = orientation * glm::vec3(0.0f, 0.0f, -1.0f);
lx = xpos;
ly = ypos;
移动、转动方式都是采取MC式,特点是:
-
前后左右的运动方向一定在一个世界水平面上,上下的运动方向也在世界直线上,这个水平面、直线由上方向确定。
-
俯仰角最多在-90到90,不能反抛帝。
结果
MC的运动方式本身就剔除了欧拉角参数化会产生的在上方向上的奇点,所以通过四元角完成这项操作并不能带来代码上的简化和思路上的简化,估计也不会优化。
如果不需要插帧的话,那么使用欧拉角绰绰有余。估计四元数主要就用在像CAD一样无限制旋转的情况了。
如果俯仰角的limit设置为90.0f的话,当视角真正垂直时将会发生剧烈抖动。建议是调成1e-3的差距,因为即使是1e-4也很抖。
comment 评论区
star_outline 咱快来抢个沙发吧!