Przeglądaj źródła

Fixed a couple issues in gameplay-encoder that caused the encoder to fail when converting certain FBX skinned models.
Updated pre-built gameplay-encoder.exe for windows - Mac and Linux executables still need to be updated.

Steve Grenier 13 lat temu
rodzic
commit
18ce049bd9

+ 10 - 17
gameplay-encoder/src/FBXSceneEncoder.cpp

@@ -309,8 +309,8 @@ void FBXSceneEncoder::loadScene(FbxScene* fbxScene)
 void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fbxNode, Animation* animation)
 {
     const char* name = fbxNode->GetName();
-    Node* node = _gamePlayFile.getNode(name);
-    
+    //Node* node = _gamePlayFile.getNode(name);
+
     // Determine which properties are animated on this node
     // Find the transform at each key frame
     // TODO: Ignore properties that are not animated (scale, rotation, translation)
@@ -466,6 +466,7 @@ void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fb
     assert(channelCount > 0);
 
     // Allocate channel list
+    int channelStart = animation->getAnimationChannelCount();
     for (unsigned int i = 0; i < channelCount; ++i)
     {
         AnimationChannel* channel = new AnimationChannel();
@@ -499,7 +500,7 @@ void FBXSceneEncoder::loadAnimationChannels(FbxAnimLayer* animLayer, FbxNode* fb
         rotation.normalize();
 
         // Append keyframe data to all channels
-        for (unsigned int i = 0; i < channelCount; ++i)
+        for (unsigned int i = channelStart, channelEnd = channelStart + channelCount; i < channelEnd; ++i)
         {
             appendKeyFrame(fbxNode, animation->getAnimationChannel(i), time, scale, rotation, translation);
         }
@@ -517,18 +518,14 @@ void FBXSceneEncoder::loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fb
     bool animationGroupId = false;
     const char* name = fbxNode->GetName();
     // Check if this node's animations are supposed to be grouped
-    if (name)
+    if (name && arguments.containsGroupNodeId(name))
     {
-        std::string str = name;
-        if (arguments.containsGroupNodeId(str))
-        {
-            animationGroupId = true;
-            _groupAnimation = new Animation();
-            _groupAnimation->setId(arguments.getAnimationId(str));
-        }
+        animationGroupId = true;
+        _groupAnimation = new Animation();
+        _groupAnimation->setId(arguments.getAnimationId(name));
     }
     Animation* animation = _groupAnimation;
-    if (!_groupAnimation)
+    if (!animation)
     {
         animation = new Animation();
         animation->setId(name);
@@ -857,8 +854,7 @@ void FBXSceneEncoder::loadSkin(FbxMesh* fbxMesh, Model* model)
                 FbxCluster* cluster = fbxSkin->GetCluster(j);
                 assert(cluster);
                 FbxNode* linkedNode = cluster->GetLink();
-                assert(linkedNode);
-                if (linkedNode->GetSkeleton())
+                if (linkedNode && linkedNode->GetSkeleton())
                 {
                     const char* jointName = linkedNode->GetName();
                     assert(jointName);
@@ -1398,9 +1394,6 @@ bool loadBlendWeights(FbxMesh* fbxMesh, std::vector<std::vector<Vector2> >& weig
             {
                 FbxCluster* cluster = fbxSkin->GetCluster(j);
                 assert(cluster);
-                FbxNode* linkedNode = cluster->GetLink();
-                assert(linkedNode);
-
                 const int vertexIndexCount = cluster->GetControlPointIndicesCount();
                 for (int k = 0; k < vertexIndexCount; ++k)
                 {

+ 6 - 3
gameplay/src/AnimationClip.cpp

@@ -444,8 +444,10 @@ bool AnimationClip::update(float elapsedTime)
 
     // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
     GP_ASSERT(_animation);
-    GP_ASSERT(_animation->_duration > 0);
-    float percentComplete = ((float)_startTime + currentTime) / (float)_animation->_duration;
+
+    // If the animation duration is zero (start time == end time, such as when there is only a single keyframe),
+    // then prevent a divide by zero and set percentComplete = 1.
+    float percentComplete = _animation->_duration == 0 ? 1 : ((float)_startTime + currentTime) / (float)_animation->_duration;
     
     if (isClipStateBitSet(CLIP_IS_FADING_OUT_BIT))
     {
@@ -483,7 +485,8 @@ bool AnimationClip::update(float elapsedTime)
             }
         }
         else
-        {   // Fade is done.
+        {
+            // Fade is done.
             _crossFadeToClip->_blendWeight = 1.0f;
             _blendWeight = 0.0f;
             resetClipStateBit(CLIP_IS_STARTED_BIT);