gpt4 book ai didi

c++ - 使用 GLM 在 OpenGL 中面向原点时围绕原点旋转对象?

转载 作者:行者123 更新时间:2023-11-30 04:56:03 26 4
gpt4 key购买 nike

我正在尝试制作一个简单的动画,其中一个对象使用 glm lib 在 OpenGL 中围绕世界原点旋转。我的想法是:

  • 发送对象到源

  • 旋转它

  • 返回原位

  • 让它看我想要什么

这是我的实现:

// Rotates object around point p
void rotate_about(float deltaTime, glm::vec3 p, bool ended) {

glm::vec3 axis = glm::vec3(0,1,0); //rotation axis
glm::mat4 scale_m = glm::scale(glm::mat4(1.0f), glm::vec3(scale, scale, scale)); //scale matrix
glm::mat4 rotation = getMatrix(Right, Up, Front, Position); //builds rotation matrix

rotation = glm::translate(rotation, p - Position );
rotation = glm::rotate(rotation, ROTATION_SPEED * deltaTime, axis);
rotation = glm::translate(rotation, Position - p );

Matrix = rotation * scale_m;

//look at point P
Front = glm::normalize(p - start_Position);
Right = glm::normalize(glm::cross(WorldUp, Front));
Up = glm::normalize(glm::cross(Right, Front));

if (ended == true) { //if last iteration of my animation: saves position
Position.x = Matrix[3][0];
Position.y = Matrix[3][1];
Position.z = Matrix[3][2];
}
}

getMatrix() 简单地返回一个 4x4 矩阵:

| Right.x Right.y Right.z |
| Up.x Up.y Up.z |
| Front.x Front.y Front.z |
| Pos.x Pos.y Pos.z |

我使用这张图片作为引用:

enter image description here

当我启动动画时,我的模型就消失了。如果我删除下面的行 "//look at point P" 它围绕原点旋转,但每次我的动画重新启动时都会抽动。我猜我正在丢失或混合我不应该在某处的信息。 如何存储我的模型前/右/上信息,以便我可以从头开始重建它的矩阵?

首先编辑,这是当我不尝试让我的模型看点 P 时的效果,在本例中为原点。当我尝试时,我的模型消失了。我怎样才能让它看我想要的地方,我怎样才能让我的模型在完成旋转后获得新的前/右/上 vector ?

Run example

This就是我在上面gif中运行的代码

最佳答案

glm::translate()这样的操作或 glm::roate()通过其参数构建矩阵并将输入矩阵乘以新矩阵

这意味着

rotation = glm::translate(rotation, Position - p );

可以表示为(伪代码):

rotation = rotation * translation(Position - p);

请注意,矩阵乘法必须从左到右“读取”。 (参见 GLSL Programming/Vector and Matrix Operations)

translate * rotate 操作导致对象围绕原点旋转:

rotate * translate 操作导致围绕世界原点旋转:

矩阵 glm::mat4 rotation(在您问题的代码中)是您对象的当前模型矩阵。
它包含对象的位置(翻译)和方向。
您想要围绕世界原点旋转对象。

为此,您必须创建一个包含新旋转的矩阵

glm::mat4 new_rot = glm::rotate(glm::mat4(1.0f), ROTATION_SPEED * deltaTime, axis);

然后你可以计算出最终的矩阵如下:

Matrix = new_rot * rotation * scale_m;

如果你想围绕一个点p旋转一个物体,并且这个物体应该始终面对一个点p,那么你所需要的只是物体的位置( start_position) 和旋转轴。在您的例子中,旋转轴是世界的向上 vector 。

glm::vec3 WorldUp( 0.0f, 1.0f, 0.0f );
glm::vec3 start_position = ...;
float scale = ...;
glm::vec3 p = ...;

计算旋转矩阵和新的(旋转的)位置

glm::mat4 rotate    = glm::rotate(glm::mat4(1.0f), ROTATION_SPEED * deltaTime, WorldUp);
glm::vec4 pos_rot_h = rotate * glm::vec4( start_position - p, 1.0f );
glm::vec3 pos_rot = glm::vec3( pos_rot_h ) + p;

计算物体应该“看”的方向

glm::vec3 Front    = glm::normalize(p - pos_rot);

您可以使用函数 getMatrix 设置对象的当前方向矩阵:

glm::vec3 Right    = glm::normalize(glm::cross(WorldUp, Front));
glm::mat4 pos_look = getMatrix(Right, WorldUp, Front, pos_rot);

计算模型矩阵:

glm::mat4 scale_m = glm::scale(glm::mat4(1.0f), glm::vec3(scale));
Matrix = pos_look * scale_m;

最终代码可能是这样的:

glm::mat4 getMatrix(const glm::vec3 &X, const glm::vec3 &Y, const glm::vec3 &Z, const glm::vec3 &T)
{
return glm::mat4(
glm::vec4( X, 0.0f ),
glm::vec4( Y, 0.0f ),
glm::vec4( Z, 0.0f ),
glm::vec4( T, 1.0f ) );
}

void rotate_about(float deltaTime, glm::vec3 p, bool ended) {

glm::mat4 rotate = glm::rotate(glm::mat4(1.0f), ROTATION_SPEED * deltaTime, WorldUp);
glm::vec4 pos_rot_h = rotate * glm::vec4( start_position - p, 1.0f );
glm::vec3 pos_rot = glm::vec3( pos_rot_h ) + p;

glm::vec3 Front = glm::normalize(p - pos_rot);
glm::vec3 Right = glm::normalize(glm::cross(WorldUp, Front));
glm::mat4 pos_look = getMatrix(Right, WorldUp, Front, pos_rot);

glm::mat4 scale_m = glm::scale(glm::mat4(1.0f), glm::vec3(scale));
Matrix = pos_look * scale_m;

if ( ended == true )
Position = glm::vec3(Matrix[3]);
}

关于c++ - 使用 GLM 在 OpenGL 中面向原点时围绕原点旋转对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52770929/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com