Advertisement

FBX:Have trouble extracting joint's rotation with respective to the joint's local coordinate system

Started by June 21, 2018 02:32 AM
8 comments, last by Dirk Gregorius 6 years, 7 months ago

Hello, everyone! I hope my problem isn't too 'beginnerish'. I'm doing research on motion synthesis now, trying to implement the Deep Mimic paper (DeepMimic) by BINPENG XUE, in this paper, I need to first retarget character A's motion to another character B to make the reference motion clips for character B, since we don't have character B‘s reference motion. The most important thing is that in the paper, the author copied character A's joint's rotation with respective to joint's local coordinate system (not the parent) to character B. In my personal understanding, the joint's rotation with respective to joint's local coordinate system is something like that in the attached photo, where for the Elbow joint, i need to get the Elbow's rotation in the elbow's local coordinate system (i'm very grateful for you to share your ideas if i have misunderstanding about it ?)

I have searched many materials on the internet about how to extract the local joint's information from FBX, the most relative one i found is the pivot rotation( and geometric transformation, object offset transformation). I'm a beginner in computer graphics, and i'm confused about whether the pivot rotation( or geometric transformation, object offset transformation) is exactly the joint's local rotation i'm seeking? I hope someone that have any ideas can help me, I'd be very grateful for any pointers in the right direction. Thanks in advance! 

8df182fc1dfbc249b19e6b4ac524fcd5.jpg

1 hour ago, plz717 said:

and i'm confused about whether the pivot rotation( or geometric transformation, object offset transformation) is exactly the joint's local rotation i'm seeking?

Is this a custom importer, made by someone else? Can you provide more info on the importer. If this is a custom importer can you then link the FBX model as a text file?

In my experience the Autodesk exporter uses: ObjectName.EvaluateLocalTransform();

 

Advertisement
2 hours ago, Scouting Ninja said:

In my experience the Autodesk exporter uses: ObjectName.EvaluateLocalTransform();

Thank you very very very much for your reply!!

I know there is a similar API to what you said from Transformation Data


// Get the node's default local transformation matrix. 

FbxAMatrix& lLocalTransform = lNode->EvaluateLocalTransform();

However, I have no idea whether the local transform here is relative to the joint's local coordinates or relative to the joint's parent node's coordinates? I have not found much information about it. Please give me some hints!

Thank you again! ?

If the API 


lNode->EvaluateLocalTransform();

returns the joint's rotation relative to its local coordinates, then, which API can return the joint's rotation relative to its parent node?

37 minutes ago, plz717 said:

then, which API can return the joint's rotation relative to its parent node?

That is what the local transform is. The local transform is calculated relative to the parent's connection or "nose".

For example if the bone is attached to the parent then it's local position = 3DVector (0,0,0) because it is touching the parent. If it is looking in the same direction as the parent it's rotation should be Quaternion (0,0,0,1) etc.

You can confirm this with the offset formula: (Bpoint -Apoint = offset) So the parent position - child position should be (0,0,0) if they are attached.

 

The "Master" (First bone,Tailbone, drop shadow bone, etc..) bone's local position should be the whole rig's local position also.

Edit: If you have problems try EvaluateLocalTransform().GetT()

23 minutes ago, Scouting Ninja said:

The local transform is calculated relative to the parent's connection or "nose".

Thank you very much again!

Then do you know how to get the joint's rotation respective to the joint's own coordinates? I mean there is a coordinate system on the joint itself, just like the small coordinate system on the elbow joint in the attached photo. When the elbow joint rotates a little, its rotation relative to its own coordinates  may also change.

5 minutes ago, plz717 said:

When the elbow joint rotates a little, its rotation relative to its own coordinates  may also change.

EvaluateLocalTransform().GetT() and LclTranslation.Get();

These two can give you different results. Evaluate checks the bones relative to parents and Lcl Transform or rotation is the bones rotation relative to its own axis.

Most of the time they should be similar; because the bones axis is relative to the parent. A bones axis is almost always relative to a parent unless told not to follow the parent.

Advertisement

Wow~~~~

It's exactly what i need! Thank you sooooooo~ much!

By the way, I found it really difficult to understand the API from the official website, i am a beginner in computer graphics and i hope i can go deeper into it, could you please give me some direction on where can i understand the difference between those API better?

Thank you ~!


 

8 hours ago, plz717 said:

could you please give me some direction on where can i understand the difference between those API better?

Sorry, I don't think there is a way to understand it better without practice. I struggled with it as much as you did when I started with it. Trail and error and asking on the web is how I learned it.

I recommend looking at the Maya documentation to get an idea how sophisticated the joint transformation can be in practice in a modeling package:

https://download.autodesk.com/us/maya/2011help/API/class_m_fn_transform.html

http://download.autodesk.com/us/maya/2011help/Api/class_m_fn_ik_joint.html

You see that the joint transformations can be composed out of up to 15 affine transformations (if I counted correctly). Also depending on the transformation type the parent scale might not be propagated down into the child transformation. This is the reason why you most likely never want to query anything local (e.g the local translation or rotation) on a node since there is a large chance that it is not the value you are looking for. 

From my experience people usually compute the world space transformations of the parent and child. Then you transform the child transformation into the local space of the parent yourself. Finally you decompose the local matrix. 

Here is a simple example how to extract the transformation data from an FBX node


// Transform
FbxAMatrix GlobalTransform = Node->EvaluateGlobalTransform();
FbxAMatrix LocalTransform = GlobalTransform;

// Hierarchy
if ( FbxNode* Parent = Node->GetParent() )
{
	FbxAMatrix ParentTransform = Parent->EvaluateGlobalTransform();
	LocalTransform = ParentTransform.Inverse() * GlobalTransform;
}

// Decomposition
FbxVector4 LocalTranslation = LocalTransform.GetT();
FbxQuaternion LocalRotation = LocalTransform.GetQ();
FbxVector4 LocalScale = LocalTransform.GetS();

Note that when you later export animations the same idea holds. You move the scene forward in time, sample the global transformations, compute the local child transformation and then decompose. It is actually pretty easy if you do it this way.

HTH,

-Dirk

PS: The local scale extraction can potentially go wrong due to limitations of the FBXAMatrix class. This is more of a theoretical problem though. If this is a problem you would still evaluate the global transformation, but store the results in your own matrix class and then decompose using whatever strategy works in your context. Again, this shouldn't be a problem in practice and I wouldn't worry too much about this. I just mentioned it for completeness! 

 

This topic is closed to new replies.

Advertisement