Hi,
I am trying to set up a simple Physics simulation, not using that of Unreal, and so far it’s going well enough.
But I have now spent the entire day trying to apply a moment (torque, if you prefer) to my actor, and it just won’t work properly. Here’s some parts of the code, I’ll explain what’s wrong after:
INIT:
// Local space of actor
FMatrix inertiaTensor = FMatrix::Identity;
// Initial rotation of actor, world space
FRotator ar = GetActorRotation();
rotation = FVector(ar.Roll, ar.Pitch, ar.Yaw);
TICK:
// Everything in world space
FVector newAngVel = angularVelocity + angularAcceleration * dt;
rotation += angularVelocity * dt + 0.5f * angularAcceleration * dt * dt;
angularVelocity = newAngVel;
// Keep rotation angles from getting crazy large
rotation.X -= 360.f * (static_cast<int>(rotation.X) / 360);
rotation.Y -= 360.f * (static_cast<int>(rotation.Y) / 360);
rotation.Z -= 360.f * (static_cast<int>(rotation.Z) / 360);
FRotator rot(rotation.Y, rotation.Z, rotation.X);
SetActorRotation(rot);
// Reset for next frame
angularAcceleration = FVector::ZeroVector;
APPLY_MOMENT: (Called every frame, from another Actor's Tick function, for testing)
// Moment about x-axis, world space
FVector moment(magnitude, 0.f, 0.f);
// Inertia Tensor in World Space
FMatrix I = GetTransform().GetRotation().Inverse() * inertiaTensor;
// alpha += I^{-1} * M
angularAcceleration += I.InverseTransformVector(moment);
So for now, I’m just using an identity matrix for the inertiaTensor for testing. And since I’m using a cube for now, it doesn’t matter much.
The problem:
- If the actor has no initial rotation, it will start rotating around the world x-axis, as it should, but
- If the actor already has a rotation, it will just start spinning in seemingly random rotations. For simple test, I gave it an initial rotation of (0, 45, 0). For the first 10-15 degrees orso, it seems to rotate mainly around world X, but after that it just starts going in all sort of directions.
Why? This isn’t Gimbal Lock is it?
Or does SetActorRotation() secretly use local space?
If I use instead the local inertiaTensor
FMatrix I = inertiaTensor;
the cube rotates nicely around its own local x-axis.
I have just been trying to make it work all day, and I’d really like to fix it. It’s one of the last things I need to finish before completing the collision response.
Thanks