Przeglądaj źródła

Adding OcclusionBoundingBoxRenderer

DESKTOP-QJU4N0L\mityh 8 lat temu
rodzic
commit
dfdacbbc6a

Plik diff jest za duży
+ 2814 - 2806
dist/preview release/babylon.d.ts


Plik diff jest za duży
+ 31 - 31
dist/preview release/babylon.js


+ 52 - 25
dist/preview release/babylon.max.js

@@ -11782,6 +11782,7 @@ var BABYLON;
             _this._gl = _this.getEngine()._gl;
             _this.occlusionType = AbstractMesh.OCCLUSION_TYPE_NO_VALUE;
             _this.occlusionRetryCount = -1;
+            _this.isOccluded = false;
             _this.occlusionQuery = _this._gl.createQuery();
             _this.isOcclusionQueryInProgress = false;
             _this._rotation = BABYLON.Vector3.Zero();
@@ -20492,6 +20493,9 @@ var BABYLON;
             _this._areNormalsFrozen = false; // Will be used by ribbons mainly
             // Will be used to save a source mesh reference, If any
             _this._source = null;
+            _this._vertexBuffers = {};
+            _this.frontColor = new BABYLON.Color3(1, 1, 1);
+            _this.backColor = new BABYLON.Color3(0.1, 0.1, 0.1);
             if (source) {
                 // Source mesh
                 _this._source = source;
@@ -21452,31 +21456,63 @@ var BABYLON;
             }
             return this;
         };
-        /**
-         * Triggers the draw call for the mesh.
-         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.
-         * Returns the Mesh.
-         */
-        Mesh.prototype.render = function (subMesh, enableAlphaMode) {
-            // check occlusion query in progress
-            if (this.occlusionType !== BABYLON.AbstractMesh.OCCLUSION_TYPE_NO_VALUE && this.isOcclusionQueryInProgress) {
+        Mesh.prototype._prepareRessources = function () {
+            if (this._caaaaolorasaShader) {
+                return;
+            }
+            var scene = this.getScene();
+            this._caaaaolorasaShader = new BABYLON.ShaderMaterial("caaaaolorasaShader", scene, "color", {
+                attributes: ["aaaa"],
+                uniforms: ["world", "viewProjection", "color"]
+            });
+            var engine = scene.getEngine();
+            var boxdata = BABYLON.VertexData.CreateBox({ size: 1.0 });
+            this._vertexBuffers["aaaa"] = new BABYLON.VertexBuffer(engine, boxdata.positions, "aaaa", false);
+            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]);
+        };
+        Mesh.prototype.renderOcclusionBoundingMesh = function () {
+            if (this.isOcclusionQueryInProgress) {
                 console.log("Enter occlusion check");
                 var isOcclusionQueryAvailable = this._gl.getQueryParameter(this.occlusionQuery, this._gl.QUERY_RESULT_AVAILABLE);
-                console.log("isOcclusionQueryAvailable" + isOcclusionQueryAvailable);
+                console.log("isOcclusionQueryAvailable " + isOcclusionQueryAvailable);
                 if (isOcclusionQueryAvailable) {
                     var occlusionQueryResult = this._gl.getQueryParameter(this.occlusionQuery, this._gl.QUERY_RESULT);
-                    console.log("occlusionQueryResult" + occlusionQueryResult);
+                    console.log("occlusionQueryResult " + occlusionQueryResult);
+                    this.isOccluded = true;
                     this.isOcclusionQueryInProgress = false;
                     if (occlusionQueryResult === 1) {
-                        // draw
-                    }
-                    else {
-                        return this;
+                        this.isOccluded = false;
+                        return true;
                     }
                 }
                 else {
-                    return this;
+                    return false;
+                }
+            }
+            var scene = this.getScene();
+            console.log("Enter Draw Bound");
+            this._gl.beginQuery(this._gl.ANY_SAMPLES_PASSED, this.occlusionQuery);
+            var _boundingBoxRenderer = new BABYLON.BoundingBoxRenderer(scene);
+            _boundingBoxRenderer.showBackLines = false;
+            _boundingBoxRenderer.renderList.push(this._boundingInfo.boundingBox);
+            _boundingBoxRenderer.render();
+            this._gl.endQuery(this._gl.ANY_SAMPLES_PASSED);
+            this.isOcclusionQueryInProgress = true;
+            return false;
+        };
+        /**
+         * Triggers the draw call for the mesh.
+         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.
+         * Returns the Mesh.
+         */
+        Mesh.prototype.render = function (subMesh, enableAlphaMode) {
+            // check occlusion query in progress
+            if (this.occlusionType !== BABYLON.AbstractMesh.OCCLUSION_TYPE_NO_VALUE) {
+                var isRenderMesh = this.renderOcclusionBoundingMesh();
+                if (!isRenderMesh) {
+                    return;
                 }
+                console.log("Enter Draw Mesh");
             }
             var scene = this.getScene();
             // Managing instances
@@ -21535,16 +21571,7 @@ var BABYLON;
                 effectiveMaterial.bind(world, this);
             }
             // Draw
-            if (this.occlusionType !== BABYLON.AbstractMesh.OCCLUSION_TYPE_NO_VALUE) {
-                console.log("Enter Draw");
-                this._gl.beginQuery(this._gl.ANY_SAMPLES_PASSED, this.occlusionQuery);
-                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
-                this._gl.endQuery(this._gl.ANY_SAMPLES_PASSED);
-                this.isOcclusionQueryInProgress = true;
-            }
-            else {
-                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
-            }
+            this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
             // Unbind
             effectiveMaterial.unbind();
             // Outline - step 2

Plik diff jest za duży
+ 2814 - 2806
dist/preview release/babylon.module.d.ts


Plik diff jest za duży
+ 40 - 40
dist/preview release/babylon.worker.js


Plik diff jest za duży
+ 4034 - 4026
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Plik diff jest za duży
+ 17 - 17
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 52 - 25
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -11782,6 +11782,7 @@ var BABYLON;
             _this._gl = _this.getEngine()._gl;
             _this.occlusionType = AbstractMesh.OCCLUSION_TYPE_NO_VALUE;
             _this.occlusionRetryCount = -1;
+            _this.isOccluded = false;
             _this.occlusionQuery = _this._gl.createQuery();
             _this.isOcclusionQueryInProgress = false;
             _this._rotation = BABYLON.Vector3.Zero();
@@ -20492,6 +20493,9 @@ var BABYLON;
             _this._areNormalsFrozen = false; // Will be used by ribbons mainly
             // Will be used to save a source mesh reference, If any
             _this._source = null;
+            _this._vertexBuffers = {};
+            _this.frontColor = new BABYLON.Color3(1, 1, 1);
+            _this.backColor = new BABYLON.Color3(0.1, 0.1, 0.1);
             if (source) {
                 // Source mesh
                 _this._source = source;
@@ -21452,33 +21456,65 @@ var BABYLON;
             }
             return this;
         };
-        /**
-         * Triggers the draw call for the mesh.
-         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.
-         * Returns the Mesh.
-         */
-        Mesh.prototype.render = function (subMesh, enableAlphaMode) {
-            // check occlusion query in progress
-            if (this.occlusionType !== BABYLON.AbstractMesh.OCCLUSION_TYPE_NO_VALUE && this.isOcclusionQueryInProgress) {
+        Mesh.prototype._prepareRessources = function () {
+            if (this._caaaaolorasaShader) {
+                return;
+            }
+            var scene = this.getScene();
+            this._caaaaolorasaShader = new BABYLON.ShaderMaterial("caaaaolorasaShader", scene, "color", {
+                attributes: ["aaaa"],
+                uniforms: ["world", "viewProjection", "color"]
+            });
+            var engine = scene.getEngine();
+            var boxdata = BABYLON.VertexData.CreateBox({ size: 1.0 });
+            this._vertexBuffers["aaaa"] = new BABYLON.VertexBuffer(engine, boxdata.positions, "aaaa", false);
+            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]);
+        };
+        Mesh.prototype.renderOcclusionBoundingMesh = function () {
+            if (this.isOcclusionQueryInProgress) {
                 console.log("Enter occlusion check");
                 var isOcclusionQueryAvailable = this._gl.getQueryParameter(this.occlusionQuery, this._gl.QUERY_RESULT_AVAILABLE);
-                console.log("isOcclusionQueryAvailable" + isOcclusionQueryAvailable);
+                console.log("isOcclusionQueryAvailable " + isOcclusionQueryAvailable);
                 if (isOcclusionQueryAvailable) {
                     var occlusionQueryResult = this._gl.getQueryParameter(this.occlusionQuery, this._gl.QUERY_RESULT);
-                    console.log("occlusionQueryResult" + occlusionQueryResult);
+                    console.log("occlusionQueryResult " + occlusionQueryResult);
+                    this.isOccluded = true;
                     this.isOcclusionQueryInProgress = false;
                     if (occlusionQueryResult === 1) {
-                        // draw
-                    }
-                    else {
-                        return this;
+                        this.isOccluded = false;
+                        return true;
                     }
                 }
                 else {
-                    return this;
+                    return false;
                 }
             }
             var scene = this.getScene();
+            console.log("Enter Draw Bound");
+            this._gl.beginQuery(this._gl.ANY_SAMPLES_PASSED, this.occlusionQuery);
+            var _boundingBoxRenderer = new BABYLON.BoundingBoxRenderer(scene);
+            _boundingBoxRenderer.showBackLines = false;
+            _boundingBoxRenderer.renderList.push(this._boundingInfo.boundingBox);
+            _boundingBoxRenderer.render();
+            this._gl.endQuery(this._gl.ANY_SAMPLES_PASSED);
+            this.isOcclusionQueryInProgress = true;
+            return false;
+        };
+        /**
+         * Triggers the draw call for the mesh.
+         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.
+         * Returns the Mesh.
+         */
+        Mesh.prototype.render = function (subMesh, enableAlphaMode) {
+            // check occlusion query in progress
+            if (this.occlusionType !== BABYLON.AbstractMesh.OCCLUSION_TYPE_NO_VALUE) {
+                var isRenderMesh = this.renderOcclusionBoundingMesh();
+                if (!isRenderMesh) {
+                    return;
+                }
+                console.log("Enter Draw Mesh");
+            }
+            var scene = this.getScene();
             // Managing instances
             var batch = this._getInstancesRenderList(subMesh._id);
             if (batch.mustReturn) {
@@ -21535,16 +21571,7 @@ var BABYLON;
                 effectiveMaterial.bind(world, this);
             }
             // Draw
-            if (this.occlusionType !== BABYLON.AbstractMesh.OCCLUSION_TYPE_NO_VALUE) {
-                console.log("Enter Draw");
-                this._gl.beginQuery(this._gl.ANY_SAMPLES_PASSED, this.occlusionQuery);
-                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
-                this._gl.endQuery(this._gl.ANY_SAMPLES_PASSED);
-                this.isOcclusionQueryInProgress = true;
-            }
-            else {
-                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
-            }
+            this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
             // Unbind
             effectiveMaterial.unbind();
             // Outline - step 2

Plik diff jest za duży
+ 4034 - 4026
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


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

@@ -128,6 +128,7 @@
         protected _gl = this.getEngine()._gl;
         public occlusionType = AbstractMesh.OCCLUSION_TYPE_NO_VALUE;
         public occlusionRetryCount = -1;
+        public isOccluded = false;
         public occlusionQuery = this._gl.createQuery();
         public isOcclusionQueryInProgress = false;
         private _rotation = Vector3.Zero();

+ 45 - 26
src/Mesh/babylon.mesh.ts

@@ -1101,33 +1101,61 @@
             return this;
         }
 
-        /**
-         * Triggers the draw call for the mesh.
-         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.   
-         * Returns the Mesh.   
-         */
-        public render(subMesh: SubMesh, enableAlphaMode: boolean): Mesh {
-            
-            // check occlusion query in progress
-            if (this.occlusionType !== AbstractMesh.OCCLUSION_TYPE_NO_VALUE && this.isOcclusionQueryInProgress) {
+        private renderOcclusionBoundingMesh() {
+
+
+            if (this.isOcclusionQueryInProgress) {
+
                 console.log("Enter occlusion check");
                 var isOcclusionQueryAvailable = this._gl.getQueryParameter(this.occlusionQuery, this._gl.QUERY_RESULT_AVAILABLE) as boolean;
-                console.log("isOcclusionQueryAvailable" + isOcclusionQueryAvailable);
+                console.log("isOcclusionQueryAvailable " + isOcclusionQueryAvailable);
                 if (isOcclusionQueryAvailable) {
                     var occlusionQueryResult = this._gl.getQueryParameter(this.occlusionQuery, this._gl.QUERY_RESULT) as number;
-                    console.log("occlusionQueryResult" + occlusionQueryResult);
+                    console.log("occlusionQueryResult " + occlusionQueryResult);
 
+                    this.isOccluded = true;
                     this.isOcclusionQueryInProgress = false;
                     if (occlusionQueryResult === 1) {
-                        // draw
-                    }
-                    else {
-                        return this;
+                        this.isOccluded = false;
+                        return true;
                     }
                 }
                 else {
-                    return this;
+                    return false;
+                }
+            }
+
+
+            var scene = this.getScene();
+
+            console.log("Enter Draw Bound");
+            this._gl.beginQuery(this._gl.ANY_SAMPLES_PASSED, this.occlusionQuery);
+            var _boundingBoxRenderer = new BoundingBoxRenderer(scene);
+            _boundingBoxRenderer.showBackLines=false;
+            _boundingBoxRenderer.renderList.push(this._boundingInfo.boundingBox);
+            _boundingBoxRenderer.render();
+            this._gl.endQuery(this._gl.ANY_SAMPLES_PASSED);
+            this.isOcclusionQueryInProgress = true;
+
+            return false;
+        }
+
+        /**
+         * Triggers the draw call for the mesh.
+         * Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager.   
+         * Returns the Mesh.   
+         */
+        public render(subMesh: SubMesh, enableAlphaMode: boolean): Mesh {
+
+            // check occlusion query in progress
+
+            if (this.occlusionType !== AbstractMesh.OCCLUSION_TYPE_NO_VALUE) {
+                var isRenderMesh = this.renderOcclusionBoundingMesh();
+                if (!isRenderMesh) {
+                    return;
                 }
+
+                console.log("Enter Draw Mesh");
             }
 
             var scene = this.getScene();
@@ -1200,16 +1228,7 @@
             }
 
             // Draw
-            if (this.occlusionType !== AbstractMesh.OCCLUSION_TYPE_NO_VALUE) {
-                console.log("Enter Draw");
-                this._gl.beginQuery(this._gl.ANY_SAMPLES_PASSED, this.occlusionQuery);
-                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
-                this._gl.endQuery(this._gl.ANY_SAMPLES_PASSED);
-                this.isOcclusionQueryInProgress = true;
-            }
-            else {
-                this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
-            }
+            this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, effectiveMaterial);
 
             // Unbind
             effectiveMaterial.unbind();

+ 87 - 0
src/Rendering/babylon.occlusionBoundingBoxRenderer.ts

@@ -0,0 +1,87 @@
+module BABYLON {
+    export class OcclusionBoundingBoxRenderer {
+        public frontColor = new Color3(1, 1, 1);
+        public backColor = new Color3(0.1, 0.1, 0.1);
+
+        private _scene: Scene;
+        private _colorShader: ShaderMaterial;
+        private _vertexBuffers: { [key: string]: VertexBuffer } = {};
+        private _indexBuffer: WebGLBuffer;
+
+        constructor(scene: Scene) {
+            this._scene = scene;
+        }
+
+        private _prepareRessources(): void {
+            if (this._colorShader) {
+                return;
+            }
+
+            this._colorShader = new ShaderMaterial("colorShader", this._scene, "color",
+                {
+                    attributes: [VertexBuffer.PositionKind],
+                    uniforms: ["world", "viewProjection", "color"]
+                });
+
+
+            var engine = this._scene.getEngine();
+            var boxdata = VertexData.CreateBox({ size: 1.0 });
+            this._vertexBuffers[VertexBuffer.PositionKind] = new VertexBuffer(engine, boxdata.positions, VertexBuffer.PositionKind, false);
+            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 render(mesh: Mesh): void {
+
+            this._prepareRessources();
+
+            if (!this._colorShader.isReady()) {
+                return;
+            }
+
+            var engine = this._scene.getEngine();
+            engine.setDepthWrite(false);
+            this._colorShader._preBind();
+
+            var boundingBox = mesh._boundingInfo.boundingBox;
+            var min = boundingBox.minimum;
+            var max = boundingBox.maximum;
+            var diff = max.subtract(min);
+            var median = min.add(diff.scale(0.5));
+
+            var worldMatrix = Matrix.Scaling(diff.x, diff.y, diff.z)
+                .multiply(Matrix.Translation(median.x, median.y, median.z))
+                .multiply(boundingBox.getWorldMatrix());
+
+            // VBOs
+            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());
+
+            // Front
+            engine.setDepthFunctionToLess();
+            this._scene.resetCachedMaterial();
+            this._colorShader.setColor4("color", this.frontColor.toColor4());
+            this._colorShader.bind(worldMatrix);
+
+            // Draw order
+            engine.draw(false, 0, 24);
+
+            this._colorShader.unbind();
+            engine.setDepthFunctionToLessOrEqual();
+            engine.setDepthWrite(true);
+        }
+
+        public dispose(): void {
+            if (!this._colorShader) {
+                return;
+            }
+
+            this._colorShader.dispose();
+
+            var buffer = this._vertexBuffers[VertexBuffer.PositionKind];
+            if (buffer) {
+                buffer.dispose();
+                this._vertexBuffers[VertexBuffer.PositionKind] = null;
+            }
+            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
+        }
+    }
+}