我想在游戏中将我的车向左旋转 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 代码,QuaternionFromAngles() 和 QuaternionMultiply() 正在覆盖第一个参数的目标。 world->axis6_input_rotation
只是一个 Quaternionf_t。输入来自 6 轴 Controller ,它比您的车辆模拟更自由,除非您实际上在代码中传递 vector 。
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;
}
关于c++ - 如何正确旋转 GLM 四元数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15055423/