Matrices and FBX [SOLVED]

On 30/05/2017 at 20:14, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   R17 
Platform:   Windows  ;   
Language(s) :     C++  ;

I'm working on a plugin using the FBX SDK, but I'm having a terrible time of figuring out the matirx calculations to get my joints rotated right. Obviously the C4D importer works somehow, so I was wondering if anyone had any hints or tips on the way FBX works vs C4D. I've came up with some conclusions based on my research: C4D is left-handed and FBX is right handed. When I'm doing my translation setup I've inverted the z axis and so the positions of the joint are proper. Rotations are a bit of a bastard though. Here's some code I'm using to set up the global matrix for a joint

	FbxAMatrix fbxMatrix;
	fbxMatrix = fbxNode->EvaluateGlobalTransform(kTime);
	Matrix base;
	base.v1.x = fbxMatrix.Get(0, 0);
	base.v1.y = fbxMatrix.Get(0, 1);
	base.v1.z = fbxMatrix.Get(0, 2);
	base.v2.x = fbxMatrix.Get(1, 0);
	base.v2.y = fbxMatrix.Get(1, 1);
	base.v2.z = fbxMatrix.Get(1, 2);
	base.v3.x = fbxMatrix.Get(2, 0);
	base.v3.y = fbxMatrix.Get(2, 1);
	base.v3.z = fbxMatrix.Get(2, 2); = fbxMatrix.Get(3, 0); = fbxMatrix.Get(3, 1); = -fbxMatrix.Get(3, 2);

Considering the handedness I imagine I have to do some interesting to the rotations but I don't know what. Setting the properties use SetAbsRot, SetAbsPos, SetAbsScale isn't working out too well for me either due to those function being local to thier parent. Maybe there's a setglobalpos I'm missing somewhere? The whole base * the inverse of the parent to make things local also failed for me.

On 31/05/2017 at 00:15, xxxxxxxx wrote:

I only can share some things that I found out so far.

Cinema 4D does HPB rotation and FBX is based on XYZ rotation. There is some confusion about rotation order and the rotation axis. Especially if you are using joint chains or a joint hierarchy. For rotation around the Z axis, Cinema 4D uses the local axis and for rotations around the X/Y axis the axis system of the parent.

So I'm confused as well. It is possible to set the world position and orientation of an object with a Python script. Maybe this is a working approach.

On 31/05/2017 at 02:55, xxxxxxxx wrote:

Hi Eldiren, thanks for writing us.
To swap back and forth RH <-> LH coordinates just swap y/z elements in the transformation matrix without inverting any value.

Basically from you should swap 2nd and 3rd row and then swap 2nd and 3rd column.
a00 a01 a02 a03            a00 a02 a01 a03
a10 a11 a12 a13  ---->  a20 a22 a21 a23
a20 a21 a22 a23           a10 a12 a11 a13
a30 a31 a32 a33           a30 a32 a31 a33

Code-wise this turns to be something like this

 base.v1.x = fbxMatrix.Get(0, 0);  
 base.v1.z = fbxMatrix.Get(0, 1);  
 base.v1.y = fbxMatrix.Get(0, 2);
 base.v3.x = fbxMatrix.Get(1, 0);  
 base.v3.z = fbxMatrix.Get(1, 1);  
 base.v3.y = fbxMatrix.Get(1, 2);
 base.v2.x = fbxMatrix.Get(2, 0);  
 base.v2.z = fbxMatrix.Get(2, 1);  
 base.v2.y = fbxMatrix.Get(2, 2); = fbxMatrix.Get(3, 0); = fbxMatrix.Get(3, 1); = fbxMatrix.Get(3, 2);  

Best, Riccardo.

On 03/09/2017 at 22:10, xxxxxxxx wrote:

For future users I finally had a epiphany about the problem and solved it. Loading in the FBX global transforms  into a flat nulls/joints hierarchy yielded a proper result that was only flipped in the x axis, and rotation wrong by 180 in the heading. Most of my problems originated from trying to apply the transforms directly to the skeleton resulting in oddities because of child and parent hierarchies. I needed to parent my clean flat hierarchy under the parents with the proper transforms in wanted. Then the final trick was to set the original bones global matrices to match mine. Probably could have done the matrix math to rotate things as well, but that stuff still never works well for me.