|
I have some animated models in an old obscure format that I’m trying to basically convert to FBX.
The data in the files comes as a full affine matrix per keyframe per mesh. I’ve got the data in an FbxAMatrix object:
FbxAMatrix mat;
mat.SetIdentity();
//inner 3x3 is first 9
mat[0][0] = m[0];
mat[0][1] = m[1];
mat[0][2] = m[2];
mat[1][0] = m[3];
mat[1][1] = m[4];
mat[1][2] = m[5];
mat[2][0] = m[6];
mat[2][1] = m[7];
mat[2][2] = m[8];
//then last 3 is translation; last column
mat[3][0] = m[9];
mat[3][1] = m[10];
mat[3][2] = m[11];
However I can’t seem to figure out how to add a keyframe to an animation curve as a matrix directly. I wouldn’t even mind doing each matrix value ([0, 0]; [0, 1]; ..) separately if need be. I just basically want to forward these matrices directly into the animations, add one keyframe per. I’m doing a workaround right now but the rotations are weird:
FbxVector4 translation = mat.GetT();
FbxVector4 rotation = mat.GetR();
FbxVector4 scaling = mat.GetS();
//one curve per element
AddCurveKey(node->LclTranslation, layer, FBXSDK_CURVENODE_COMPONENT_X, (float)translation[0], time);
AddCurveKey(node->LclTranslation, layer, FBXSDK_CURVENODE_COMPONENT_Y, (float)translation[1], time);
AddCurveKey(node->LclTranslation, layer, FBXSDK_CURVENODE_COMPONENT_Z, (float)translation[2], time);
AddCurveKey(node->LclRotation, layer, FBXSDK_CURVENODE_COMPONENT_X, (float)rotation[0], time);
AddCurveKey(node->LclRotation, layer, FBXSDK_CURVENODE_COMPONENT_Y, (float)rotation[1], time);
AddCurveKey(node->LclRotation, layer, FBXSDK_CURVENODE_COMPONENT_Z, (float)rotation[2], time);
AddCurveKey(node->LclScaling, layer, FBXSDK_CURVENODE_COMPONENT_X, (float)scaling[0], time);
AddCurveKey(node->LclScaling, layer, FBXSDK_CURVENODE_COMPONENT_Y, (float)scaling[1], time);
AddCurveKey(node->LclScaling, layer, FBXSDK_CURVENODE_COMPONENT_Z, (float)scaling[2], time);
void AddCurveKey(FbxProperty& p, FbxAnimLayer* layer, std::string component, float k, float t) {
FbxTime time;
FbxAnimCurveKey key;
FbxAnimCurve* curve = p.GetCurve<FbxAnimCurve>(layer, component.c_str(), true);
if (curve)
{
time.SetSecondDouble(t);
key.Set(time, k);
curve->KeyAdd(time, key);
}
}
My rotations are not correct; they simply spazz out all over the place when my original animation just contained a simple “Spin” around the y-axis.
Am I even animating this correctly?
Any help would be greatly appreciated, thanks!
EDIT: I increased the time between keyframes to 1 second just to see what was happening better. It appears that each keyframe STARTS correctly, where it should be for that frame; it’s the in-between interpolation that causes the “spazzing”.
For example, this matrix:
-0.50000006 0.0 0.8660254 0.0
0.0 1.0 0.0 0.0 -0.8660254 0.0 -0.50000006 0.0
0.0 0.0 0.0 1.0
Should just be 120-degree rotation around the y-axis. But GetR() above returns (180, 60, 180). These two rotations are actually identical and would produce the same matrix, but the problem is that when I animate the rotation components (x, y, z) separately, it thinks it needs to do a full 180 for x and z and thus interpolates it as such, causing the “spazzing”. So even though it ends up where it needs to each time, the journey there looks very odd. Is there a way to animate the full rotation and have it interpolate properly, instead of each individual component?
Just to clarify, in the original program there was no interpolation; it’s very old and it just played each keyframe directly. It’d be nice to add in proper interpolation now, and modernize the look a little bit, but I suppose not a necessity. So somehow disabling interpolation for this FBX file would work too, if there’s a way.
|