[英]OpenGL rotate around global axis using glm::rotate
我正在嘗試圍繞全局軸旋轉 model。 這就是我所擁有的:
我創建了一個處理用戶輸入的方法。 如果用戶按下 A 或 D,model 將繞 Z 軸向左或向右旋轉 90 度。 如果用戶按下 W 或 S,它會繞 X 軸向前或向后旋轉 90 度。 最后,如果用戶按下 Q 或 E,它會繞 Y 軸向左或向右旋轉。 但是如果我在 x 軸上旋轉然后嘗試在 y 軸上旋轉,它將根據 model 的局部軸旋轉,而不是圍繞全局軸旋轉。
有人可以幫我解決這個問題嗎?
以下是我處理 model 輸入的代碼:
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;
}
}
以下是我的model:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.