Browse Source

Better fix for #7606

David Catuhe 5 years ago
parent
commit
51bf585aba

+ 6 - 2
loaders/src/OBJ/mtlFileLoader.ts

@@ -27,8 +27,9 @@ export class MTLFileLoader {
      * @param scene defines the scene the material will be created in
      * @param data defines the mtl data to parse
      * @param rootUrl defines the rooturl to use in order to load relative dependencies
+     * @param forAssetContainer defines if the matetrial should be registered in the scene
      */
-    public parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string): void {
+    public parseMTL(scene: Scene, data: string | ArrayBuffer, rootUrl: string, forAssetContainer: boolean): void {
         if (data instanceof ArrayBuffer) {
             return;
         }
@@ -69,7 +70,10 @@ export class MTLFileLoader {
                 }
                 //Create a new material.
                 // value is the name of the material read in the mtl file
-                material = new StandardMaterial(value, scene);
+                
+                scene._blockEntityCollection = forAssetContainer;
+                material = new StandardMaterial(value, scene);                
+                scene._blockEntityCollection = false;
             } else if (key === "kd" && material) {
                 // Diffuse color (color under white light) using RGB values
 

+ 10 - 1
loaders/src/OBJ/objFileLoader.ts

@@ -153,6 +153,8 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
     /** @hidden */
     public facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
 
+    private _forAssetContainer = false;
+
     private _meshLoadOptions: MeshLoadOptions;
 
     /**
@@ -271,6 +273,7 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
      * @returns The loaded asset container
      */
     public loadAssetContainerAsync(scene: Scene, data: string, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<AssetContainer> {
+        this._forAssetContainer = true;
         return this.importMeshAsync(null, scene, data, rootUrl).then((result) => {
             var container = new AssetContainer(scene);
             result.meshes.forEach((mesh) => container.meshes.push(mesh));
@@ -292,6 +295,8 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
                 }
             });
             return container;
+        }).finally(() => {
+            this._forAssetContainer = false;
         });
     }
 
@@ -918,7 +923,11 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
             //Set the data with VertexBuffer for each mesh
             handledMesh = meshesFromObj[j];
             //Create a Mesh with the name of the obj mesh
+            
+            scene._blockEntityCollection = this._forAssetContainer;
             var babylonMesh = new Mesh(meshesFromObj[j].name, scene);
+            scene._blockEntityCollection = false;
+
             //Push the name of the material to an array
             //This is indispensable for the importMesh function
             materialToUse.push(meshesFromObj[j].materialName);
@@ -957,7 +966,7 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
                 this._loadMTL(fileToLoad, rootUrl, (dataLoaded) => {
                     try {
                         //Create materials thanks MTLLoader function
-                        materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl);
+                        materialsFromMTLFile.parseMTL(scene, dataLoaded, rootUrl, this._forAssetContainer);
                         //Look at each material loaded in the mtl file
                         for (var n = 0; n < materialsFromMTLFile.materials.length; n++) {
                             //Three variables to get all meshes with the same material

+ 2 - 0
loaders/src/STL/stlFileLoader.ts

@@ -136,7 +136,9 @@ export class STLFileLoader implements ISceneLoaderPlugin {
      */
     public loadAssetContainer(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): AssetContainer {
         var container = new AssetContainer(scene);
+        scene._blockEntityCollection = true;
         this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+        scene._blockEntityCollection = false;
         return container;
     }
 

+ 25 - 6
loaders/src/glTF/1.0/glTFLoader.ts

@@ -246,7 +246,9 @@ var loadAnimations = (gltfRuntime: IGLTFRuntime) => {
             }
 
             if (!modifyKey) {
+                gltfRuntime.scene._blockEntityCollection = gltfRuntime.forAssetContainer;
                 babylonAnimation = new Animation(anim, isBone ? "_matrix" : targetPath, 1, animationType, Animation.ANIMATIONLOOPMODE_CYCLE);
+                gltfRuntime.scene._blockEntityCollection = false;
             }
 
             // For each frame
@@ -606,7 +608,9 @@ var importSkeleton = (gltfRuntime: IGLTFRuntime, skins: IGLTFSkins, mesh: Mesh,
 */
 var importMesh = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, meshes: string[], id: string, newMesh: Mesh): Mesh => {
     if (!newMesh) {
+        gltfRuntime.scene._blockEntityCollection = gltfRuntime.forAssetContainer;
         newMesh = new Mesh(node.name || "", gltfRuntime.scene);
+        gltfRuntime.scene._blockEntityCollection = false;
         newMesh.id = id;
     }
 
@@ -732,6 +736,7 @@ var importMesh = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, meshes: string[],
         }
     }
     let material: StandardMaterial | MultiMaterial;
+    gltfRuntime.scene._blockEntityCollection = gltfRuntime.forAssetContainer;
     if (subMaterials.length > 1) {
         material = new MultiMaterial("multimat" + id, gltfRuntime.scene);
         (material as MultiMaterial).subMaterials = subMaterials;
@@ -752,6 +757,8 @@ var importMesh = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, meshes: string[],
     new Geometry(id, gltfRuntime.scene, vertexData!, false, newMesh);
     newMesh.computeWorldMatrix(true);
 
+    gltfRuntime.scene._blockEntityCollection = false;
+
     // Apply submeshes
     newMesh.subMeshes = [];
     var index = 0;
@@ -916,6 +923,8 @@ var importNode = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, id: string, parent
         var camera: IGLTFCamera = gltfRuntime.cameras[node.camera];
 
         if (camera) {
+            
+            gltfRuntime.scene._blockEntityCollection = gltfRuntime.forAssetContainer;
             if (camera.type === "orthographic") {
                 var orthoCamera = new FreeCamera(node.camera, Vector3.Zero(), gltfRuntime.scene, false);
 
@@ -943,6 +952,8 @@ var importNode = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, id: string, parent
 
                 lastNode = persCamera;
             }
+            
+            gltfRuntime.scene._blockEntityCollection = false;
         }
     }
 
@@ -952,7 +963,9 @@ var importNode = (gltfRuntime: IGLTFRuntime, node: IGLTFNode, id: string, parent
             return node.babylonNode;
         }
         else if (lastNode === null) {
+            gltfRuntime.scene._blockEntityCollection = gltfRuntime.forAssetContainer;
             var dummy = new Mesh(node.name || "", gltfRuntime.scene);
+            gltfRuntime.scene._blockEntityCollection = false;
             node.babylonNode = dummy;
             lastNode = dummy;
         }
@@ -1238,7 +1251,9 @@ export class GLTFLoaderBase {
 
             importOnlyMeshes: false,
 
-            dummyNodes: []
+            dummyNodes: [],
+
+            forAssetContainer: false
         };
 
         // Parse
@@ -1430,7 +1445,9 @@ export class GLTFLoaderBase {
 
         var technique: IGLTFTechnique = gltfRuntime.techniques[material.technique];
         if (!technique) {
+            gltfRuntime.scene._blockEntityCollection = gltfRuntime.forAssetContainer;
             var defaultMaterial = new StandardMaterial(id, gltfRuntime.scene);
+            gltfRuntime.scene._blockEntityCollection = false;
             defaultMaterial.diffuseColor = new Color3(0.5, 0.5, 0.5);
             defaultMaterial.sideOrientation = Material.CounterClockWiseSideOrientation;
             onSuccess(defaultMaterial);
@@ -1605,10 +1622,11 @@ export class GLTFLoader implements IGLTFLoader {
         // do nothing
     }
 
-    private _importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], skeletons: Skeleton[]) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string) => void): boolean {
+    private _importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, forAssetContainer: boolean, onSuccess: (meshes: AbstractMesh[], skeletons: Skeleton[]) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string) => void): boolean {
         scene.useRightHandedSystem = true;
 
         GLTFLoaderExtension.LoadRuntimeAsync(scene, data, rootUrl, (gltfRuntime) => {
+            gltfRuntime.forAssetContainer = forAssetContainer;
             gltfRuntime.importOnlyMeshes = true;
 
             if (meshesNames === "") {
@@ -1672,14 +1690,15 @@ export class GLTFLoader implements IGLTFLoader {
     * Imports one or more meshes from a loaded gltf file and adds them to the scene
     * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
     * @param scene the scene the meshes should be added to
+    * @param forAssetContainer defines if the entities must be stored in the scene
     * @param data gltf data containing information of the meshes in a loaded file
     * @param rootUrl root url to load from
     * @param onProgress event that fires when loading progress has occured
     * @returns a promise containg the loaded meshes, particles, skeletons and animations
     */
-    public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
+    public importMeshAsync(meshesNames: any, scene: Scene, forAssetContainer: boolean, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
         return new Promise((resolve, reject) => {
-            this._importMeshAsync(meshesNames, scene, data, rootUrl, (meshes, skeletons) => {
+            this._importMeshAsync(meshesNames, scene, data, rootUrl, forAssetContainer, (meshes, skeletons) => {
                 resolve({
                     meshes: meshes,
                     particleSystems: [],
@@ -1692,7 +1711,7 @@ export class GLTFLoader implements IGLTFLoader {
         });
     }
 
-    private _loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string) => void): void {
+    private _loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, forAssetContainer: boolean, onSuccess: () => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string) => void): void {
         scene.useRightHandedSystem = true;
 
         GLTFLoaderExtension.LoadRuntimeAsync(scene, data, rootUrl, (gltfRuntime) => {
@@ -1730,7 +1749,7 @@ export class GLTFLoader implements IGLTFLoader {
     */
     public loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<void> {
         return new Promise((resolve, reject) => {
-            this._loadAsync(scene, data, rootUrl, () => {
+            this._loadAsync(scene, data, rootUrl, false, () => {
                 resolve();
             }, onProgress, (message) => {
                 reject(new Error(message));

+ 2 - 0
loaders/src/glTF/1.0/glTFLoaderInterfaces.ts

@@ -409,6 +409,8 @@ export interface IGLTFRuntime {
     importMeshesNames?: string[];
 
     dummyNodes: Node[];
+
+    forAssetContainer: boolean;
 }
 
 /** @hidden */

+ 4 - 0
loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts

@@ -85,6 +85,8 @@ export class KHR_lights implements IGLTFLoaderExtension {
                 const light = ArrayItem.Get(extensionContext, this._lights, extension.light);
                 const name = light.name || babylonMesh.name;
 
+                this._loader.babylonScene._blockEntityCollection = this._loader._forAssetContainer;
+
                 switch (light.type) {
                     case LightType.DIRECTIONAL: {
                         babylonLight = new DirectionalLight(name, Vector3.Backward(), this._loader.babylonScene);
@@ -102,10 +104,12 @@ export class KHR_lights implements IGLTFLoaderExtension {
                         break;
                     }
                     default: {
+                        this._loader.babylonScene._blockEntityCollection = false;
                         throw new Error(`${extensionContext}: Invalid light type (${light.type})`);
                     }
                 }
 
+                this._loader.babylonScene._blockEntityCollection = false;
                 babylonLight.falloffType = Light.FALLOFF_GLTF;
                 babylonLight.diffuse = light.color ? Color3.FromArray(light.color) : Color3.White();
                 babylonLight.intensity = light.intensity == undefined ? 1 : light.intensity;

+ 22 - 2
loaders/src/glTF/2.0/glTFLoader.ts

@@ -99,6 +99,9 @@ export class GLTFLoader implements IGLTFLoader {
     /** @hidden */
     public _completePromises = new Array<Promise<any>>();
 
+    /** @hidden */
+    public _forAssetContainer = false;
+
     private _disposed = false;
     private _parent: GLTFFileLoader;
     private _state: Nullable<GLTFLoaderState> = null;
@@ -225,12 +228,13 @@ export class GLTFLoader implements IGLTFLoader {
     }
 
     /** @hidden */
-    public importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
+    public importMeshAsync(meshesNames: any, scene: Scene, forAssetContainer: boolean, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string): Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }> {
         return Promise.resolve().then(() => {
             this._babylonScene = scene;
             this._rootUrl = rootUrl;
             this._fileName = fileName || "scene";
             this._progressCallback = onProgress;
+            this._forAssetContainer = forAssetContainer;
             this._loadData(data);
 
             let nodes: Nullable<Array<number>> = null;
@@ -455,7 +459,9 @@ export class GLTFLoader implements IGLTFLoader {
     }
 
     private _createRootNode(): INode {
+        this._babylonScene._blockEntityCollection = this._forAssetContainer;
         this._rootBabylonMesh = new Mesh("__root__", this._babylonScene);
+        this._babylonScene._blockEntityCollection = false;
         this._rootBabylonMesh.setEnabled(false);
 
         const rootNode: INode = {
@@ -755,7 +761,9 @@ export class GLTFLoader implements IGLTFLoader {
         else {
             const promises = new Array<Promise<any>>();
 
+            this._babylonScene._blockEntityCollection = this._forAssetContainer;
             const babylonMesh = new Mesh(name, this._babylonScene);
+            this._babylonScene._blockEntityCollection = false;
             babylonMesh.overrideMaterialSideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
 
             this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
@@ -1012,7 +1020,9 @@ export class GLTFLoader implements IGLTFLoader {
         }
 
         const skeletonId = `skeleton${skin.index}`;
+        this._babylonScene._blockEntityCollection = this._forAssetContainer;
         const babylonSkeleton = new Skeleton(skin.name || skeletonId, skeletonId, this._babylonScene);
+        this._babylonScene._blockEntityCollection = false;
 
         // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
         babylonSkeleton.overrideMesh = this._rootBabylonMesh;
@@ -1116,7 +1126,11 @@ export class GLTFLoader implements IGLTFLoader {
 
         this.logOpen(`${context} ${camera.name || ""}`);
 
-        const babylonCamera = new FreeCamera(camera.name || `camera${camera.index}`, Vector3.Zero(), this._babylonScene, false);
+        
+        this._babylonScene._blockEntityCollection = this._forAssetContainer;
+        const babylonCamera = new FreeCamera(camera.name || `camera${camera.index}`, Vector3.Zero(), this._babylonScene, false);        
+        this._babylonScene._blockEntityCollection = false;
+
         babylonCamera.rotation = new Vector3(0, Math.PI, 0);
 
         switch (camera.type) {
@@ -1187,7 +1201,9 @@ export class GLTFLoader implements IGLTFLoader {
             return promise;
         }
 
+        this._babylonScene._blockEntityCollection = this._forAssetContainer;
         const babylonAnimationGroup = new AnimationGroup(animation.name || `animation${animation.index}`, this._babylonScene);
+        this._babylonScene._blockEntityCollection = false;
         animation._babylonAnimationGroup = babylonAnimationGroup;
 
         const promises = new Array<Promise<any>>();
@@ -1687,7 +1703,9 @@ export class GLTFLoader implements IGLTFLoader {
     }
 
     private _createDefaultMaterial(name: string, babylonDrawMode: number): Material {
+        this._babylonScene._blockEntityCollection = this._forAssetContainer;
         const babylonMaterial = new PBRMaterial(name, this._babylonScene);
+        this._babylonScene._blockEntityCollection = false;
         // Moved to mesh so user can change materials on gltf meshes: babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? Material.CounterClockWiseSideOrientation : Material.ClockWiseSideOrientation;
         babylonMaterial.fillMode = babylonDrawMode;
         babylonMaterial.enableSpecularAntiAliasing = true;
@@ -1894,6 +1912,7 @@ export class GLTFLoader implements IGLTFLoader {
         }
 
         const deferred = new Deferred<void>();
+        this._babylonScene._blockEntityCollection = this._forAssetContainer;
         const babylonTexture = new Texture(url, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, () => {
             if (!this._disposed) {
                 deferred.resolve();
@@ -1903,6 +1922,7 @@ export class GLTFLoader implements IGLTFLoader {
                 deferred.reject(new Error(`${context}: ${(exception && exception.message) ? exception.message : message || "Failed to load texture"}`));
             }
         }, undefined, undefined, undefined, image.mimeType);
+        this._babylonScene._blockEntityCollection = false;
         promises.push(deferred.promise);
 
         if (!url) {

+ 3 - 3
loaders/src/glTF/glTFFileLoader.ts

@@ -112,7 +112,7 @@ export enum GLTFLoaderState {
 /** @hidden */
 export interface IGLTFLoader extends IDisposable {
     readonly state: Nullable<GLTFLoaderState>;
-    importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }>;
+    importMeshAsync: (meshesNames: any, scene: Scene, forAssetContainer: boolean, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<{ meshes: AbstractMesh[], particleSystems: IParticleSystem[], skeletons: Skeleton[], animationGroups: AnimationGroup[] }>;
     loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void, fileName?: string) => Promise<void>;
 }
 
@@ -551,7 +551,7 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
 
             this._log(`Loading ${fileName || ""}`);
             this._loader = this._getLoader(data);
-            return this._loader.importMeshAsync(meshesNames, scene, data, rootUrl, onProgress, fileName);
+            return this._loader.importMeshAsync(meshesNames, scene, false, data, rootUrl, onProgress, fileName);
         });
     }
 
@@ -586,7 +586,7 @@ export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISc
                 textures.push(texture);
             });
 
-            return this._loader.importMeshAsync(null, scene, data, rootUrl, onProgress, fileName).then((result) => {
+            return this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then((result) => {
                 const container = new AssetContainer(scene);
                 Array.prototype.push.apply(container.meshes, result.meshes);
                 Array.prototype.push.apply(container.particleSystems, result.particleSystems);

+ 3 - 0
src/Loading/Plugins/babylonFileLoader.ts

@@ -112,6 +112,8 @@ var loadDetailLevels = (scene: Scene, mesh: AbstractMesh) => {
 var loadAssetContainer = (scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void, addToScene = false): AssetContainer => {
     var container = new AssetContainer(scene);
 
+    scene._blockEntityCollection = !addToScene;
+
     // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details
     // when SceneLoader.debugLogging = true (default), or exception encountered.
     // Everything stored in var log instead of writing separate lines to support only writing in exception,
@@ -448,6 +450,7 @@ var loadAssetContainer = (scene: Scene, data: string, rootUrl: string, onError?:
             throw err;
         }
     } finally {
+        scene._blockEntityCollection = false;
         if (log !== null && SceneLoader.loggingLevel !== SceneLoader.NO_LOGGING) {
             Logger.Log(logOperation("loadAssets", parsedData ? parsedData.producer : "Unknown") + (SceneLoader.loggingLevel !== SceneLoader.MINIMAL_LOGGING ? log : ""));
         }

+ 0 - 5
src/Loading/sceneLoader.ts

@@ -901,8 +901,6 @@ export class SceneLoader {
             return null;
         }
 
-        scene._blockEntityCollection = true;
-
         const fileInfo = SceneLoader._getFileInfo(rootUrl, sceneFilename);
         if (!fileInfo) {
             return null;
@@ -916,8 +914,6 @@ export class SceneLoader {
         };
 
         var errorHandler = (message: Nullable<string>, exception?: any) => {
-            scene._blockEntityCollection = false;
-
             let errorMessage = "Unable to load assets from " + fileInfo.url + (message ? ": " + message : "");
 
             if (exception && exception.message) {
@@ -944,7 +940,6 @@ export class SceneLoader {
         } : undefined;
 
         var successHandler = (assets: AssetContainer) => {
-            scene._blockEntityCollection = false;
             if (onSuccess) {
                 try {
                     onSuccess(assets);