Quellcode durchsuchen

Update for instantiateIntoScene

David Catuhe vor 5 Jahren
Ursprung
Commit
fa05f9cd99
5 geänderte Dateien mit 99 neuen und 18 gelöschten Zeilen
  1. 1 1
      src/Bones/bone.ts
  2. 1 1
      src/Meshes/transformNode.ts
  3. 59 5
      src/assetContainer.ts
  4. 8 11
      src/node.ts
  5. 30 0
      src/scene.ts

+ 1 - 1
src/Bones/bone.ts

@@ -91,7 +91,7 @@ export class Bone extends Node {
          */
         public name: string, skeleton: Skeleton, parentBone: Nullable<Bone> = null, localMatrix: Nullable<Matrix> = null,
         restPose: Nullable<Matrix> = null, baseMatrix: Nullable<Matrix> = null, index: Nullable<number> = null) {
-        super(name, skeleton.getScene(), false);
+        super(name, skeleton.getScene());
         this._skeleton = skeleton;
         this._localMatrix = localMatrix ? localMatrix.clone() : Matrix.Identity();
         this._restPose = restPose ? restPose : this._localMatrix.clone();

+ 1 - 1
src/Meshes/transformNode.ts

@@ -171,7 +171,7 @@ export class TransformNode extends Node {
 
         if (isPure) {
             this.getScene().addTransformNode(this);
-        }
+        }        
     }
 
     /**

+ 59 - 5
src/assetContainer.ts

@@ -4,6 +4,9 @@ import { Mesh } from "./Meshes/mesh";
 import { TransformNode } from './Meshes/transformNode';
 import { Skeleton } from './Bones/skeleton';
 import { AnimationGroup } from './Animations/animationGroup';
+import { AbstractMesh } from './Meshes/abstractMesh';
+import { MultiMaterial } from './Materials/multiMaterial';
+import { Material } from './Materials';
 
 /**
  * Set of assets to keep when moving a scene into an asset container.
@@ -57,13 +60,16 @@ export class AssetContainer extends AbstractScene {
     /**
      * Instantiate or clone all meshes and add the new ones to the scene.
      * Skeletons and animation groups will all be cloned
+     * @param nameFunction defines an optional function used to get new names for clones
+     * @param cloneMaterials defines an optional boolean that defines if materials must be cloned as well (false by default)
      * @returns a list of rootNodes, skeletons and aniamtion groups that were duplicated
      */
-    public instantiateModelsToScene(): InstantiatedEntries {
+    public instantiateModelsToScene(nameFunction?: (sourceName: string) => string, cloneMaterials = false): InstantiatedEntries {
         let convertionMap: {[key: number]: number} = {};
         let storeMap: {[key: number]: any} = {};
         let result = new InstantiatedEntries();
-        let alreadySwapped: Skeleton[] = [];
+        let alreadySwappedSkeletons: Skeleton[] = [];
+        let alreadySwappedMaterials: Material[] = [];
 
         let options = {
             doNotInstantiate: true
@@ -73,6 +79,10 @@ export class AssetContainer extends AbstractScene {
             convertionMap[source.uniqueId] = clone.uniqueId;
             storeMap[clone.uniqueId] = clone;
 
+            if (nameFunction) {
+                clone.name = nameFunction(source.name);
+            }
+
             if (clone instanceof Mesh) {
                 let clonedMesh = clone as Mesh;
 
@@ -107,6 +117,50 @@ export class AssetContainer extends AbstractScene {
             if (!o.parent) {
                 let newOne = o.instantiateHierarchy(null, options, (source, clone) => {
                     onClone(source, clone);
+
+                    if ((clone as any).material) {
+                        let mesh = clone as AbstractMesh;
+
+                        if (mesh.material) {
+                            if (cloneMaterials) {
+                                let sourceMaterial = (source as AbstractMesh).material!;
+                                
+                                if (alreadySwappedMaterials.indexOf(sourceMaterial) === -1) {
+                                    let swap = sourceMaterial.clone(nameFunction ? nameFunction(sourceMaterial.name) : "Clone of " + sourceMaterial.name)!;
+                                    alreadySwappedMaterials.push(sourceMaterial);
+                                    convertionMap[sourceMaterial.uniqueId] = swap.uniqueId;
+                                    storeMap[swap.uniqueId] = swap;
+
+                                    if (sourceMaterial.getClassName() === "MultiMaterial") {
+                                        let multi = sourceMaterial as MultiMaterial;
+
+                                        for (var material of multi.subMaterials) {
+                                            if (!material) {
+                                                continue;
+                                            }
+                                            swap = material.clone(nameFunction ? nameFunction(material.name) : "Clone of " + material.name)!;
+                                            alreadySwappedMaterials.push(material);
+                                            convertionMap[material.uniqueId] = swap.uniqueId;
+                                            storeMap[swap.uniqueId] = swap;
+                                        }
+                                    }
+                                }
+
+                                mesh.material = storeMap[convertionMap[sourceMaterial.uniqueId]];
+                            } else {
+                                if (mesh.material.getClassName() === "MultiMaterial") {
+                                    if (this.scene.multiMaterials.indexOf(mesh.material as MultiMaterial) === -1) {
+                                        this.scene.addMultiMaterial(mesh.material as MultiMaterial);
+                                    }
+                                } else {
+                                    if (this.scene.materials.indexOf(mesh.material) === -1) {
+                                        this.scene.addMaterial(mesh.material);
+                                    }
+                                }
+                            }
+                        }
+                    }
+
                 });
 
                 if (newOne) {
@@ -116,7 +170,7 @@ export class AssetContainer extends AbstractScene {
         });
 
         this.skeletons.forEach((s) => {
-            let clone = s.clone("Clone of " + s.name);
+            let clone =  s.clone(nameFunction ? nameFunction(s.name) :"Clone of " + s.name);
 
             if (s.overrideMesh) {
                 clone.overrideMesh = storeMap[convertionMap[s.overrideMesh.uniqueId]];
@@ -127,11 +181,11 @@ export class AssetContainer extends AbstractScene {
                     let copy = storeMap[convertionMap[m.uniqueId]];
                     (copy as Mesh).skeleton = clone;
 
-                    if (alreadySwapped.indexOf(clone) !== -1) {
+                    if (alreadySwappedSkeletons.indexOf(clone) !== -1) {
                         continue;
                     }
 
-                    alreadySwapped.push(clone);
+                    alreadySwappedSkeletons.push(clone);
 
                     // Check if bones are mesh linked
                     for (var bone of clone.bones) {

+ 8 - 11
src/node.ts

@@ -190,7 +190,7 @@ export class Node implements IBehaviorAware<Node> {
             }
 
             if (!parent && !this._isDisposed) {
-                this.addToSceneRootNodes();
+                this._addToSceneRootNodes();
             }
         }
 
@@ -205,7 +205,7 @@ export class Node implements IBehaviorAware<Node> {
             this._parentNode._children.push(this);
 
             if (!previousParentNode) {
-                this.removeFromSceneRootNodes();
+                this._removeFromSceneRootNodes();
             }
         }
 
@@ -217,14 +217,16 @@ export class Node implements IBehaviorAware<Node> {
         return this._parentNode;
     }
 
-    private addToSceneRootNodes() {
+    /** @hidden */
+    public _addToSceneRootNodes() {
         if (this._sceneRootNodesIndex === -1) {
             this._sceneRootNodesIndex = this._scene.rootNodes.length;
             this._scene.rootNodes.push(this);
         }
     }
 
-    private removeFromSceneRootNodes() {
+    /** @hidden */
+    public _removeFromSceneRootNodes() {
         if (this._sceneRootNodesIndex !== -1) {
             const rootNodes = this._scene.rootNodes;
             const lastIdx = rootNodes.length - 1;
@@ -282,18 +284,13 @@ export class Node implements IBehaviorAware<Node> {
      * Creates a new Node
      * @param name the name and id to be given to this node
      * @param scene the scene this node will be added to
-     * @param addToRootNodes the node will be added to scene.rootNodes
      */
-    constructor(name: string, scene: Nullable<Scene> = null, addToRootNodes = true) {
+    constructor(name: string, scene: Nullable<Scene> = null) {
         this.name = name;
         this.id = name;
         this._scene = <Scene>(scene || EngineStore.LastCreatedScene);
         this.uniqueId = this._scene.getUniqueId();
         this._initCache();
-
-        if (addToRootNodes) {
-            this.addToSceneRootNodes();
-        }
     }
 
     /**
@@ -764,7 +761,7 @@ export class Node implements IBehaviorAware<Node> {
         }
 
         if (!this.parent) {
-            this.removeFromSceneRootNodes();
+            this._removeFromSceneRootNodes();
         } else {
             this.parent = null;
         }

+ 30 - 0
src/scene.ts

@@ -2004,6 +2004,10 @@ export class Scene extends AbstractScene implements IAnimatable {
 
         newMesh._resyncLightSources();
 
+        if (!newMesh.parent) {
+            newMesh._addToSceneRootNodes();
+        }          
+
         this.onNewMeshAddedObservable.notifyObservers(newMesh);
 
         if (recursive) {
@@ -2025,6 +2029,10 @@ export class Scene extends AbstractScene implements IAnimatable {
             // Remove from the scene if mesh found
             this.meshes[index] = this.meshes[this.meshes.length - 1];
             this.meshes.pop();
+
+            if (!toRemove.parent) {
+                toRemove._removeFromSceneRootNodes();
+            }
         }
 
         this.onMeshRemovedObservable.notifyObservers(toRemove);
@@ -2044,6 +2052,10 @@ export class Scene extends AbstractScene implements IAnimatable {
         newTransformNode._indexInSceneTransformNodesArray = this.transformNodes.length;
         this.transformNodes.push(newTransformNode);
 
+        if (!newTransformNode.parent) {
+            newTransformNode._addToSceneRootNodes();
+        }            
+
         this.onNewTransformNodeAddedObservable.notifyObservers(newTransformNode);
     }
 
@@ -2063,6 +2075,9 @@ export class Scene extends AbstractScene implements IAnimatable {
 
             toRemove._indexInSceneTransformNodesArray = -1;
             this.transformNodes.pop();
+            if (!toRemove.parent) {
+                toRemove._removeFromSceneRootNodes();
+            }
         }
 
         this.onTransformNodeRemovedObservable.notifyObservers(toRemove);
@@ -2117,6 +2132,10 @@ export class Scene extends AbstractScene implements IAnimatable {
             // Remove from the scene if mesh found
             this.lights.splice(index, 1);
             this.sortLightsByPriority();
+
+            if (!toRemove.parent) {
+                toRemove._removeFromSceneRootNodes();
+            }
         }
         this.onLightRemovedObservable.notifyObservers(toRemove);
         return index;
@@ -2132,6 +2151,9 @@ export class Scene extends AbstractScene implements IAnimatable {
         if (index !== -1) {
             // Remove from the scene if mesh found
             this.cameras.splice(index, 1);
+            if (!toRemove.parent) {
+                toRemove._removeFromSceneRootNodes();
+            }
         }
         // Remove from activeCameras
         var index2 = this.activeCameras.indexOf(toRemove);
@@ -2272,6 +2294,10 @@ export class Scene extends AbstractScene implements IAnimatable {
         this.lights.push(newLight);
         this.sortLightsByPriority();
 
+        if (!newLight.parent) {
+            newLight._addToSceneRootNodes();
+        }        
+
         // Add light to all meshes (To support if the light is removed and then readded)
         for (var mesh of this.meshes) {
             if (mesh.lightSources.indexOf(newLight) === -1) {
@@ -2299,6 +2325,10 @@ export class Scene extends AbstractScene implements IAnimatable {
     public addCamera(newCamera: Camera): void {
         this.cameras.push(newCamera);
         this.onNewCameraAddedObservable.notifyObservers(newCamera);
+
+        if (!newCamera.parent) {
+            newCamera._addToSceneRootNodes();
+        }
     }
 
     /**