How to rotate the GLM Quaternion correctly?

I want to turn my car 90 degrees to the left in the game that I have.

When I use this code:

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; 

The car gets a weird spin.

However, the following codes do not change the rotation of cars at all (just what I expected, just to be sure that GLM is compatible with quats from the game):

  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; 

and whenever I try to check if the rotation has changed with it:

  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; 

the rotation of the cars is simply set to 0,0,0,0 revolutions in the game. I expected the rotations to remain untouched with this code, because I expected the following code to rotate the car 90 degrees to the left:

  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; 

but it doesn’t work the way I want. It simply sets the rotation, not adds it to the "rot".

What am I doing wrong?

+7
source share
2 answers

If you don't care about locking the driveshaft, this should work.

 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; 

I think this is also true

 glm::vec3 rot(90.0*(float)M_PI/180.0, 0, 0); info.Rotation = glm::normalize(info.Rotation * glm::quat(rot)); 

Quaternions are fantastic because they can be compounded to make very complex rotations.

0
source

[Although this is not GLM, the ordering of quaternions during multiplication is still pretty clear and usually a problem]

I used this code to avoid cardan locking (since any solution introducing a cardan lock into a code that already has quaternions is too ironic to consider).

This is C code, and QuaternionFromAngles () and QuaternionMultiply () rewrite the purpose of the first parameter. world->axis6_input_rotation is just Quaternionf_t. The input is from a 6-axis controller, which is a bit freer than your car simulator, unless you actually transfer vectors to your code.

 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; } 
0
source

All Articles