OpenGL围绕自身而不是原点(0,0,0)旋转对象(一组立方体)
Posted
技术标签:
【中文标题】OpenGL围绕自身而不是原点(0,0,0)旋转对象(一组立方体)【英文标题】:OpenGL Rotating an object (set of cubes) around itself rather than the origin (0,0,0) 【发布时间】:2019-12-03 10:28:48 【问题描述】:我正在练习 OpenGL 和转换,但遇到了问题。我有四个立方体一起平移形成汽车的骨架。我希望能够在汽车不自行拆卸的情况下驾驶和转动汽车。基本上,我希望后备箱和汽车的前部围绕车身而不是原点 (0,0,0) 旋转。我已经阅读了要完成此操作,我必须遵循以下步骤:
从单位矩阵开始
按对象的中心平移矩阵
将矩阵旋转所需的量
按对象中心平移矩阵
使用生成的矩阵变换您想要旋转的对象
并已将其实现到我的代码中,但它没有按我预期的那样工作。请告诉我我做错了什么以及实现这一点的正确方法。我在下面粘贴了我的代码,并对其进行了修剪,所以这里只有重要的部分。
结果:
float xMove = 0.0f; //xMove and zMove keeps track of the center of the main body while driving
float zMove = 0.0f;
float carRotate = 0.0f; //degrees of rotation incremented by pressing E
int main()
/*some code to initialize the program...*/
while (!glfwWindowShouldClose(window))
/*Draw main car body*/
mat4 carMatrix = translate(mat4(1.0f), vec3(0.0f + xMove + x, 0.2f, 0.0f + zMove + z))
* rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f))
* scale(mat4(1.0f), vec3(0.5f, 0.4f, 1.0f))
* translate(mat4(1.0f), vec3(0.0f, -0.2f,0.0f));
shaderProgram.setMat4("model", carMatrix);
glDrawArrays(GL_TRIANGLES, 0, 36);
//Bonnet
carMatrix = translate(mat4(1.0f), vec3(0.0f + xMove + x, 0.1f, 0.65f + zMove + z))
* rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f))
* scale(mat4(1.0f), vec3(0.3f, 0.2f, 0.3f))
* translate(mat4(1.0f), vec3(xMove, 0.0f, -zMove));
shaderProgram.setMat4("model", carMatrix);
glDrawArrays(GL_TRIANGLES, 0, 36);
//Trunk
carMatrix = translate(mat4(1.0f), vec3(0.0f + xMove + x, 0.1f, -0.65f + zMove + z))
* rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f))
* scale(mat4(1.0f), vec3(0.3f, 0.2f, 0.3f))
* translate(mat4(1.0f), vec3(0.0f, 0.0f, 0.0f));
shaderProgram.setMat4("model", carMatrix);
glDrawArrays(GL_TRIANGLES, 0, 36);
//Roof
carMatrix = translate(mat4(1.0f), vec3(0.0f + xMove + x, 0.45f, 0.0f + zMove + z))
* rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f))
* scale(mat4(1.0f), vec3(0.3f, 0.1f, 0.6f))
* translate(mat4(1.0f), vec3(0.0f, 0.0f, 0.0f));
shaderProgram.setMat4("model", carMatrix);
glDrawArrays(GL_TRIANGLES, 0, 36);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
zMove++;
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
carRotate++;
【问题讨论】:
【参考方案1】:不要“按对象的中心平移矩阵”。
然后以这种方式放置整辆车,使其中心位于 (0, 0, 0)。 Thant 意味着将每个对象转换到相对于 (0, 0, 0) 的位置。然后缩放和旋转。终于把护理移到了世界的位置上。
如果汽车的某个部分与 (0, 0, 0) 的相对位置为 (relX
, relY
, relZ
),则:
mat4 carMatrix =
translate(mat4(1.0f), vec3(xMove + x, 0.0f, zMove + z) *
rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f));
//Bonnet
mat4 partMatrix_1 =
translate(mat4(1.0f), vec3(relX, relY, relZ)) *
scale(mat4(1.0f), vec3(0.5f, 0.4f, 1.0f));
shaderProgram.setMat4("model", carMatrix * partMatrix_1);
glDrawArrays(GL_TRIANGLES, 0, 36);
//Trunk
mat4 partMatrix_2 =
translate(mat4(1.0f), vec3(relX2, relY2, relZ2)) *
scale(mat4(1.0f), vec3(0.3f, 0.2f, 0.3f));
shaderProgram.setMat4("model", carMatrix * partMatrix_2);
glDrawArrays(GL_TRIANGLES, 0, 36);
// [...]
注意,我建议先缩放每个部分。然后把它放回原处。
relX
、relY
、relZ
是汽车每个部件的恒定且单独的坐标。
【讨论】:
嗨,谢谢你的回答,但我还是有点困惑。如何计算与 (0,0,0) 的相对位置?公式(原点 - 当前位置)我认为矩阵在最终翻译之前 translate(mat4(1.0f), vec3(xMove + x, 0.0f, zMove + z) 是在原点开始的吗?你能举一个我的行李箱的例子,例如,我将不胜感激 @AnthonyP。没有公式。您必须以这种方式放置汽车的组件,使汽车的中心位于 (0, 0, 0)。relX
、relY
是 relZ
常量值,并且对于汽车的每个组件都是单独的。删除translate(mat4(1.0f), vec3(xMove + x, 0.0f, zMove + z)
和rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f))
并使用relX
、relY
和relZ
的常量值绘制您的汽车。之后添加移动平移和旋转,它将起作用。我无法展示示例,因为我没有关于您的组件的数据。
我按照您编辑的代码进行了操作,它可以工作:) 非常感谢!为此,我环顾四周了很多以上是关于OpenGL围绕自身而不是原点(0,0,0)旋转对象(一组立方体)的主要内容,如果未能解决你的问题,请参考以下文章