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);

// [...]

注意,我建议先缩放每个部分。然后把它放回原处。

relXrelYrelZ 是汽车每个部件的恒定且单独的坐标。

【讨论】:

嗨,谢谢你的回答,但我还是有点困惑。如何计算与 (0,0,0) 的相对位置?公式(原点 - 当前位置)我认为矩阵在最终翻译之前 translate(mat4(1.0f), vec3(xMove + x, 0.0f, zMove + z) 是在原点开始的吗?你能举一个我的行李箱的例子,例如,我将不胜感激 @AnthonyP。没有公式。您必须以这种方式放置汽车的组件,使汽车的中心位于 (0, 0, 0)。 relXrelYrelZ 常量值,并且对于汽车的每个组件都是单独的。删除translate(mat4(1.0f), vec3(xMove + x, 0.0f, zMove + z)rotate(mat4(1.0f), radians(carRotate), vec3(0.0f, 1.0f, 0.0f)) 并使用relXrelYrelZ 的常量值绘制您的汽车。之后添加移动平移和旋转,它将起作用。我无法展示示例,因为我没有关于您的组件的数据。 我按照您编辑的代码进行了操作,它可以工作:) 非常感谢!为此,我环顾四周了很多

以上是关于OpenGL围绕自身而不是原点(0,0,0)旋转对象(一组立方体)的主要内容,如果未能解决你的问题,请参考以下文章

围绕世界 0,0,0 而不是对象中心旋转

OpenGL glRotatef

围绕世界原点旋转对象

在 OpenGL 4.0 中是不是有围绕局部坐标(即从模型视图矩阵)旋转的标准方法?

OpenGL - 骨骼动画 - 骨骼围绕原点旋转

围绕对象旋转的矩阵乘法opengl