I am building a small game engine and using fbx sdk to ipmort fbx mesh and animation, which means I want to store animation in my own class. Now, there are two ways to achieve this:
- The first way is to store key frames only. If I store key frames only, I will have the raw animation data within the fbx file, and I can manipulate or adjust the animation whenever I want.
- The second way is to sample frames at a fixed rate. Instead of storing key frames, I obtain some of the frames that I need from the fbx file and store them. This way, I may lost the raw animation data, because when I sample frames, the chosen frames may not be the key frames, resulting in minor loss of details.
From my perspective, the first way is the best way but most of the tutorails on the Internet are using the second way. For example, here. Below is a snippet of it:
for (FbxLongLong i = start.GetFrameCount(FbxTime::eFrames24); i <= end.GetFrameCount(FbxTime::eFrames24); ++i)
{
FbxTime currTime;
currTime.SetFrame(i, FbxTime::eFrames24);
*currAnim = new Keyframe();
(*currAnim)->mFrameNum = i;
FbxAMatrix currentTransformOffset = inNode->EvaluateGlobalTransform(currTime) * geometryTransform;
(*currAnim)->mGlobalTransform = currentTransformOffset.Inverse() * currCluster->GetLink()->EvaluateGlobalTransform(currTime);
currAnim = &((*currAnim)->mNext);
}
Notice that the function EvaluateGlobalTransform(..) is an fbxsdk function and it seems the only safe interface between us and an fbx animation on which we can rely. Also it seems the second way(use EvaluateGlobalTransform to sample at a specific rate) is the standard and commonly accepted way to do the job. And there is an explation says:
"The FBX SDK gives you a number of ways to get the data you might want. Unfortunately due to different DCC tools (Max/Maya/etc) you may not be able to get exactly the data you want. For instance, let's say you find the root bone and it has translation on it in the animation. You can access the transform in a number of ways. You can use the LclTransform property and ask for the FbxAMatrix at various times. Or you can call the evaluation functions with a time to get the matrix. Or you can use the evaluator's EvaluateNode function to evaluate the node at a time. And finally, the most complicated version is you can get the curve nodes from the properties and look at the curve's keys.
Given all those options, you might think getting the curves would be the way to go. Unfortunately Maya, for instance, bakes the animation data to a set of keys which have nothing to do with the keys actually setup in Maya. The reason for this is that the curves Maya uses are not the same as those FBX supports. So, even if you get the curves directly, they may have hundreds of keys in them since they might have been baked.
What this means is that basically unless Max has curves supported by FBX, it may be baking them and you won't have a way to find what the original two poses in your terms were. Generally you will iterate through time and sample the scene at a fixed rate. Yup, it kinda sucks and generally you'll want to simplify the data after sampling."
To sum up:
The first way:
pros: easy to manipulate and adjust, accurate detail, less memory comsuption(if you generate your vertex transformation matrix on the fly)
cons:difficult to get these key frames, not applicable to some fbx files
The second way:
pros:easy to get chosen frames, adaptable to all fbx files
cons:difficult to change the animation, large memory comsuption, inaccurate details
So, my questions are:
- Is the second way really is the common way to do this?
- Which way do the famous game engines, like Unreal and Unity, use?
- If I want to use the first way even though it may not work under some circumstances, how can I get only key frames from an fbx file(i.e. not using EvaluateGlobalTransform but working with FbxAnimStack, FbxAnimLayer, FbxAnimCurveNode, FbxAnimCurve, FbxAnimCurveKey)?