Ignore animation 'takes', calculate frame intervals ourselves.
Lifted from comment in source: Individual animations are often concatenated on the timeline, and the only certain way to identify precisely what interval they occupy is to depth-traverse the entire animation stack, and examine the actual keys. There is a deprecated concept of an "animation take" which is meant to provide precisely this time interval information, but the data is not actually derived by the SDK from source-of-truth data structures, but rather provided directly by the FBX exporter, and not sanity checked. Some exporters calculate it correctly. Others do not. In any case, we now ignore it completely.
This commit is contained in:
parent
a07cabd1ec
commit
df00e0538d
|
@ -742,24 +742,35 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
|
||||||
|
|
||||||
pScene->SetCurrentAnimationStack(pAnimStack);
|
pScene->SetCurrentAnimationStack(pAnimStack);
|
||||||
|
|
||||||
FbxTakeInfo* takeInfo = pScene->GetTakeInfo(animStackName);
|
FbxLongLong firstFrameIndex = -1;
|
||||||
if (takeInfo == nullptr) {
|
FbxLongLong lastFrameIndex = -1;
|
||||||
fmt::printf("Warning:: animation '%s' has no Take information. Skipping.\n", animStackName);
|
for (int layerIx = 0; layerIx < pAnimStack->GetMemberCount(); layerIx++) {
|
||||||
// not all animstacks have a take
|
auto* layer = pAnimStack->GetMember<FbxAnimLayer>(layerIx);
|
||||||
continue;
|
for (int nodeIx = 0; nodeIx < layer->GetMemberCount(); nodeIx++) {
|
||||||
|
auto* node = layer->GetMember<FbxAnimCurveNode>(nodeIx);
|
||||||
|
FbxTimeSpan nodeTimeSpan;
|
||||||
|
if (node->GetAnimationInterval(nodeTimeSpan)) {
|
||||||
|
FbxLongLong firstNodeFrame = nodeTimeSpan.GetStart().GetFrameCount(eMode);
|
||||||
|
FbxLongLong lastNodeFrame = nodeTimeSpan.GetStop().GetFrameCount(eMode);
|
||||||
|
if (firstFrameIndex == -1 || firstNodeFrame < firstFrameIndex) {
|
||||||
|
firstFrameIndex = firstNodeFrame;
|
||||||
}
|
}
|
||||||
|
if (lastFrameIndex == -1 || lastNodeFrame < lastFrameIndex) {
|
||||||
|
lastFrameIndex = lastNodeFrame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RawAnimation animation;
|
||||||
|
animation.name = animStackName;
|
||||||
|
|
||||||
|
fmt::printf(
|
||||||
|
"Animation %s: [%lu - %lu]\n", std::string(animStackName), firstFrameIndex, lastFrameIndex);
|
||||||
|
|
||||||
if (verboseOutput) {
|
if (verboseOutput) {
|
||||||
fmt::printf("animation %zu: %s (%d%%)", animIx, (const char*)animStackName, 0);
|
fmt::printf("animation %zu: %s (%d%%)", animIx, (const char*)animStackName, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxTime start = takeInfo->mLocalTimeSpan.GetStart();
|
|
||||||
FbxTime end = takeInfo->mLocalTimeSpan.GetStop();
|
|
||||||
|
|
||||||
RawAnimation animation;
|
|
||||||
animation.name = animStackName;
|
|
||||||
|
|
||||||
FbxLongLong firstFrameIndex = start.GetFrameCount(eMode);
|
|
||||||
FbxLongLong lastFrameIndex = end.GetFrameCount(eMode);
|
|
||||||
for (FbxLongLong frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; frameIndex++) {
|
for (FbxLongLong frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; frameIndex++) {
|
||||||
FbxTime pTime;
|
FbxTime pTime;
|
||||||
// first frame is always at t = 0.0
|
// first frame is always at t = 0.0
|
||||||
|
|
Loading…
Reference in New Issue