Trouble converting global to local rotation in motion builder


#1

Hello,

I’m currently developing something with pyfbxsdk but I’m prototyping with mobu and well… Im getting the same problem in both.

So I have those 2 objects named Parent and child (parent being child parent). I need to rotate the child object -90 degree globally on the X axis on all the animation. Basically I need to add a -90 degree offset.

So i thought I would open the animation with the fbxsdk, calculate the offset and modify the curves. I decided to go with the fbxsdk because of the speed and ideally I’d like to keep it.

I’ve been able to calculate the global transform of what child should be easily by doing some sinple matrix multiplication. However, for some reason I cant convert this global transform to the proper local tm.

When I multiply this global transform with the inverse of my parent transform I get garbage… at first I thought that my calculated glibal tm was wrong but I tested it and I know for a fact that my global transform gives me the right result.

After some investigations I discovered that my child object has pre-rotations(-90,0,90) but tbh Im not sure if this is what is causing the issue or how to take it into account in my math. Could this pre-rotation mess everything when calculating the local Tm?

Does anyone had issues like that in the past or knows a better way to solves this. In the fbx sdk it says that you can’t write global values but is there anither way to modify an animation other than loading thr curve and doing a KeySet() ?


#2

Absolutely. In fact I haven’t directly resolved this as the way mobu does it is somewhat cryptic. Here’s what you’re looking for, but be warned, I haven’t gotten it to work correctly in the scenario you describe. Let me know if you have better luck.

In the docs under FBModel:

DofToLRM	(	FBModel 	arg1,
FBMatrix 	arg2,
FBVector3d 	arg3 
)		
Convert object space vector to local matrix.

Python Docstring:

DofToLRM( (FBModel)arg1, (FBMatrix)arg2, (FBVector3d)arg3) -> None 
C++ Signature:

void DofToLRM(ORSDK2015::FBMatrix & pLM, const FBRVector & pDof) 
Parameters
pDof	Vector to convert
Return values
pLM	Resulting local rotation matrix.
Note
Use this function when you want to convert euler to local rotation with proper pre/post transformation and rotation order applied from this model.

NB: you can write transforms, but its cryptic and require scene evaluate calls which is not what you want.


#3

actually I’m doing the work with the fbxSdk and only using mobu to prototype. Mostly because we have huge scenes and I was hoping to re-use this process in maya and mobu. I know that in mobu you can set a global matrix to an object and then key the object at the current transform. But with the fbxsdk, it’s unfortunately not that easy it seems. Worst case I’ll probably migrate everything back in mobu for now.

from the fbxsdk help:

Note A node’s global transformation matrix of cannot be explicitly set in the FBX SDK.

and:

A node’s global and local transformation matrices can be respectively obtained by calling FbxNode::EvaluateGlobalTransform() and FbxNode::EvaluateLocalTransform():

So I was using EvaluateGlobalTransform and then calculating the offset matrix and applying it back. The result matrix is then global space which I then need to convert to local. I tried adding pre-rotation matrix into the multiplication but I couldn’t get it to work.

Regarding the DofToLRM, I wish I could access this as well through the fbxsdk.
As a side note, I also saw this on another forum:
Convert the preRot/rotation/postRot to quat and do this to get the final rotation
TotalRot = Pre * Rot * Post
I guess you could then convert this to a matrix, but I haven’t tested it.


#4

That’s what I tried and didn’t get the proper results… I had to give up rather quickly however.


#5

from :
https://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref__transformations_2main_8cxx_example_html

		// Calculate local transform according to: LocalTransform = ParentGlobalInverse * GlobalTransform.
		lLocalTransform = lParentTransform.Inverse() * lGlobalTransform;

It doesnt mention anything about pre or post rotation being considered for this calculation. Sigh… I guess I’ll rely to mobu to do the rotation fix rather than the fbxsdk for now


#6

I solved this by doing everything in mobu, i calculate the matrix and do the changes directly onto the control rig. I then apply the corresponding matrix components using set and key candidate. Its not as fast or elegant as the fbxsdk but at least it’s working and it will have to do for now :confused:


#7

Out of curiosity, did you end up using the DofToLRM method(s) to include pre-rotations/post-rotations?


#8

No didn’t had too, what I ended up doing was something like:

hips.SetMatrix (myGlobalMatrix)
FBSystem().Scene.Evaluate()
hips.Rotation.GetAnimationNode().SetCandidate( [ hips.Rotation ] )
hips.Rotation.GetAnimationNode().KeyCandidate()

That way I didn’t had to bother at all about local rotation and pre or post rotation. I let mobu handle it, its probably a a bit slower, but that’s something I’d really like to solve in a near future when I’ll have time. THe DofToLRM will surely be handy.