Browse Source

forcing a root mesh on viewer model

Raanan Weber 7 years ago
parent
commit
6cb0d5707c

+ 1 - 0
Viewer/src/configuration/configuration.ts

@@ -76,6 +76,7 @@ export interface IModelConfiguration {
     parentObjectIndex?: number; // the index of the parent object of the model in the loaded meshes array.
 
     castShadow?: boolean;
+    receiveShadows?: boolean;
     normalize?: boolean | {
         center?: boolean;
         unitSize?: boolean;

+ 1 - 1
Viewer/src/model/modelLoader.ts

@@ -47,8 +47,8 @@ export class ModelLoader {
         model.loader = SceneLoader.ImportMesh(undefined, base, filename, this._viewer.scene, (meshes, particleSystems, skeletons, animationGroups) => {
             meshes.forEach(mesh => {
                 Tags.AddTagsTo(mesh, "viewerMesh");
+                model.addMesh(mesh);
             });
-            model.meshes = meshes;
             model.particleSystems = particleSystems;
             model.skeletons = skeletons;
 

+ 46 - 8
Viewer/src/model/viewerModel.ts

@@ -30,10 +30,10 @@ export class ViewerModel implements IDisposable {
     /**
      * the list of meshes that are a part of this model
      */
-    public meshes: Array<AbstractMesh> = [];
+    private _meshes: Array<AbstractMesh> = [];
     /**
      * This model's root mesh (the parent of all other meshes).
-     * This mesh also exist in the meshes array.
+     * This mesh does not(!) exist in the meshes array.
      */
     public rootMesh: AbstractMesh;
     /**
@@ -88,13 +88,40 @@ export class ViewerModel implements IDisposable {
 
         this.state = ModelState.INIT;
 
+        this.rootMesh = new AbstractMesh("modelRootMesh", this._viewer.scene);
+
         this._animations = [];
         //create a copy of the configuration to make sure it doesn't change even after it is changed in the viewer
         this._modelConfiguration = deepmerge({}, modelConfiguration);
 
         this._viewer.models.push(this);
+        this._viewer.onModelAddedObservable.notifyObservers(this);
+
+    }
+
+    /**
+     * Add a mesh to this model.
+     * Any mesh that has no parent will be provided with the root mesh as its new parent.
+     * 
+     * @param mesh the new mesh to add
+     */
+    public addMesh(mesh: AbstractMesh) {
+        if (!mesh.parent) {
+            mesh.parent = this.rootMesh;
+        }
+        mesh.receiveShadows = !!this.configuration.receiveShadows;
+        this._meshes.push(mesh);
+    }
+
+    /**
+     * get the list of meshes (excluding the root mesh)
+     */
+    public get meshes() {
+        return this._meshes;
     }
 
+    public get
+
     /**
      * Get the model's configuration
      */
@@ -215,7 +242,7 @@ export class ViewerModel implements IDisposable {
     }
 
     private _configureModel() {
-        let meshesWithNoParent: Array<AbstractMesh> = this.meshes.filter(m => !m.parent);
+        let meshesWithNoParent: Array<AbstractMesh> = this._meshes.filter(m => m === this.rootMesh);
         let updateMeshesWithNoParent = (variable: string, value: any, param?: string) => {
             meshesWithNoParent.forEach(mesh => {
                 if (param) {
@@ -261,7 +288,7 @@ export class ViewerModel implements IDisposable {
         }
 
         if (this._modelConfiguration.castShadow) {
-            this.meshes.forEach(mesh => {
+            this._meshes.forEach(mesh => {
                 Tags.AddTagsTo(mesh, 'castShadow');
             });
         }
@@ -282,7 +309,7 @@ export class ViewerModel implements IDisposable {
 
             let meshesToNormalize: Array<AbstractMesh> = [];
             if (parentIndex !== undefined) {
-                meshesToNormalize.push(this.meshes[parentIndex]);
+                meshesToNormalize.push(this._meshes[parentIndex]);
             } else {
                 meshesToNormalize = meshesWithNoParent;
             }
@@ -313,9 +340,20 @@ export class ViewerModel implements IDisposable {
     }
 
     /**
+     * Will remove this model from the viewer (but NOT dispose it).
+     */
+    public remove() {
+        this._viewer.models.splice(this._viewer.models.indexOf(this), 1);
+        // hide it
+        this.rootMesh.isVisible = false;
+        this._viewer.onModelRemovedObservable.notifyObservers(this);
+    }
+
+    /**
      * Dispose this model, including all of its associated assets.
      */
     public dispose() {
+        this.remove();
         this.onAfterConfigure.clear();
         this.onLoadedObservable.clear();
         this.onLoadErrorObservable.clear();
@@ -329,8 +367,8 @@ export class ViewerModel implements IDisposable {
         this.skeletons.length = 0;
         this._animations.forEach(ag => ag.dispose());
         this._animations.length = 0;
-        this.meshes.forEach(m => m.dispose());
-        this.meshes.length = 0;
-        this._viewer.models.splice(this._viewer.models.indexOf(this), 1);
+        this._meshes.forEach(m => m.dispose());
+        this._meshes.length = 0;
+        this.rootMesh.dispose();
     }
 }

+ 12 - 0
Viewer/src/viewer/viewer.ts

@@ -103,6 +103,12 @@ export abstract class AbstractViewer {
      * will notify when the engine was initialized
      */
     public onEngineInitObservable: Observable<Engine>;
+
+    /**
+     * Will notify when a new model was added to the scene.
+     * Note that added does not neccessarily mean loaded!
+     */
+    public onModelAddedObservable: Observable<ViewerModel>;
     /**
      * will notify after every model load
      */
@@ -116,6 +122,10 @@ export abstract class AbstractViewer {
      */
     public onModelLoadErrorObservable: Observable<{ message: string; exception: any }>;
     /**
+     * Will notify when a model was removed from the scene;
+     */
+    public onModelRemovedObservable: Observable<ViewerModel>;
+    /**
      * will notify when a new loader was initialized.
      * Used mainly to know when a model starts loading.
      */
@@ -165,6 +175,8 @@ export abstract class AbstractViewer {
         this.onModelLoadedObservable = new Observable();
         this.onModelLoadProgressObservable = new Observable();
         this.onModelLoadErrorObservable = new Observable();
+        this.onModelAddedObservable = new Observable();
+        this.onModelRemovedObservable = new Observable();
         this.onInitDoneObservable = new Observable();
         this.onLoaderInitObservable = new Observable();
         this.onFrameRenderedObservable = new Observable();