Code: Select all
Quat bOrientationInA = m_b->m_actor->m_orientation * m_a->m_actor->m_orientation.Inverse();
Quat scalar = (bOrientationInA + bOrientationInA.Conjugate()) / 2; // .r is the scalar.
Quat vector = (bOrientationInA - bOrientationInA.Conjugate()) / 2; // .xyz is the vector
Code: Select all
float angle = 2 * acos(scalar.r);
The next thing I tried was to use atan2.
Code: Select all
float angle = 2 * atan2(scalar.r, vector.Length()); // Might be (v, r)?

I've realized that the problem with this atan method is that, due to the duality of quaternions, the direction of rotation around the axis can either be embedded in the scalar or the vector component. For example, (.9219, -.03, -.37, -.109) gives the same twist angle as (.9219, .03, .37, -.109) when using the previously mentioned method even though they are twisted in opposite directions. Using the number of positive/negative numbers as the indicator for the correct direction of twists seems like it might work, but I'm not sure. I'm not even 100% sure if this is the correct way to be going about it. It might be something in my implementation that isn't working, but I wanted to make sure I have the concept correct before continuing. Specifically the things about atan and the extraction of the angle and the determination of the direction of the twist.
The last thing I'm trying to get working is how to nicely fix the limits for constrained objects that have an initial "twist" as a part of the construction. So, for example, I want to have the limit as being initialTwist-pi/2 < currentTwist < initialTwist+pi/2 where initialTwist is equal to something like 2*pi/3. I can't think of a nice way to get this to work without having to do some ugly bounds checking. Maybe something to the effect of using atan((v - v_initial) / (s - s_initial)) to calculate the twist?