Przeglądaj źródła

Merge pull request #24 from V-Sekai/animation-fixes

Revert animation changes to fix bug.
K. S. Ernest (iFire) Lee 2 lat temu
rodzic
commit
b64998ee02
2 zmienionych plików z 48 dodań i 32 usunięć
  1. 1 1
      src/FBX2glTF.h
  2. 47 31
      src/fbx/Fbx2Raw.cpp

+ 1 - 1
src/FBX2glTF.h

@@ -17,7 +17,7 @@
 #include <Windows.h>
 #include <Windows.h>
 #endif
 #endif
 
 
-#define FBX2GLTF_VERSION std::string("0.12.9")
+#define FBX2GLTF_VERSION std::string("0.13.0")
 
 
 #include <fmt/printf.h>
 #include <fmt/printf.h>
 
 

+ 47 - 31
src/fbx/Fbx2Raw.cpp

@@ -182,10 +182,7 @@ static void ReadMesh(
   const FbxVector4 meshTranslation = pNode->GetGeometricTranslation(FbxNode::eSourcePivot);
   const FbxVector4 meshTranslation = pNode->GetGeometricTranslation(FbxNode::eSourcePivot);
   const FbxVector4 meshRotation = pNode->GetGeometricRotation(FbxNode::eSourcePivot);
   const FbxVector4 meshRotation = pNode->GetGeometricRotation(FbxNode::eSourcePivot);
   const FbxVector4 meshScaling = pNode->GetGeometricScaling(FbxNode::eSourcePivot);
   const FbxVector4 meshScaling = pNode->GetGeometricScaling(FbxNode::eSourcePivot);
-  FbxAMatrix meshTransform(meshTranslation, meshRotation, meshScaling);
-  const FbxVector4 meshRotationPivot = pNode->GetRotationPivot(FbxNode::eSourcePivot);
-  const FbxAMatrix meshPivotTransform(-meshRotationPivot, FbxVector4(0, 0, 0, 0), FbxVector4(1, 1, 1, 1));
-  meshTransform *= meshPivotTransform;
+  const FbxAMatrix meshTransform(meshTranslation, meshRotation, meshScaling);
   const FbxMatrix transform = meshTransform;
   const FbxMatrix transform = meshTransform;
 
 
   // Remove translation & scaling from transforms that will bi applied to normals, tangents &
   // Remove translation & scaling from transforms that will bi applied to normals, tangents &
@@ -686,23 +683,6 @@ static FbxVector4 computeLocalScale(FbxNode* pNode, FbxTime pTime = FBXSDK_TIME_
   return FbxVector4(1, 1, 1, 1);
   return FbxVector4(1, 1, 1, 1);
 }
 }
 
 
-/**
- * Compute the local position incorporating the rotation pivot offset, and subtracting out the pivot
- * of the parent node.
- */
-static FbxVector4 computeLocalTranslation(FbxNode* pNode, FbxTime pTime = FBXSDK_TIME_INFINITE) {
-  const FbxVector4 meshRotationPivot = pNode->GetRotationPivot(FbxNode::eSourcePivot);
-  const FbxAMatrix meshPivotTransform(meshRotationPivot, FbxVector4(0, 0, 0, 0), FbxVector4(1, 1, 1, 1));
-  FbxAMatrix localTransform = pNode->EvaluateLocalTransform(pTime);
-  localTransform *= meshPivotTransform;
-  FbxVector4 lTranslation = localTransform.GetT();
-  FbxNode* parent = pNode->GetParent();
-  if (pNode->GetParent() != nullptr) {
-    lTranslation -= parent->GetRotationPivot(FbxNode::eSourcePivot);
-  }
-  return lTranslation;
-}
-
 static void ReadNodeHierarchy(
 static void ReadNodeHierarchy(
     RawModel& raw,
     RawModel& raw,
     FbxScene* pScene,
     FbxScene* pScene,
@@ -745,9 +725,9 @@ static void ReadNodeHierarchy(
 
 
   // Set the initial node transform.
   // Set the initial node transform.
   const FbxAMatrix localTransform = pNode->EvaluateLocalTransform();
   const FbxAMatrix localTransform = pNode->EvaluateLocalTransform();
-  FbxVector4 localTranslation = computeLocalTranslation(pNode);
-  FbxQuaternion localRotation = localTransform.GetQ();
-  FbxVector4 localScaling = computeLocalScale(pNode);
+  const FbxVector4 localTranslation = localTransform.GetT();
+  const FbxQuaternion localRotation = localTransform.GetQ();
+  const FbxVector4 localScaling = computeLocalScale(pNode);
 
 
   node.translation = toVec3f(localTranslation) * scaleFactor;
   node.translation = toVec3f(localTranslation) * scaleFactor;
   node.rotation = toQuatf(localRotation);
   node.rotation = toQuatf(localRotation);
@@ -782,6 +762,7 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
       eMode = FbxTime::eFrames60;
       eMode = FbxTime::eFrames60;
       break;
       break;
   }
   }
+  const double epsilon = 1e-5f;
 
 
   const int animationCount = pScene->GetSrcObjectCount<FbxAnimStack>();
   const int animationCount = pScene->GetSrcObjectCount<FbxAnimStack>();
   for (size_t animIx = 0; animIx < animationCount; animIx++) {
   for (size_t animIx = 0; animIx < animationCount; animIx++) {
@@ -855,9 +836,13 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
     for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
     for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) {
       FbxNode* pNode = pScene->GetNode(nodeIndex);
       FbxNode* pNode = pScene->GetNode(nodeIndex);
       const FbxAMatrix baseTransform = pNode->EvaluateLocalTransform();
       const FbxAMatrix baseTransform = pNode->EvaluateLocalTransform();
-      const FbxVector4 baseTranslation = computeLocalTranslation(pNode);
+      const FbxVector4 baseTranslation = baseTransform.GetT();
       const FbxQuaternion baseRotation = baseTransform.GetQ();
       const FbxQuaternion baseRotation = baseTransform.GetQ();
       const FbxVector4 baseScaling = computeLocalScale(pNode);
       const FbxVector4 baseScaling = computeLocalScale(pNode);
+      bool hasTranslation = false;
+      bool hasRotation = false;
+      bool hasScale = false;
+      bool hasMorphs = false;
 
 
       RawChannel channel;
       RawChannel channel;
       channel.nodeIndex = raw.GetNodeById(pNode->GetUniqueID());
       channel.nodeIndex = raw.GetNodeById(pNode->GetUniqueID());
@@ -867,10 +852,24 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
         pTime.SetFrame(frameIndex, eMode);
         pTime.SetFrame(frameIndex, eMode);
 
 
         const FbxAMatrix localTransform = pNode->EvaluateLocalTransform(pTime);
         const FbxAMatrix localTransform = pNode->EvaluateLocalTransform(pTime);
-        const FbxVector4 localTranslation = computeLocalTranslation(pNode, pTime);
+        const FbxVector4 localTranslation = localTransform.GetT();
         const FbxQuaternion localRotation = localTransform.GetQ();
         const FbxQuaternion localRotation = localTransform.GetQ();
         const FbxVector4 localScale = computeLocalScale(pNode, pTime);
         const FbxVector4 localScale = computeLocalScale(pNode, pTime);
 
 
+        hasTranslation |=
+            (fabs(localTranslation[0] - baseTranslation[0]) > epsilon ||
+             fabs(localTranslation[1] - baseTranslation[1]) > epsilon ||
+             fabs(localTranslation[2] - baseTranslation[2]) > epsilon);
+        hasRotation |=
+            (fabs(localRotation[0] - baseRotation[0]) > epsilon ||
+             fabs(localRotation[1] - baseRotation[1]) > epsilon ||
+             fabs(localRotation[2] - baseRotation[2]) > epsilon ||
+             fabs(localRotation[3] - baseRotation[3]) > epsilon);
+        hasScale |=
+            (fabs(localScale[0] - baseScaling[0]) > epsilon ||
+             fabs(localScale[1] - baseScaling[1]) > epsilon ||
+             fabs(localScale[2] - baseScaling[2]) > epsilon);
+
         channel.translations.push_back(toVec3f(localTranslation) * scaleFactor);
         channel.translations.push_back(toVec3f(localTranslation) * scaleFactor);
         channel.rotations.push_back(toQuatf(localRotation));
         channel.rotations.push_back(toQuatf(localRotation));
         channel.scales.push_back(toVec3f(localScale));
         channel.scales.push_back(toVec3f(localScale));
@@ -925,6 +924,7 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
                 if (!std::isnan(result)) {
                 if (!std::isnan(result)) {
                   // we're transitioning into targetIx
                   // we're transitioning into targetIx
                   channel.weights.push_back(result);
                   channel.weights.push_back(result);
+                  hasMorphs = true;
                   continue;
                   continue;
                 }
                 }
                 if (targetIx != targetCount - 1) {
                 if (targetIx != targetCount - 1) {
@@ -932,6 +932,7 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
                   if (!std::isnan(result)) {
                   if (!std::isnan(result)) {
                     // we're transitioning AWAY from targetIx
                     // we're transitioning AWAY from targetIx
                     channel.weights.push_back(1.0f - result);
                     channel.weights.push_back(1.0f - result);
+                    hasMorphs = true;
                     continue;
                     continue;
                   }
                   }
                 }
                 }
@@ -945,12 +946,27 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& o
         }
         }
       }
       }
 
 
-      animation.channels.emplace_back(channel);
+      if (hasTranslation || hasRotation || hasScale || hasMorphs) {
+        if (!hasTranslation) {
+          channel.translations.clear();
+        }
+        if (!hasRotation) {
+          channel.rotations.clear();
+        }
+        if (!hasScale) {
+          channel.scales.clear();
+        }
+        if (!hasMorphs) {
+          channel.weights.clear();
+        }
+
+        animation.channels.emplace_back(channel);
 
 
-      totalSizeInBytes += channel.translations.size() * sizeof(channel.translations[0]) +
-          channel.rotations.size() * sizeof(channel.rotations[0]) +
-          channel.scales.size() * sizeof(channel.scales[0]) +
-          channel.weights.size() * sizeof(channel.weights[0]);
+        totalSizeInBytes += channel.translations.size() * sizeof(channel.translations[0]) +
+            channel.rotations.size() * sizeof(channel.rotations[0]) +
+            channel.scales.size() * sizeof(channel.scales[0]) +
+            channel.weights.size() * sizeof(channel.weights[0]);
+      }
 
 
       if (verboseOutput) {
       if (verboseOutput) {
         fmt::printf(
         fmt::printf(