Browse Source

Merge pull request #4899 from sebavan/master

Simplification and GeometryBuffer As A SceneComponent
sebavan 7 years ago
parent
commit
c0d26d6447

+ 5 - 2
Tools/Gulp/config.json

@@ -732,7 +732,8 @@
         },
         "geometryBufferRenderer": {
             "files": [
-                "../../src/Rendering/babylon.geometryBufferRenderer.js"
+                "../../src/Rendering/babylon.geometryBufferRenderer.js",
+                "../../src/Rendering/babylon.geometryBufferRendererSceneComponent.js"
             ],
             "dependUpon": [
                 "core"
@@ -988,7 +989,8 @@
             ],
             "dependUpon": [
                 "renderingPipeline",
-                "depthRenderer"
+                "depthRenderer",
+                "geometryBufferRenderer"
             ],
             "shaders": [
                 "ssao.fragment",
@@ -1269,6 +1271,7 @@
         "optimizations": {
             "files": [
                 "../../src/Mesh/babylon.meshSimplification.js",
+                "../../src/Mesh/babylon.meshSimplificationSceneComponent.js",
                 "../../src/Mesh/babylon.meshLODLevel.js",
                 "../../src/Tools/babylon.sceneOptimizer.js"
             ],

+ 37 - 14
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
-  "errors": 4018,
+  "errors": 4023,
   "babylon.typedoc.json": {
-    "errors": 4018,
+    "errors": 4023,
     "AbstractMesh": {
       "Property": {
         "showBoundingBox": {
@@ -7767,18 +7767,6 @@
             }
           }
         },
-        "simplify": {
-          "Comments": {
-            "MissingReturn": true
-          },
-          "Parameter": {
-            "simplificationType": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "subdivide": {
           "Comments": {
             "MissingText": true
@@ -8824,6 +8812,21 @@
               }
             }
           }
+        },
+        "simplify": {
+          "Naming": {
+            "NotPascalCase": true
+          },
+          "Comments": {
+            "MissingReturn": true
+          },
+          "Parameter": {
+            "simplificationType": {
+              "Comments": {
+                "MissingText": true
+              }
+            }
+          }
         }
       }
     },
@@ -14271,9 +14274,29 @@
           "Naming": {
             "NotPascalCase": true
           }
+        },
+        "geometryBufferRenderer": {
+          "Naming": {
+            "NotPascalCase": true
+          }
+        },
+        "simplificationQueue": {
+          "Naming": {
+            "NotPascalCase": true
+          }
         }
       },
       "Method": {
+        "disableGeometryBufferRenderer": {
+          "Naming": {
+            "NotPascalCase": true
+          }
+        },
+        "enableGeometryBufferRenderer": {
+          "Naming": {
+            "NotPascalCase": true
+          }
+        },
         "getBoundingBoxRenderer": {
           "Naming": {
             "NotPascalCase": true

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

@@ -2189,25 +2189,6 @@
         }
 
         /**
-         * Simplify the mesh according to the given array of settings.
-         * Function will return immediately and will simplify async. It returns the Mesh.  
-         * @param settings a collection of simplification settings.
-         * @param parallelProcessing should all levels calculate parallel or one after the other.
-         * @param type the type of simplification to run.
-         * @param successCallback optional success callback to be called after the simplification finished processing all settings.
-         */
-        public simplify(settings: Array<ISimplificationSettings>, parallelProcessing: boolean = true, simplificationType: SimplificationType = SimplificationType.QUADRATIC, successCallback?: (mesh?: Mesh, submeshIndex?: number) => void): Mesh {
-            this.getScene().simplificationQueue.addTask({
-                settings: settings,
-                parallelProcessing: parallelProcessing,
-                mesh: this,
-                simplificationType: simplificationType,
-                successCallback: successCallback
-            });
-            return this;
-        }
-
-        /**
          * Optimization of the mesh's indices, in case a mesh has duplicated vertices.   
          * The function will only reorder the indices and will not remove unused vertices to avoid problems with submeshes.   
          * This should be used together with the simplification to avoid disappearing triangles.  

+ 0 - 2
src/Mesh/babylon.meshSimplification.ts

@@ -1,5 +1,4 @@
 module BABYLON {
-
     /**
      * A simplifier interface for future simplification implementations.
      */
@@ -699,7 +698,6 @@
             }
         }
 
-
         private vertexError(q: QuadraticMatrix, point: Vector3): number {
             var x = point.x;
             var y = point.y;

+ 106 - 0
src/Mesh/babylon.meshSimplificationSceneComponent.ts

@@ -0,0 +1,106 @@
+module BABYLON {
+    export interface Scene {
+        /** @hidden (Backing field) */
+        _simplificationQueue: SimplificationQueue;
+
+        /**
+         * Gets or sets the simplification queue attached to the scene
+         * @see http://doc.babylonjs.com/how_to/in-browser_mesh_simplification
+         */
+        simplificationQueue: SimplificationQueue;
+    }
+
+    Object.defineProperty(Scene.prototype, "simplificationQueue", {
+        get: function (this:Scene) {
+            if (!this._simplificationQueue) {
+                this._simplificationQueue = new SimplificationQueue();
+                let component = this._getComponent(SceneComponentConstants.NAME_SIMPLIFICATIONQUEUE) as SimplicationQueueSceneComponent;
+                if (!component) {
+                    component = new SimplicationQueueSceneComponent(this);
+                    this._addComponent(component);
+                }
+            }
+            return this._simplificationQueue;
+        },
+        set: function (this:Scene, value: SimplificationQueue) {
+            this._simplificationQueue = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+
+    export interface Mesh {
+        /**
+         * Simplify the mesh according to the given array of settings.
+         * Function will return immediately and will simplify async. It returns the Mesh.  
+         * @param settings a collection of simplification settings.
+         * @param parallelProcessing should all levels calculate parallel or one after the other.
+         * @param type the type of simplification to run.
+         * @param successCallback optional success callback to be called after the simplification finished processing all settings.
+         */
+        simplify(settings: Array<ISimplificationSettings>, parallelProcessing?: boolean, simplificationType?: SimplificationType, successCallback?: (mesh?: Mesh, submeshIndex?: number) => void): Mesh;
+    }
+
+    Mesh.prototype.simplify = function(settings: Array<ISimplificationSettings>, parallelProcessing: boolean = true, simplificationType: SimplificationType = SimplificationType.QUADRATIC, successCallback?: (mesh?: Mesh, submeshIndex?: number) => void): Mesh {
+        this.getScene().simplificationQueue.addTask({
+            settings: settings,
+            parallelProcessing: parallelProcessing,
+            mesh: this,
+            simplificationType: simplificationType,
+            successCallback: successCallback
+        });
+        return this;
+    }
+
+    /**
+     * Defines the simplification queue scene component responsible to help scheduling the various simplification task
+     * created in a scene
+     */
+    export class SimplicationQueueSceneComponent implements ISceneComponent {
+        /**
+         * The component name helpfull to identify the component in the list of scene components.
+         */
+        public readonly name = SceneComponentConstants.NAME_SIMPLIFICATIONQUEUE;
+
+        /**
+         * The scene the component belongs to.
+         */
+        public scene: Scene;
+
+        /**
+         * Creates a new instance of the component for the given scene
+         * @param scene Defines the scene to register the component in
+         */
+        constructor(scene: Scene) {
+            this.scene = scene;
+        }
+
+        /**
+         * Registers the component in a given scene
+         */
+        public register(): void {
+            this.scene._beforeCameraUpdateStage.registerStep(SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE, this, this._beforeCameraUpdate);
+        }
+
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        public rebuild(): void {
+            // Nothing to do for this component
+        }
+
+        /**
+         * Disposes the component and the associated ressources
+         */
+        public dispose(): void {
+            // Nothing to do for this component
+        }
+
+        private _beforeCameraUpdate(): void {
+            if (this.scene._simplificationQueue && !this.scene._simplificationQueue.running) {
+                this.scene._simplificationQueue.executeNext();
+            }
+        }
+    }
+} 

+ 7 - 0
src/Rendering/babylon.geometryBufferRenderer.ts

@@ -67,6 +67,13 @@ module BABYLON {
             this._scene = scene;
             this._ratio = ratio;
 
+            // Register the G Buffer component to the scene.
+            let component = scene._getComponent(SceneComponentConstants.NAME_GEOMETRYBUFFERRENDERER) as GeometryBufferRendererSceneComponent;
+            if (!component) {
+                component = new GeometryBufferRendererSceneComponent(scene);
+                scene._addComponent(component);
+            }
+
             // Render target
             this._createRenderTargets();
         }

+ 110 - 0
src/Rendering/babylon.geometryBufferRendererSceneComponent.ts

@@ -0,0 +1,110 @@
+module BABYLON {
+    export interface Scene {
+        /** @hidden (Backing field) */
+        _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
+
+        /**
+         * Gets or Sets the current geometry buffer associated to the scene.
+         */
+        geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
+
+        /**
+         * Enables a GeometryBufferRender and associates it with the scene
+         * @param ratio defines the scaling ratio to apply to the renderer (1 by default which means same resolution)
+         * @returns the GeometryBufferRenderer
+         */
+        enableGeometryBufferRenderer(ratio?: number): Nullable<GeometryBufferRenderer>;
+
+        /**
+         * Disables the GeometryBufferRender associated with the scene
+         */
+        disableGeometryBufferRenderer(): void;
+    }
+
+    Object.defineProperty(Scene.prototype, "geometryBufferRenderer", {
+        get: function (this:Scene) {
+            this._geometryBufferRenderer;
+        },
+        set: function (this:Scene, value: Nullable<GeometryBufferRenderer>) {
+            if (value && value.isSupported) {
+                this._geometryBufferRenderer = value;
+            };
+        },
+        enumerable: true,
+        configurable: true
+    });
+
+    Scene.prototype.enableGeometryBufferRenderer = function(ratio: number = 1): Nullable<GeometryBufferRenderer> {
+        if (this._geometryBufferRenderer) {
+            return this._geometryBufferRenderer;
+        }
+
+        this._geometryBufferRenderer = new GeometryBufferRenderer(this, ratio);
+        if (!this._geometryBufferRenderer.isSupported) {
+            this._geometryBufferRenderer = null;
+        }
+
+        return this._geometryBufferRenderer;
+    }
+
+    Scene.prototype.disableGeometryBufferRenderer = function(): void {
+        if (!this._geometryBufferRenderer) {
+            return;
+        }
+
+        this._geometryBufferRenderer.dispose();
+        this._geometryBufferRenderer = null;
+    }
+
+    /**
+     * Defines the Geometry Buffer scene component responsible to manage a G-Buffer usefull
+     * in several rendering techniques.
+     */
+    export class GeometryBufferRendererSceneComponent implements ISceneComponent {
+        /**
+         * The component name helpfull to identify the component in the list of scene components.
+         */
+        public readonly name = SceneComponentConstants.NAME_GEOMETRYBUFFERRENDERER;
+
+        /**
+         * The scene the component belongs to.
+         */
+        public scene: Scene;
+
+        /**
+         * Creates a new instance of the component for the given scene
+         * @param scene Defines the scene to register the component in
+         */
+        constructor(scene: Scene) {
+            this.scene = scene;
+        }
+
+        /**
+         * Registers the component in a given scene
+         */
+        public register(): void {
+            this.scene._gatherRenderTargetsStage.registerStep(SceneComponentConstants.STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER, this, this._gatherRenderTargets);
+        }
+
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        public rebuild(): void {
+            // Nothing to do for this component
+        }
+
+        /**
+         * Disposes the component and the associated ressources
+         */
+        public dispose(): void {
+            // Nothing to do for this component
+        }
+
+        private _gatherRenderTargets(renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>): void {
+            if (this.scene._geometryBufferRenderer) {
+                renderTargets.push(this.scene._geometryBufferRenderer.getGBuffer());
+            }
+        }
+    }
+} 

+ 11 - 67
src/babylon.scene.ts

@@ -966,12 +966,6 @@
          */
         public VRHelper: VRExperienceHelper;
 
-        /**
-         * Gets or sets the simplification queue attached to the scene
-         * @see http://doc.babylonjs.com/how_to/in-browser_mesh_simplification
-         */
-        public simplificationQueue: SimplificationQueue;
-
         // Private
         private _engine: Engine;
 
@@ -1079,22 +1073,6 @@
         private _debugLayer: DebugLayer;
 
         private _depthRenderer: { [id: string]: DepthRenderer } = {};
-        private _geometryBufferRenderer: Nullable<GeometryBufferRenderer>;
-
-        /**
-         * Gets the current geometry buffer associated to the scene.
-         */
-        public get geometryBufferRenderer(): Nullable<GeometryBufferRenderer> {
-            return this._geometryBufferRenderer;
-        }
-        /**
-         * Sets the current geometry buffer for the scene.
-         */
-        public set geometryBufferRenderer(geometryBufferRenderer: Nullable<GeometryBufferRenderer>) {
-            if (geometryBufferRenderer && geometryBufferRenderer.isSupported) {
-                this._geometryBufferRenderer = geometryBufferRenderer;
-            }
-        }
 
         private _pickedDownMesh: Nullable<AbstractMesh>;
         private _pickedUpMesh: Nullable<AbstractMesh>;
@@ -1172,6 +1150,11 @@
         public _beforeCameraUpdateStage = Stage.Create<SimpleStageAction>();
         /**
          * @hidden
+         * Defines the actions happening before camera updates.
+         */
+        public _gatherRenderTargetsStage = Stage.Create<RenderTargetsStageAction>();
+        /**
+         * @hidden
          * Defines the actions happening during the per mesh ready checks.
          */
         public _isReadyForMeshStage = Stage.Create<MeshStageAction>();
@@ -1240,11 +1223,6 @@
                 this.attachControl();
             }
 
-            //simplification queue
-            if (SimplificationQueue) {
-                this.simplificationQueue = new SimplificationQueue();
-            }
-
             //collision coordinator initialization. For now legacy per default.
             this.workerCollisions = false;//(!!Worker && (!!BABYLON.CollisionWorker || BABYLON.WorkerIncluded));
 
@@ -4525,11 +4503,6 @@
                 this.actionManager.processTrigger(ActionManager.OnEveryFrameTrigger);
             }
 
-            //Simplification Queue
-            if (this.simplificationQueue && !this.simplificationQueue.running) {
-                this.simplificationQueue.executeNext();
-            }
-
             if (this._engine.isDeterministicLockStep()) {
                 var deltaTime = Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime)) + this._timeAccumulator;
 
@@ -4691,16 +4664,16 @@
                 }
             }
 
+            // Collects render targets from external components.
+            for (let step of this._gatherRenderTargetsStage) {
+                step.action(this._renderTargets);
+            }
+
             // Depth renderer
             for (var key in this._depthRenderer) {
                 this._renderTargets.push(this._depthRenderer[key].getDepthMap());
             }
 
-            // Geometry renderer
-            if (this._geometryBufferRenderer) {
-                this._renderTargets.push(this._geometryBufferRenderer.getGBuffer());
-            }
-
             // RenderPipeline
             if (this._postProcessRenderPipelineManager) {
                 this._postProcessRenderPipelineManager.update();
@@ -4928,36 +4901,6 @@
             delete this._depthRenderer[camera.id];
         }
 
-        /**
-         * Enables a GeometryBufferRender and associates it with the scene
-         * @param ratio defines the scaling ratio to apply to the renderer (1 by default which means same resolution)
-         * @returns the GeometryBufferRenderer
-         */
-        public enableGeometryBufferRenderer(ratio: number = 1): Nullable<GeometryBufferRenderer> {
-            if (this._geometryBufferRenderer) {
-                return this._geometryBufferRenderer;
-            }
-
-            this._geometryBufferRenderer = new GeometryBufferRenderer(this, ratio);
-            if (!this._geometryBufferRenderer.isSupported) {
-                this._geometryBufferRenderer = null;
-            }
-
-            return this._geometryBufferRenderer;
-        }
-
-        /**
-         * Disables the GeometryBufferRender associated with the scene
-         */
-        public disableGeometryBufferRenderer(): void {
-            if (!this._geometryBufferRenderer) {
-                return;
-            }
-
-            this._geometryBufferRenderer.dispose();
-            this._geometryBufferRenderer = null;
-        }
-
         /** 
          * Freeze all materials
          * A frozen material will not be updatable but should be faster to render
@@ -4998,6 +4941,7 @@
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
             this._beforeCameraUpdateStage.clear();
+            this._gatherRenderTargetsStage.clear();
             for (let component of this._components) {
                 component.dispose();
             }

+ 11 - 1
src/babylon.sceneComponent.ts

@@ -10,6 +10,8 @@
         public static readonly NAME_BOUNDINGBOXRENDERER = "BoundingBoxRenderer";
         public static readonly NAME_PARTICLESYSTEM = "ParticleSystem";
         public static readonly NAME_GAMEPAD = "Gamepad";
+        public static readonly NAME_SIMPLIFICATIONQUEUE = "SimplificationQueue";
+        public static readonly NAME_GEOMETRYBUFFERRENDERER = "GeometryBufferRenderer";
 
         public static readonly STEP_ISREADYFORMESH_EFFECTLAYER = 0;
 
@@ -26,13 +28,16 @@
 
         public static readonly STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
 
-        public static readonly STEP_BEFORECAMERAUPDATE_GAMEPAD = 0;
+        public static readonly STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
+        public static readonly STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
 
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
         public static readonly STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
         public static readonly STEP_AFTERCAMERADRAW_BOUNDINGBOXRENDERER = 2;
         public static readonly STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 3;
         public static readonly STEP_AFTERCAMERADRAW_LAYER = 4;
+
+        public static readonly STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER = 0;
     }
 
     /**
@@ -125,6 +130,11 @@
     export type SimpleStageAction = () => void;
 
     /** 
+     * Strong typing of a render target action.
+     */
+    export type RenderTargetsStageAction = (renderTargets: SmartArrayNoDuplicate<RenderTargetTexture>) => void;
+
+    /** 
      * Repressentation of a stage in the scene (Basically a list of ordered steps) 
      * @hidden
      */

BIN
tests/validation/ReferenceImages/meshSimplification.png


BIN
tests/validation/ReferenceImages/ssao2.png


+ 12 - 0
tests/validation/config.json

@@ -517,6 +517,18 @@
       "title": "LightFalloff",
       "playgroundId": "#20OAV9#201",
       "referenceImage": "lightFalloff.png"
+    },
+    {
+      "title": "MeshSimplification",
+      "playgroundId": "#1ED15P#35",
+      "referenceImage": "meshSimplification.png"
+    },
+    {
+      "title": "SSAO2",
+      "playgroundId": "#XT1HAS#1",
+      "referenceImage": "ssao2.png",
+      "renderCount": 200,
+      "excludeFromAutomaticTesting": true
     }
   ]
 }