MATH::rotationf axis-angle conversion

Discussions concerning programming of SOFTIMAGE©
User avatar
Posts: 9
Joined: 10 Jul 2009, 20:52

MATH::rotationf axis-angle conversion

Post by Roughy » 18 Sep 2013, 04:00


It did occur to me that it might be using radians, but seeing as the internal axisangletoquat function
gave me the correct result with the input in degrees, and there does not appear to be any degrees-radians conversion going on, I did not even think to double check.

Turns out it does though. I am an idiot.

But then what happens when I pass it to the output port? Does it automatically convert everything to degrees instead? (Edit3: it does. The more you know ☆彡)


Dug up crotationf's private AxisAngletoQuat function and recreated it in ICE. It works perfectly fine. I am now even more confused.
The code is correct, but is somehow fetching the wrong axis-angle numbers? As far as I can tell it's using the very same numbers as crotationf::GetAxisAngle uses and returns, so that shouldn't be possible.

Given the specified angle-axis input the math in this function does return the correct quat (WXYZ <0.793353, 0.430459, 0.000000, 0.430459>), but setRepresentation and getQuarternion are returning something else (WXYZ: 0.968688,-0.154892,-0.116874,-0.154892)

Code: Select all

SICPPSDK_INLINE void CRotationf::AxisAngleToQuat( const CVector3f& in_vctAxis, const float in_fAngle, CQuaternionf& out_quat)
	float fCos, fSin;
	CVector3f vct(in_vctAxis);

	fCos = cos( in_fAngle * 0.5f );
	fSin = sin( in_fAngle * 0.5f );

	vct.SetLength( fSin );
	out_quat.Set( fCos, vct.GetX(), vct.GetY(), vct.GetZ() );
The function itself is fine, and neither setRepresentation nor getQuarternion do much of anything but grab and return the results of axisAngletoQuat, so there shouldn't be room for me to break anything. Yet here we are.


After prototyping everything in ICE I sat down to recreate a custom ice node that does a lot of rotation math.

Alas, rotationf is not behaving as one (I) would expect, and I am evidently not even managing to declare them correctly.

Code: Select all

	MATH::CRotationf rot;
	rot.Set(MATH::CVector3f(0.7071,0.0,0.7071),75);  //Set from axis-angle rotation
Then we convert to a quat to see if it's working correctly:

Code: Select all

	Application().LogMessage("Rot converted to quat: "+CString(rot.GetQuaternion()));

Rot converted to quat: WXYZ: 0.968688,-0.154892,-0.116874,-0.154892

Compared to the ICE output of WXYZ <0.793353, 0.430459, 0.000000, 0.430459> this is at least showing the same number pattern (x and z are equal), but is still very much incorrect.

Further, if I fetch the axis-angle after changing the representation to euler I end up with

Code: Select all

	rotVector = rot.GetAxisAngle(rotAngle);
	Application().LogMessage("rot axis/angle output: "+CString(rotVector)+", "+CString(rotAngle));

-0.623862,-0.470737,-0.623862, 0.501808
While if I change it to quat I get

Code: Select all

	rotVector = rot.GetAxisAngle(rotAngle);
	Application().LogMessage("rot axis/angle output: "+CString(rotVector)+", "+CString(rotAngle));

-0.707107,-0,-0.707107, 0.398223
the axis is actually correct here but inverted, and the angle is incorrect.

Both different from the 0.7071, 0.0, 0.7071, 75 input, but consistent after the first conversion (changing back to axis-angle afterwards does not affect the result).

As I have understood it, I were to change the rotation representation it should still be representing the same rotation, and thus the axis-angle representation should remain unchanged.

Evidently I have no idea what I am doing. Any pointers?