浏览代码

Merge pull request #4643 from sebavan/master

Move BoundingBoxRenderer to Component
sebavan 7 年之前
父节点
当前提交
037d7a85ef

+ 18 - 7
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 4233,
+  "errors": 4234,
   "babylon.typedoc.json": {
-    "errors": 4233,
+    "errors": 4234,
     "AbstractScene": {
       "Property": {
         "effectLayers": {
@@ -1973,11 +1973,6 @@
         }
       },
       "Method": {
-        "_rebuild": {
-          "Comments": {
-            "MissingText": true
-          }
-        },
         "dispose": {
           "Comments": {
             "MissingText": true
@@ -15180,6 +15175,22 @@
         }
       }
     },
+    "Scene": {
+      "Property": {
+        "forceShowBoundingBoxes": {
+          "Naming": {
+            "NotPascalCase": true
+          }
+        }
+      },
+      "Method": {
+        "getBoundingBoxRenderer": {
+          "Naming": {
+            "NotPascalCase": true
+          }
+        }
+      }
+    },
     "SceneInstrumentation": {
       "Constructor": {
         "new SceneInstrumentation": {

+ 1 - 1
src/Layer/babylon.effectLayerSceneComponent.ts

@@ -48,7 +48,7 @@
      * Defines the layer scene component responsible to manage any effect layers
      * in a given scene.
      */
-    export class EffectLayerSceneComponent implements ISceneComponent {
+    export class EffectLayerSceneComponent implements ISceneSerializableComponent {
         /**
          * The component name helpfull to identify the component in the list of scene components.
          */

+ 0 - 41
src/Layer/babylon.layerSceneComponent.ts

@@ -53,47 +53,6 @@
         }
 
         /**
-         * Serializes the component data to the specified json object
-         * @param serializationObject The object to serialize to
-         */
-        public serialize(serializationObject: any): void {
-            // TODO. Implement layer serialization
-            // serializationObject.layers = [];
-
-            // for (let layer of this._layers) {
-            //     if (layer.serialize) {
-            //         serializationObject.layers.push(layer.serialize());
-            //     }
-            // }
-        }
-
-        /**
-         * Adds all the element from the container to the scene
-         * @param container the container holding the elements
-         */
-        public addFromContainer(container: AbstractScene): void {
-            if (!container.layers) {
-                return;
-            }
-            // container.layers.forEach((o) => {
-            //     this.scene.addLayer(o);
-            // });
-        }
-
-        /**
-         * Removes all the elements in the container from the scene
-         * @param container contains the elements to remove 
-         */
-        public removeFromContainer(container: AbstractScene): void {
-            if (!container.layers) {
-                return;
-            }
-            // container.layers.forEach((o) => {
-            //     this.scene.removeLayer(o);
-            // });
-        }
-
-        /**
          * Disposes the component and the associated ressources.
          */
         public dispose(): void {

+ 1 - 1
src/LensFlare/babylon.lensFlareSystemSceneComponent.ts

@@ -81,7 +81,7 @@
      * Defines the layer scene component responsible to manage any layers
      * in a given scene.
      */
-    export class LensFlareSystemSceneComponent implements ISceneComponent {
+    export class LensFlareSystemSceneComponent implements ISceneSerializableComponent {
         /**
          * The component name helpfull to identify the component in the list of scene components.
          */

+ 11 - 9
src/Mesh/babylon.abstractMesh.ts

@@ -2146,18 +2146,20 @@
                 }
             }
 
+            // Todo. Move into an occlusion query component.
             var scene = this.getScene();
-            var occlusionBoundingBoxRenderer = scene.getBoundingBoxRenderer();
+            if (scene.getBoundingBoxRenderer) {
+               var occlusionBoundingBoxRenderer = scene.getBoundingBoxRenderer();
 
-            if (!this._occlusionQuery) {
-                this._occlusionQuery = engine.createQuery();
-            }
+                if (!this._occlusionQuery) {
+                    this._occlusionQuery = engine.createQuery();
+                }
 
-            engine.beginOcclusionQuery(this.occlusionQueryAlgorithmType, this._occlusionQuery);
-            occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);
-            engine.endOcclusionQuery(this.occlusionQueryAlgorithmType);
-            this._isOcclusionQueryInProgress = true;
+                engine.beginOcclusionQuery(this.occlusionQueryAlgorithmType, this._occlusionQuery);
+                occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);
+                engine.endOcclusionQuery(this.occlusionQueryAlgorithmType);
+                this._isOcclusionQueryInProgress = true;
+            }
         }
-
     }
 }

+ 0 - 1
src/Mesh/babylon.mesh.ts

@@ -1298,7 +1298,6 @@
             }
 
             var scene = this.getScene();
-
             // Managing instances
             var batch = this._getInstancesRenderList(subMesh._id);
 

+ 100 - 13
src/Rendering/babylon.boundingBoxRenderer.ts

@@ -1,17 +1,100 @@
 module BABYLON {
-    export class BoundingBoxRenderer {
+    export interface Scene {
+        /** @hidden (Backing field) */
+        _boundingBoxRenderer: BoundingBoxRenderer;
+
+        /** @hidden (Backing field) */
+        _forceShowBoundingBoxes: boolean;
+
+        /**
+         * Gets or sets a boolean indicating if all bounding boxes must be rendered
+         */    
+        forceShowBoundingBoxes: boolean;
+
+        /** 
+         * Gets the bounding box renderer associated with the scene
+         * @returns a BoundingBoxRenderer
+         */
+        getBoundingBoxRenderer(): BoundingBoxRenderer;
+    }
+
+    Object.defineProperty(Scene.prototype, "forceShowBoundingBoxes", {
+        get: function (this:Scene) {
+            return this._forceShowBoundingBoxes || false;
+        },
+        set: function (this:Scene, value: boolean) {
+            this._forceShowBoundingBoxes = value;
+            // Lazyly creates a BB renderer if needed.
+            if (value) {
+                this.getBoundingBoxRenderer();
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+
+    Scene.prototype.getBoundingBoxRenderer = function(): BoundingBoxRenderer {
+
+        if (!this._boundingBoxRenderer) {
+            this._boundingBoxRenderer = new BoundingBoxRenderer(this);
+        }
+
+        return this._boundingBoxRenderer;
+    }
+
+    export class BoundingBoxRenderer implements ISceneComponent {
+        /**
+         * The component name helpfull to identify the component in the list of scene components.
+         */
+        public readonly name = SceneComponentConstants.NAME_BOUNDINGBOXRENDERER;
+
+        /**
+         * The scene the component belongs to.
+         */
+        public scene: Scene;
+
         public frontColor = new Color3(1, 1, 1);
         public backColor = new Color3(0.1, 0.1, 0.1);
         public showBackLines = true;
         public renderList = new SmartArray<BoundingBox>(32);
 
-        private _scene: Scene;
         private _colorShader: ShaderMaterial;
         private _vertexBuffers: { [key: string]: Nullable<VertexBuffer> } = {};
         private _indexBuffer: WebGLBuffer;
 
         constructor(scene: Scene) {
-            this._scene = scene;
+            this.scene = scene;
+            scene._addComponent(this);
+        }
+
+        /**
+         * Registers the component in a given scene
+         */
+        public register(): void {
+            this.scene._beforeEvaluateActiveMeshStage.registerStep(SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER, this, this.reset);
+
+            this.scene._activeMeshStage.registerStep(SceneComponentConstants.STEP_ACTIVEMESH_BOUNDINGBOXRENDERER, this, this._activeMesh);
+
+            this.scene._evaluateSubMeshStage.registerStep(SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER, this, this._evaluateSubMesh);
+
+            this.scene._afterCameraDrawStage.registerStep(SceneComponentConstants.STEP_AFTERCAMERADRAW_BOUNDINGBOXRENDERER, this, this.render);
+        }
+
+        private _evaluateSubMesh(mesh: AbstractMesh, subMesh: SubMesh): void {
+            if (mesh.showSubMeshesBoundingBox) {
+                const boundingInfo = subMesh.getBoundingInfo();
+                if (boundingInfo !== null && boundingInfo !== undefined) {
+                    this.renderList.push(boundingInfo.boundingBox);
+                }
+            }
+        }
+
+        private _activeMesh(sourceMesh: AbstractMesh, mesh: AbstractMesh): void {
+            if (sourceMesh.showBoundingBox || this.scene.forceShowBoundingBoxes) {
+                let boundingInfo = sourceMesh.getBoundingInfo();
+
+                this.renderList.push(boundingInfo.boundingBox);
+            }
         }
 
         private _prepareRessources(): void {
@@ -19,25 +102,29 @@
                 return;
             }
 
-            this._colorShader = new ShaderMaterial("colorShader", this._scene, "color",
+            this._colorShader = new ShaderMaterial("colorShader", this.scene, "color",
                 {
                     attributes: [VertexBuffer.PositionKind],
                     uniforms: ["world", "viewProjection", "color"]
                 });
 
 
-            var engine = this._scene.getEngine();
+            var engine = this.scene.getEngine();
             var boxdata = VertexData.CreateBox({ size: 1.0 });
             this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, <FloatArray>boxdata.positions, VertexBuffer.PositionKind, false);
             this._createIndexBuffer();
         }
 
         private _createIndexBuffer(): void {
-            var engine = this._scene.getEngine();
+            var engine = this.scene.getEngine();
             this._indexBuffer = engine.createIndexBuffer([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 7, 1, 6, 2, 5, 3, 4]);
         }
 
-        public _rebuild(): void {
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        public rebuild(): void {
             let vb = this._vertexBuffers[VertexBuffer.PositionKind];
             if (vb) {
                 vb._rebuild();
@@ -60,7 +147,7 @@
                 return;
             }
 
-            var engine = this._scene.getEngine();
+            var engine = this.scene.getEngine();
             engine.setDepthWrite(false);
             this._colorShader._preBind();
             for (var boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {
@@ -80,7 +167,7 @@
                 if (this.showBackLines) {
                     // Back
                     engine.setDepthFunctionToGreaterOrEqual();
-                    this._scene.resetCachedMaterial();
+                    this.scene.resetCachedMaterial();
                     this._colorShader.setColor4("color", this.backColor.toColor4());
                     this._colorShader.bind(worldMatrix);
 
@@ -90,7 +177,7 @@
 
                 // Front
                 engine.setDepthFunctionToLess();
-                this._scene.resetCachedMaterial();
+                this.scene.resetCachedMaterial();
                 this._colorShader.setColor4("color", this.frontColor.toColor4());
                 this._colorShader.bind(worldMatrix);
 
@@ -110,7 +197,7 @@
                 return;
             }
 
-            var engine = this._scene.getEngine();
+            var engine = this.scene.getEngine();
             engine.setDepthWrite(false);
             engine.setColorWrite(false);
             this._colorShader._preBind();
@@ -128,7 +215,7 @@
             engine.bindBuffers(this._vertexBuffers, this._indexBuffer, <Effect>this._colorShader.getEffect());
 
             engine.setDepthFunctionToLess();
-            this._scene.resetCachedMaterial();
+            this.scene.resetCachedMaterial();
             this._colorShader.bind(worldMatrix);
 
             engine.drawElementsType(Material.LineListDrawMode, 0, 24);
@@ -153,7 +240,7 @@
                 buffer.dispose();
                 this._vertexBuffers[VertexBuffer.PositionKind] = null;
             }
-            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
+            this.scene.getEngine()._releaseBuffer(this._indexBuffer);
         }
     }
 } 

+ 1 - 1
src/Tools/babylon.sceneSerializer.ts

@@ -300,7 +300,7 @@
             }
 
             // Components
-            for (let component of scene._components) {
+            for (let component of scene._serializableComponents) {
                 component.serialize(serializationObject);
             }
 

+ 2 - 2
src/babylon.assetContainer.ts

@@ -74,7 +74,7 @@ module BABYLON {
                 this.scene.addTexture(o);
             });
 
-            for (let component of this.scene._components) {
+            for (let component of this.scene._serializableComponents) {
                 component.addFromContainer(this.scene);
             }
         }
@@ -131,7 +131,7 @@ module BABYLON {
                 this.scene.removeTexture(o);
             });
 
-            for (let component of this.scene._components) {
+            for (let component of this.scene._serializableComponents) {
                 component.removeFromContainer(this.scene);
             }
         }

+ 31 - 43
src/babylon.scene.ts

@@ -243,11 +243,6 @@
         }
 
         /**
-         * Gets or sets a boolean indicating if all bounding boxes must be rendered
-         */    
-        public forceShowBoundingBoxes = false;
-
-        /**
          * Gets or sets the active clipplane
          */
         public clipPlane: Nullable<Plane>;
@@ -1080,8 +1075,6 @@
         private _alternateSceneUbo: UniformBuffer;
 
         private _pickWithRayInverseMatrix: Matrix;
-
-        private _boundingBoxRenderer: BoundingBoxRenderer;
         private _outlineRenderer: OutlineRenderer;
 
         private _viewMatrix: Matrix;
@@ -1150,6 +1143,11 @@
         public _components: ISceneComponent[] = [];
 
         /**
+         * Backing store of defined scene components.
+         */
+        public _serializableComponents: ISceneSerializableComponent[] = [];
+
+        /**
          * List of components to register on the next registration step.
          */
         private _transientComponents: ISceneComponent[] = [];
@@ -1176,6 +1174,11 @@
         public _addComponent(component: ISceneComponent) {
             this._components.push(component);
             this._transientComponents.push(component);
+
+            const serializableComponent = component as ISceneSerializableComponent;
+            if (serializableComponent.addFromContainer) {
+                this._serializableComponents.push(serializableComponent);
+            }
         }
 
         /**
@@ -1197,6 +1200,18 @@
          */
         public _isReadyForMeshStage = Stage.Create<MeshStageAction>();
         /**
+         * Defines the actions happening before evaluate active mesh checks.
+         */
+        public _beforeEvaluateActiveMeshStage = Stage.Create<SimpleStageAction>();
+        /**
+         * Defines the actions happening during the evaluate sub mesh checks.
+         */
+        public _evaluateSubMeshStage = Stage.Create<EvaluateSubMeshStageAction>();
+        /**
+         * Defines the actions happening during the active mesh stage.
+         */
+        public _activeMeshStage = Stage.Create<ActiveMeshStageAction>();
+        /**
          * Defines the actions happening during the per camera render target step.
          */
         public _cameraDrawRenderTargetStage = Stage.Create<CameraStageAction>();
@@ -1360,18 +1375,6 @@
         }
 
         /** 
-         * Gets the bounding box renderer associated with the scene
-         * @returns a BoundingBoxRenderer
-         */
-        public getBoundingBoxRenderer(): BoundingBoxRenderer {
-            if (!this._boundingBoxRenderer) {
-                this._boundingBoxRenderer = new BoundingBoxRenderer(this);
-            }
-
-            return this._boundingBoxRenderer;
-        }
-
-        /** 
          * Gets the outline renderer associated with the scene
          * @returns a OutlineRenderer
          */        
@@ -4049,11 +4052,8 @@
 
         private _evaluateSubMesh(subMesh: SubMesh, mesh: AbstractMesh): void {
             if (this.dispatchAllSubMeshesOfActiveMeshes || mesh.alwaysSelectAsActiveMesh || mesh.subMeshes.length === 1 || subMesh.isInFrustum(this._frustumPlanes)) {
-                if (mesh.showSubMeshesBoundingBox) {
-                    const boundingInfo = subMesh.getBoundingInfo();
-                    if (boundingInfo !== null && boundingInfo !== undefined) {
-                        this.getBoundingBoxRenderer().renderList.push(boundingInfo.boundingBox);
-                    }
+                for (let step of this._evaluateSubMeshStage) {
+                    step.action(mesh, subMesh);
                 }
 
                 const material = subMesh.getMaterial();
@@ -4184,8 +4184,8 @@
             this._activeParticleSystems.reset();
             this._activeSkeletons.reset();
             this._softwareSkinnedMeshes.reset();
-            if (this._boundingBoxRenderer) {
-                this._boundingBoxRenderer.reset();
+            for (let step of this._beforeEvaluateActiveMeshStage) {
+                step.action();
             }
 
             // Meshes
@@ -4291,10 +4291,8 @@
                 }
             }
 
-            if (sourceMesh.showBoundingBox || this.forceShowBoundingBoxes) {
-                let boundingInfo = sourceMesh.getBoundingInfo();
-
-                this.getBoundingBoxRenderer().renderList.push(boundingInfo.boundingBox);
+            for (let step of this._activeMeshStage) {
+                step.action(sourceMesh, mesh);
             }
 
             if (
@@ -4438,11 +4436,6 @@
             for (let step of this._afterCameraDrawStage) {
                 step.action(this.activeCamera);
             }
-
-            // Bounding boxes
-            if (this._boundingBoxRenderer) {
-                this._boundingBoxRenderer.render();
-            }
             
             // Finalize frame
             if (this.postProcessManager) {
@@ -5008,6 +5001,9 @@
             this.morphTargetManagers = [];
             this._transientComponents = [];
             this._isReadyForMeshStage.clear();
+            this._beforeEvaluateActiveMeshStage.clear();
+            this._evaluateSubMeshStage.clear();
+            this._activeMeshStage.clear();
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
@@ -5045,10 +5041,6 @@
             this._softwareSkinnedMeshes.dispose();
             this._renderTargets.dispose();
             this._registeredForLateAnimationBindings.dispose();
-
-            if (this._boundingBoxRenderer) {
-                this._boundingBoxRenderer.dispose();
-            }
             this._meshesForIntersections.dispose();
             this._toBeDisposed.dispose();
 
@@ -5748,10 +5740,6 @@
                 component.rebuild();
             }
 
-            if (this._boundingBoxRenderer) {
-                this._boundingBoxRenderer._rebuild();
-            }
-
             for (var system of this.particleSystems) {
                 system.rebuild();
             }

+ 38 - 14
src/babylon.sceneComponent.ts

@@ -7,9 +7,16 @@
         public static readonly NAME_EFFECTLAYER = "EffectLayer";
         public static readonly NAME_LAYER = "Layer";
         public static readonly NAME_LENSFLARESYSTEM = "LensFlareSystem";
+        public static readonly NAME_BOUNDINGBOXRENDERER = "BoundingBoxRenderer";
 
         public static readonly STEP_ISREADYFORMESH_EFFECTLAYER = 0;
 
+        public static readonly STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER = 0;
+
+        public static readonly STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER = 0;
+
+        public static readonly STEP_ACTIVEMESH_BOUNDINGBOXRENDERER = 0;
+
         public static readonly STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         
         public static readonly STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
@@ -19,9 +26,9 @@
 
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
-        public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
-        public static readonly STEP_AFTERCAMERADRAW_LAYER = 3;
-
+        public static readonly STEP_AFTERCAMERADRAW_BOUNDINGBOXRENDERER = 2;
+        public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 3;
+        public static readonly STEP_AFTERCAMERADRAW_LAYER = 4;
     }
 
     /**
@@ -47,6 +54,24 @@
         register(): void;
 
         /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        rebuild(): void;
+
+        /**
+         * Disposes the component and the associated ressources.
+         */
+        dispose(): void;
+    }
+
+    /**
+     * This represents a SERIALIZABLE scene component.
+     * 
+     * This extends Scene Component to add Serialization methods on top.
+     */
+    export interface ISceneSerializableComponent extends ISceneComponent {
+        /**
          * Adds all the element from the container to the scene
          * @param container the container holding the elements
          */
@@ -59,21 +84,10 @@
         removeFromContainer(container: AbstractScene): void;
 
         /**
-         * Rebuilds the elements related to this component in case of
-         * context lost for instance.
-         */
-        rebuild(): void;
-
-        /**
          * Serializes the component data to the specified json object
          * @param serializationObject The object to serialize to
          */
         serialize(serializationObject: any): void;
-
-        /**
-         * Disposes the component and the associated ressources.
-         */
-        dispose(): void;
     }
 
     /** 
@@ -82,6 +96,16 @@
     export type MeshStageAction = (mesh: AbstractMesh, hardwareInstancedRendering: boolean) => boolean;
 
     /** 
+     * Strong typing of a Evaluate Sub Mesh related stage step action
+     */
+    export type EvaluateSubMeshStageAction = (mesh: AbstractMesh, subMesh: SubMesh) => void;
+
+    /**
+     * Strong typing of a Active Mesh related stage step action
+     */
+    export type ActiveMeshStageAction =  (sourceMesh: AbstractMesh, mesh: AbstractMesh) => void;
+
+    /** 
      * Strong typing of a Camera related stage step action 
      */
     export type CameraStageAction = (camera: Camera) => void;