瀏覽代碼

Merge pull request #3771 from RaananW/viewer-load-meh-fix

Viewer load mesh fix
Raanan Weber 7 年之前
父節點
當前提交
6f1b2d1846

+ 8 - 0
Viewer/src/templateManager.ts

@@ -303,8 +303,12 @@ export class Template {
         });
     }
 
+    private isShowing: boolean;
+    private isHiding: boolean;
     public show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
+        if (this.isHiding) return Promise.resolve(this);
         return Promise.resolve().then(() => {
+            this.isShowing = true;
             if (visibilityFunction) {
                 return visibilityFunction(this);
             } else {
@@ -314,13 +318,16 @@ export class Template {
             }
         }).then(() => {
             this.isShown = true;
+            this.isShowing = false;
             this.onStateChange.notifyObservers(this);
             return this;
         });
     }
 
     public hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
+        if (this.isShowing) return Promise.resolve(this);
         return Promise.resolve().then(() => {
+            this.isHiding = true;
             if (visibilityFunction) {
                 return visibilityFunction(this);
             } else {
@@ -330,6 +337,7 @@ export class Template {
             }
         }).then(() => {
             this.isShown = false;
+            this.isHiding = false;
             this.onStateChange.notifyObservers(this);
             return this;
         });

+ 2 - 2
Viewer/src/viewer/defaultViewer.ts

@@ -103,8 +103,8 @@ export class DefaultViewer extends AbstractViewer {
         this.containerElement.style.display = 'flex';
     }
 
-    protected configureModel(modelConfiguration: Partial<IModelConfiguration>) {
-        super.configureModel(modelConfiguration);
+    protected configureModel(modelConfiguration: Partial<IModelConfiguration>, focusMeshes: Array<AbstractMesh> = this.scene.meshes) {
+        super.configureModel(modelConfiguration, focusMeshes);
 
         let navbar = this.templateManager.getTemplate('navBar');
         if (!navbar) return;

+ 41 - 7
Viewer/src/viewer/viewer.ts

@@ -421,7 +421,9 @@ export abstract class AbstractViewer {
             }
         };
 
-        const sceneExtends = this.scene.getWorldExtends();
+        const sceneExtends = this.scene.getWorldExtends((mesh) => {
+            return !this.environmentHelper || (mesh !== this.environmentHelper.ground && mesh !== this.environmentHelper.rootMesh && mesh !== this.environmentHelper.skybox);
+        });
         const sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);
         const sceneDiagonalLenght = sceneDiagonal.length();
         if (isFinite(sceneDiagonalLenght))
@@ -744,13 +746,36 @@ export abstract class AbstractViewer {
         return Promise.resolve(this.scene);
     }
 
+    private isLoading: boolean;
+    private nextLoading: Function;
+
     public loadModel(model: any = this.configuration.model, clearScene: boolean = true): Promise<Scene> {
         // no model was provided? Do nothing!
-        if (!model.url) {
+        let modelUrl = (typeof model === 'string') ? model : model.url;
+        if (!modelUrl) {
             return Promise.resolve(this.scene);
         }
-        this.configuration.model = model;
-        let modelUrl = (typeof model === 'string') ? model : model.url;
+        if (this.isLoading) {
+            //another model is being model. Wait for it to finish, trigger the load afterwards
+            this.nextLoading = () => {
+                delete this.nextLoading;
+                this.loadModel(model, clearScene);
+            }
+            return Promise.resolve(this.scene);
+        }
+        this.isLoading = true;
+        if ((typeof model === 'string')) {
+            if (this.configuration.model && typeof this.configuration.model === 'object') {
+                this.configuration.model.url = model;
+            }
+        } else {
+            if (this.configuration.model) {
+                deepmerge(this.configuration.model, model)
+            } else {
+                this.configuration.model = model;
+            }
+        }
+
         let parts = modelUrl.split('/');
         let filename = parts.pop();
         let base = parts.join('/') + '/';
@@ -761,13 +786,18 @@ export abstract class AbstractViewer {
 
             if (clearScene) {
                 scene.meshes.forEach(mesh => {
-                    mesh.dispose();
+                    if (Tags.MatchesQuery(mesh, "viewerMesh")) {
+                        mesh.dispose();
+                    }
                 });
             }
             return scene!;
         }).then(() => {
             return new Promise<Array<AbstractMesh>>((resolve, reject) => {
                 this.lastUsedLoader = SceneLoader.ImportMesh(undefined, base, filename, this.scene, (meshes) => {
+                    meshes.forEach(mesh => {
+                        Tags.AddTagsTo(mesh, "viewerMesh");
+                    });
                     resolve(meshes);
                 }, (progressEvent) => {
                     this.onModelLoadProgressObservable.notifyObserversWithPromise(progressEvent);
@@ -783,7 +813,7 @@ export abstract class AbstractViewer {
             return this.onModelLoadedObservable.notifyObserversWithPromise(meshes)
                 .then(() => {
                     // update the models' configuration
-                    this.configureModel(model, meshes);
+                    this.configureModel(this.configuration.model || model, meshes);
                     this.configureLights(this.configuration.lights);
 
                     if (this.configuration.camera) {
@@ -791,12 +821,16 @@ export abstract class AbstractViewer {
                     }
                     return this.initEnvironment(meshes);
                 }).then(() => {
+                    this.isLoading = false;
+                    if (this.nextLoading) {
+                        return this.nextLoading();
+                    }
                     return this.scene;
                 });
         });
     }
 
-    protected initEnvironment(focusMeshes: Array<AbstractMesh> = []): Promise<Scene> {
+    protected initEnvironment(focusMeshes: Array<AbstractMesh> = this.scene.meshes): Promise<Scene> {
         this.configureEnvironment(this.configuration.skybox, this.configuration.ground);
 
         return Promise.resolve(this.scene);

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

@@ -83,6 +83,7 @@
 - SPS internal temporary vector3 instead of Tmp.Vector3 to avoid possible concurrent uses ([jbousquie](https://github.com/jbousquie))
 - Fixed a bug when calling load on an empty assets manager - [#3739](https://github.com/BabylonJS/Babylon.js/issues/3739). ([RaananW](https://github.com/RaananW))
 - Enabling teleportation in the vr helper class caused a redundant post process to be added ([trevordev](https://github.com/trevordev))
+- (Viewer) Fixed a bug where loading another mesh positioned it incorrectly ([RaananW](https://github.com/RaananW))
 
 ## Breaking changes
 

+ 3 - 1
src/Helpers/babylon.environmentHelper.ts

@@ -476,7 +476,9 @@ module BABYLON {
                 return { groundSize, skyboxSize, rootPosition };
             }
 
-            const sceneExtends = this._scene.getWorldExtends();
+            const sceneExtends = this._scene.getWorldExtends((mesh) => {
+                return (mesh !== this._ground && mesh !== this._rootMesh && mesh !== this._skybox);
+            });
             const sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);
 
             if (this._options.sizeAuto) {

+ 11 - 6
src/babylon.scene.ts

@@ -4230,16 +4230,21 @@
         }
 
         // Octrees
-        public getWorldExtends(): { min: Vector3; max: Vector3 } {
+        /**
+         * Get the world extend vectors with an optional filter
+         * 
+         * @param {(mesh: AbstractMesh) => boolean} [filterPredicate] the predicate - which meshes should be included when calculating the world size
+         * @returns {{ min: Vector3; max: Vector3 }} min and max vectors
+         */
+        public getWorldExtends(filterPredicate?: (mesh: AbstractMesh) => boolean): { min: Vector3; max: Vector3 } {
             var min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
-            for (var index = 0; index < this.meshes.length; index++) {
-                var mesh = this.meshes[index];
-
+            filterPredicate = filterPredicate || (() => true);
+            this.meshes.filter(filterPredicate).forEach(mesh => {
                 mesh.computeWorldMatrix(true);
 
                 if (!mesh.subMeshes || mesh.subMeshes.length === 0 || mesh.infiniteDistance) {
-                    continue;
+                    return;
                 }
 
                 let boundingInfo = mesh.getBoundingInfo();
@@ -4249,7 +4254,7 @@
 
                 Tools.CheckExtends(minBox, min, max);
                 Tools.CheckExtends(maxBox, min, max);
-            }
+            })
 
             return {
                 min: min,