如何正确旋转GLM四元数
How to rotate a GLM quaternion correctly?
我想在游戏中向左旋转90度。
当我使用这个代码:
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(glm::rotate(rot,glm::eulerAngles(rot)+glm::vec3(90.0f,0.0,0.0)));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
汽车有一个奇怪的旋转。
然而,以下代码根本不会改变赛车的旋转(这正是我所期望的,只是为了确保GLM与游戏中的quats兼容):
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(rot);
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
每当我尝试这个来检查旋转是否随之改变时:
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(glm::rotate(rot,vec3(0.0,0.0,0.0)));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
汽车的旋转只是设置为0,0,0,0旋转在游戏中。我希望这个代码不会影响旋转,因为我希望下面的代码将汽车向左旋转90度:
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat done(glm::rotate(rot,vec3(90.0,0.0,0.0)));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
但这不是我想要的方式。它只是设置旋转,而不是将其添加到"rot"中。
我做错了什么?
[虽然这不是GLM,但乘法中四元数的排序仍然很清楚,这通常是问题所在]
我用这样的代码来避免万向锁(因为任何将万向锁引入已经有四元数的代码中的解决方案都太讽刺了,无法考虑)。
这是C代码,四元数FromAngles()和四元数Multiply()正在覆盖第一个参数的目标。world->axis6_input_rotation
只是一个四元数。输入来自一个6轴控制器,它比你的车辆模拟更自由,除非你真的在代码中传递矢量。
typedef struct { float w, x, y, z; } Quaternionf_t;
void GuiMotion6axis(World_t *world, Port_t *port,
int x, int y, int z,
int xr, int yr, int zr)
{
// convert spaceball input to World->rotation (a quaternion)
// Source http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm
const float scale = 0.0004; // should factor in the time delta it covers as well.
float xrf = (float)xr * scale;
float yrf = (float)yr * scale;
float zrf = (float)zr * scale;
QuaternionFromAngles(& world->axis6_input_rotation, xrf, yrf, zrf);
QuaternionMultiply(& world->rotation, // worldrot = inputrot * worldrot
& world->axis6_input_rotation, // a read-only use
& world->rotation // a read-only use
);
world->position.x += (float)x * scale; // really should factor in the
world->position.y += (float)y * scale; // elasped time.
world->position.z += (float)z * scale;
return;
}
如果您不关心万向节锁,那么这应该会起作用。
glm::quat rot(info.Rotation.w,info.Rotation.x,info.Rotation.y,info.Rotation.z);
glm::quat rot_euler_angles = glm::gtx::quaternion::eulerAngles(rot);
rot_euler_angles.x += 90;
glm::quat done(glm::rotate(rot,rot_euler_angles));
info.Rotation.x = done.x;
info.Rotation.y = done.y;
info.Rotation.z = done.z;
info.Rotation.w = done.w;
我认为这也是有效的
glm::vec3 rot(90.0*(float)M_PI/180.0, 0, 0);
info.Rotation = glm::normalize(info.Rotation * glm::quat(rot));
四元数非常神奇,因为它们可以被复合以进行非常复杂的旋转。
这是我编写的一个简单函数,它将随参考轴旋转(度)。可以通过在w和(x,y,z)分量的单独部分中创建四元数来创建它。GLM有一个初始值设定项,可以将其转换为4x4或用于变换的3x3矩阵。
void QuaternionRotate(const glm::vec3& axis, float angle)
{
float angleRad = glm::radians(angle);
auto& axisNorm = glm::normalize(axis);
float w = glm::cos(angleRad / 2);
float v = glm::sin(angleRad / 2);
glm::vec3 qv = axisNorm * v;
glm::quat quaternion(w, qv);
glm::mat4 quatTransform = glm::mat4_cast(quaternion);
// Now with the quaternion transform you rotate any vector or compound it with another transformation matrix
}
相关文章:
- 单元测试欧拉到四元数实现失败
- 零四元数和任何向量都不为零的特征积,这是一个错误吗?
- 将四元数旋转的游戏对象旋转另一个四元数时出现问题
- 在OpenGL(GLM/C++)中使用四元数旋转时出现问题
- 想要将 CGAL 与四元数相结合是否合乎逻辑
- Eigen::Quaternion FromTwoVectors() 不返回有效的四元数
- C++四元数方程程序
- 四元数旋转不起作用
- 四元数和翻译
- 使用四元数防止绕某个轴旋转
- 四元数 -> 欧拉角 -> 旋转矩阵问题 (GLM)
- 将 glm 四元数转换为旋转矩阵并将其与 opengl 一起使用
- 笛卡尔到四元数 glm
- 如何否定GLM四元数在任何单轴上的旋转
- GLM矩阵的旋转方向,使用四元数
- OpenGL, GLM四元数旋转
- 用GLM确定四元数前面的位置
- 如何正确旋转GLM四元数
- 使用glm的四元数到矩阵
- 当提供轴和四元数时,我如何使用GLM获得角度