Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate Euler angles from Forward, Up and Right vectors?

Because this is a complex question that usually results in much confusion (I've asked variations on this question previously, but never asked the question the right way and never got an answer), I'm going to try to make this as clear as possible.

Facts:

  • I'm using Unity.
  • I'm can get the Forward, Up and Right vectors easily from any Quaternion rotation.
  • I can't simply record my own Euler angles, modify them and apply the rotation through a new Quaternion because the object is controlled by physics.
  • I don't understand maths very well at all unless it's written in code (or pseudo-code), so this would be most beneficial to me.
  • A C++ style answer would be easiest for me to understand, but I can work out pretty much any kind of code.
  • I'm NOT trying to get anyone to write the code for me! I'm only asking for the answer in code or pseudo-code because I never learned to read normal maths squiggles; I'm a programmer, not a mathematician.
  • Unity uses a left-handed coordinate system. X = right, Y = up, Z = forward.

What I'm trying to do:

I'm trying to play an animation on a humanoid bone structure and, using torque (rotational force), push the physics ragdoll into approximately the same pose as the bone structure.

The problem:

I can work fully in Quaternions right up to the point where I need to apply the torque to the rigidbodies. The AddTorque function effectively works in Euler angles, which means I can't use the Quaternions. I can easily extract Euler angles from the Quaternions, but they are unreliable and cause the ragdoll to spaz out severely.

What I need:

I need to calculate reliable 3D Euler angles (as in, ones that don't flip from + to - "randomly") from Forward, Up and Right vectors. I realise this is a bit complicated, but that's why I ask here: I lack the knowledge and experience to work out this problem myself.

Given that the vectors themselves are reliable, I see no reason why it would not be possible to work out reliable Euler angles from them. Also, I don't know what order of rotation I would want or need for the Euler angles, but I believe that would be fairly easy to modify later.

Any help would be much appreciated!

like image 754
Clonkex Avatar asked Feb 13 '23 17:02

Clonkex


1 Answers

First, I'd like to say that I solved my problem entirely due to @Tobias's efforts. Many, many thanks! All this time I've been approaching the problem from the wrong end. I assumed that I needed to use AddTorque in a particular way (with Euler angles) and worked from there, but @Tobias (and @JarkkoL a little later) pointed out that I needed to use AddTorque differently.

So this is what I did, in UnityScript (effectively JavaScript):

var quat0:Quaternion;
var quat1:Quaternion;
var quat10:Quaternion;
quat0=transform.rotation;
quat1=target.transform.rotation;
quat10=quat1*Quaternion.Inverse(quat0);
rigidbody.AddTorque(quat10.x,quat10.y,quat10.z,ForceMode.Force);

And, against all expectations, this WORKS!! It just... works! Sure, it takes a long time for the rigidbody cube to settle down, but that's because I need a PID controller. Or maybe quat10 needs normalising, not sure. I'll work it out :)

I had no idea you could actually use that part of a quat by itself.

like image 56
Clonkex Avatar answered Feb 15 '23 11:02

Clonkex