Parcourir la source

added a feature to be able to export fbx animation w/o skinned mesh

Lumak il y a 9 ans
Parent
commit
931b9bbd98
1 fichiers modifiés avec 61 ajouts et 5 suppressions
  1. 61 5
      Source/Tools/AssetImporter/AssetImporter.cpp

+ 61 - 5
Source/Tools/AssetImporter/AssetImporter.cpp

@@ -182,6 +182,7 @@ float defaultTicksPerSecond_ = 4800.0f;
 float importStartTime_ = 0.0f;
 float importEndTime_ = 0.0f;
 bool suppressFbxPivotNodes_ = true;
+OutModel sceneFbxModel_;
 
 int main(int argc, char** argv);
 void Run(const Vector<String>& arguments);
@@ -246,6 +247,7 @@ String SanitateAssetName(const String& name);
 
 unsigned GetPivotlessBoneIndex(OutModel& model, const String& boneName);
 void ExtrapolatePivotlessAnimation(OutModel* model);
+void CollectSceneNodesAsBones(aiNode* rootNode);
 
 int main(int argc, char** argv)
 {
@@ -687,6 +689,17 @@ void ExportAnimation(const String& outName, bool animationOnly)
 
         // Save scene-global animations
         CollectAnimations();
+
+        // Most fbx animation files contain only skeleton and no model skinned mesh.
+        // -create model's bone struct and assign scene animation
+        if (suppressFbxPivotNodes_ && model.bones_.Size() == 0)
+        {
+            sceneFbxModel_.animations_ = sceneAnimations_;
+            sceneFbxModel_.bones_.Clear();
+
+            CollectSceneNodesAsBones(rootNode_);
+        }
+
         BuildAndSaveAnimations();
     }
 }
@@ -1337,12 +1350,36 @@ void BuildAndSaveAnimations(OutModel* model)
             }
             else
             {
-                boneNode = GetNode(channelName, scene_->mRootNode);
-                if (!boneNode)
+                unsigned pos = channelName.Find("_$AssimpFbx$");
+
+                if (!suppressFbxPivotNodes_ || pos == String::NPOS || sceneFbxModel_.bones_.Size() == 0)
                 {
-                    PrintLine("Warning: skipping animation track " + channelName + " whose scene node was not found");
-                    outAnim->RemoveTrack(channelName);
-                    continue;
+                    boneNode = GetNode(channelName, scene_->mRootNode);
+                    if (!boneNode)
+                    {
+                        PrintLine("Warning: skipping animation track " + channelName + " whose scene node was not found");
+                        outAnim->RemoveTrack(channelName);
+                        continue;
+                    }
+                }
+                else
+                {
+                    channelName = channelName.Substring(0, pos);
+
+                    // every first $fbx animation channel for a bone will consolidate other $fbx animation to a single channel
+                    // skip subsequent $fbx animation channel for the same bone
+                    if (outAnim->GetTrack(channelName) != NULL)
+                        continue;
+
+                    unsigned boneIndex = GetPivotlessBoneIndex(sceneFbxModel_, channelName);
+                    if (boneIndex == M_MAX_UNSIGNED)
+                    {
+                        PrintLine("Warning: skipping animation track " + channelName + " whose scene node was not found");
+                        outAnim->RemoveTrack(channelName);
+                        continue;
+                    }
+
+                    boneNode = sceneFbxModel_.pivotlessBones_[boneIndex];
                 }
             }
 
@@ -2775,6 +2812,12 @@ void CreatePivotlessFbxBoneStruct(OutModel &model)
 
 void ExtrapolatePivotlessAnimation(OutModel* model)
 {
+    // If there was no model present in the scene, use sceneFbxModel_
+    if ( suppressFbxPivotNodes_ && model == NULL && sceneFbxModel_.bones_.Size() > 0)
+    {
+        model = &sceneFbxModel_;
+    }
+
     if (suppressFbxPivotNodes_ && model)
     {
         PrintLine("Suppressing $fbx nodes");
@@ -2896,3 +2939,16 @@ void ExtrapolatePivotlessAnimation(OutModel* model)
     }
 }
 
+void CollectSceneNodesAsBones(aiNode* rootNode)
+{
+    if (!rootNode)
+        return;
+
+    sceneFbxModel_.bones_.Push(rootNode);
+
+    for (unsigned i = 0; i < rootNode->mNumChildren; ++i)
+    {
+        CollectSceneNodesAsBones(rootNode->mChildren[i]);
+    }
+}
+