我正在尝试围绕全局轴旋转我的模型。这就是我所拥有的:
我创建了一个处理用户输入的方法。如果用户按 A 或 D,模型将绕 Z 轴向左或向右旋转 90 度。如果用户按下W或S,它将绕X轴向前或向后旋转90度。最后,如果用户按 Q 或 E,它将绕 Y 轴向左或向右旋转。但是,如果我在 x 轴上旋转,然后尝试在 y 轴上旋转,它将根据模型的局部轴旋转,而不是围绕全局轴旋转。
有人可以帮我解决这个问题吗?
以下是我处理模型输入的代码:
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) {
// reposition camera
heartModel1 = true;
heartModelX -= 30.0f;
heartWallX -= 30.0f;
heartModelZ += 30.0f;
heartWallZ += 30.0f;
}
if (heartModel1) {
// Rotate model
// D -> Rotate Right
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
heartAngleZ -= 90.0f;
}
// A -> Rotate left
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
heartAngleZ += 90.0f;
}
// S -> Rotate back
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
heartAngleX += 90.0f;
}
// W -> Rotate forward
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
heartAngleX -= 90.0f;
}
// Q -> Rotate left on Y axis
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) {
heartAngleY += 90.0f;
}
}
以下是我的模型:
glm::mat4 modelHeart = glm::mat4(1.0f);
modelHeart = glm::translate(modelHeart, glm::vec3(heartModelX + 30, heartModelY, heartModelZ - 30));
modelHeart = glm::rotate(modelHeart, glm::radians(heartAngleX), glm::vec3(1.0f, 0.0, 0.0)); // Rotate on X axis
modelHeart = glm::rotate(modelHeart, glm::radians(heartAngleY), glm::vec3(0.0, 1.0f, 0.0)); // Rotate on Y axis
modelHeart = glm::rotate(modelHeart, glm::radians(heartAngleZ), glm::vec3(0.0, 0.0, 1.0f)); // Rotate on Z axis
modelHeart = glm::scale(modelHeart, glm::vec3(heartModelScale, heartModelScale, heartModelScale));
最佳答案
代码中的旋转是累积的,因此,例如,如果您沿偏航(y 轴)旋转飞机,然后向上倾斜(x 轴),它将在模型的局部空间中向上倾斜,无论它首先偏航到哪里,而不是在全局空间。
要进行全局转换,您需要实际更改转换的顺序,以始终与您正在执行的操作按顺序匹配。也许最简单的方法是在帧之间保留 modelHeart
,这样它就会持续存在,您只需在帧之间修改它即可。
当然,这只是在我正确解释问题的情况下。
另一种方法,如果您没有特别将其设置在全局空间中,则可以使用相同的法线但负角度,以与之前的旋转相反的方向旋转中间旋转的法线轴。
也许是这样的?
// back of the envelope psuedo-code
#include <glm/gtx/rotate_vector.hpp>
glm::vec3 xNorm(1.0, 0.0f, 0.0);
glm::vec3 yNorm(0.0, 1.0f, 0.0);
glm::vec3 zNorm(0.0, 0.0f, 1.0);
modelHeart = glm::rotate(modelHeart, glm::radians(heartAngleX), xNorm); // Rotate on X axis
yNorm = glm::rotate(yNorm, glm::radians(-heartAngleX), xNorm);
modelHeart = glm::rotate(modelHeart, glm::radians(heartAngleY), yNorm); // Rotate on Y axis
zNorm = glm::rotate(zNorm, glm::radians(-heartAngleY), yNorm);
modelHeart = glm::rotate(modelHeart, glm::radians(heartAngleZ), zNorm); // Rotate on Z axis
关于c++ - OpenGL 使用 glm::rotate 绕全局轴旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68779716/