Просмотр исходного кода

Merge pull request #7936 from phenry20/fix/importanimations

fix(assetcontainer): Fixed ImportAnimations
David Catuhe 5 лет назад
Родитель
Сommit
3336ceb4e7
3 измененных файлов с 47 добавлено и 1 удалено
  1. 1 0
      dist/preview release/what's new.md
  2. 28 1
      src/assetContainer.ts
  3. 18 0
      src/scene.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -45,6 +45,7 @@
 
 - Added support for glTF mesh instancing extension ([#7521](https://github.com/BabylonJS/Babylon.js/issues/7521)) ([drigax](https://github.com/Drigax))
 - Get the list of cameras retrieved from a gLTF file when loaded through the asset container ([Popov72](https://github.com/Popov72))
+- Fixed SceneLoader.ImportAnimations. Now targets nodes based on "targetProperty" ([#7931](https://github.com/BabylonJS/Babylon.js/issues/7931)) ([phenry20](https://github.com/phenry20))
 
 ### Navigation
 

+ 28 - 1
src/assetContainer.ts

@@ -485,7 +485,34 @@ export class AssetContainer extends AbstractScene {
             return;
         }
 
-        let _targetConverter = targetConverter ? targetConverter : (target: any) => { return scene.getBoneByName(target.name) || scene.getNodeByName(target.name); };
+        let _targetConverter = targetConverter ? targetConverter : (target: any) => {
+            let node = null;
+
+            const targetProperty = target.animations.length ? target.animations[0].targetProperty : "";
+            /*
+                BabylonJS adds special naming to targets that are children of nodes.
+                This name attempts to remove that special naming to get the parent nodes name in case the target
+                can't be found in the node tree
+
+                Ex: Torso_primitive0 likely points to a Mesh primitive. We take away primitive0 and are left with "Torso" which is the name
+                of the primitive's parent.
+            */
+            const name = target.name.split(".").join("").split("_primitive")[0];
+
+            switch (targetProperty) {
+                case "position":
+                case "rotationQuaternion":
+                    node = scene.getTransformNodeByName(target.name) || scene.getTransformNodeByName(name);
+                    break;
+                case "influence":
+                    node = scene.getMorphTargetByName(target.name) || scene.getMorphTargetByName(name);
+                    break;
+                default:
+                    node = scene.getNodeByName(target.name) || scene.getNodeByName(name);
+            }
+
+            return node;
+        };
 
         // Copy new node animations
         let nodesInAC = this.getNodes();

+ 18 - 0
src/scene.ts

@@ -3204,6 +3204,24 @@ export class Scene extends AbstractScene implements IAnimatable {
     }
 
     /**
+     * Gets a morph target using a given name (if many are found, this function will pick the first one)
+     * @param name defines the name to search for
+     * @return the found morph target or null if not found at all.
+     */
+    public getMorphTargetByName(name: string): Nullable<MorphTarget> {
+        for (let managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {
+            const morphTargetManager = this.morphTargetManagers[managerIndex];
+            for (let index = 0; index < morphTargetManager.numTargets; ++index) {
+                const target = morphTargetManager.getTarget(index);
+                if (target.name === name) {
+                    return target;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Gets a boolean indicating if the given mesh is active
      * @param mesh defines the mesh to look for
      * @returns true if the mesh is in the active list