将形状旋转到 1 到 2 弧度之间的任何位置都会重置其旋转
Posted
技术标签:
【中文标题】将形状旋转到 1 到 2 弧度之间的任何位置都会重置其旋转【英文标题】:Rotating a shape to anywhere between 1 and 2 radians resets its rotation 【发布时间】:2021-08-25 12:49:48 【问题描述】:我目前正在使用 GLM 在 OpenGL 中转换形状。但是,当形状的旋转在 1 到 2 弧度之间时,表示旋转的矩阵的值将设置回它们在单位矩阵中的值。我目前正在将模型矩阵输出到控制台,这有助于找出它转回 0 旋转弧度的确切时刻。就是这样:
对不起,如果很难理解,我已经尝试对其进行注释,因为否则看起来很烦人。如果需要,可以直接在图片中添加link。
控制台中每行的第一个值是以弧度为单位的单个值的旋转。然后输出形状的模型矩阵。
上传它的视频很烦人,但我相信你可以想象它 - 它只是一个正常旋转一段时间的形状,直到旋转达到一个弧度,此时它会重置为正常旋转。然后,当它达到两个弧度时,它会恢复正常,就好像从来没有问题一样。
以下是变形相关的代码:
// NOTE: the variables 'active_translation, active_rotation, and active_scaling' are the values the user gives to translate, rotate, and scale the shape
// In this case, 'active_rotation' is equal to ~0.02 (1 degree in radians) every frame
void defshape::apply_transformations()
// Create an identity matrix to store the applied transformations
glm::mat4 applied_transformation = glm::mat4(1.0f);
// Add the active translation to the stored transformations variable
applied_transformation = glm::translate(applied_transformation, active_translation);
// Apply the rotation to the mat4. For the sake of this example, I've only showed the Z axis line to simplify it as it's the only one being affected.
applied_transformation = glm::rotate(applied_transformation, active_rotation.z, glm::vec3(0, 0, 1));
// Add the active scale to the stored transformations variable
applied_transformation = glm::scale(applied_transformation, active_scaling);
// Apply these changes to the renderer by setting its model matrix and then updating it
renderer_handle->model_matrix = applied_transformation;
renderer_handle->update_renderer();
// Reset the translation of the model matrix back to 0
// This step ensures that the object rotates around its local origin, rather than the world space origin
applied_transformation = glm::translate(applied_transformation, glm::vec3(0.0f));
// Then apply this change to the renderer's model matrix
renderer_handle->model_matrix = applied_transformation;
renderer_handle->update_renderer();
这可能与 GLM 有关,还是我的代码有问题?
【问题讨论】:
【参考方案1】:已解决 - 该问题与我的项目特定的代码块有关,这可能就是它如此独特的原因。
具体来说,我犯了一个错误,与通过 glm 旋转时要影响的轴有关。我第一次编码的方式如下:
// Variable to store the affected rotation axes
glm::vec3 _active_rotation_axes = glm::vec3(0, 0, 0);
// Get the affected axes for rotation
// 'active_rotation' stores the rotation values for each axis
_active_rotation_axes.x = (active_rotation.x != 0) ? 1 : 0;
_active_rotation_axes.y = (active_rotation.y != 0) ? 1 : 0;
_active_rotation_axes.z = (active_rotation.z != 0) ? 1 : 0;
// Keep in mind the above code is partly pseudocode, as I have simplified it heavily and typed it directly into the answer.
变量_active_rotation_axes
被这样使用:
if (_active_rotation_axes.x != 0) applied_transformation = glm::rotate(applied_transformation, active_rotation.x, glm::vec3(_active_rotation_axes.x, 0, 0));
if (_active_rotation_axes.y != 0) applied_transformation = glm::rotate(applied_transformation, active_rotation.y, glm::vec3(0, _active_rotation_axes.y, 0));
if (_active_rotation_axes.z != 0) applied_transformation = glm::rotate(applied_transformation, active_rotation.z, glm::vec3(0, 0, _active_rotation_axes.z));
这导致了我遇到的问题,虽然我仍然不知道具体原因。
无论如何,最后我要做的就是删除第一个代码块,并将第二个代码块更改为以下代码块,它直接检查active_rotation
,而不是现在不存在的变量_active_rotation_axes
:
if (active_rotation.x != 0) applied_transformation = glm::rotate(applied_transformation, active_rotation.x, glm::vec3(1, 0, 0));
if (active_rotation.y != 0) applied_transformation = glm::rotate(applied_transformation, active_rotation.y, glm::vec3(0, 1, 0));
if (active_rotation.z != 0) applied_transformation = glm::rotate(applied_transformation, active_rotation.z, glm::vec3(0, 0, 1));
真的,我应该从一开始就这样做,因为它更加高效和简单。
【讨论】:
以上是关于将形状旋转到 1 到 2 弧度之间的任何位置都会重置其旋转的主要内容,如果未能解决你的问题,请参考以下文章