Ver código fonte

Merge pull request #1413 from sebavan/HighlightLayerExcludeList

Highlight layer exclude list
David Catuhe 8 anos atrás
pai
commit
d73506b4ad
3 arquivos alterados com 92 adições e 30 exclusões
  1. 66 6
      src/Layer/babylon.highlightlayer.ts
  2. 4 3
      src/Mesh/babylon.mesh.ts
  3. 22 21
      src/babylon.scene.ts

+ 66 - 6
src/Layer/babylon.highlightlayer.ts

@@ -75,6 +75,24 @@
     }
 
     /**
+     * Storage interface grouping all the information required for an excluded mesh.
+     */
+    interface IHighlightLayerExcludedMesh {
+        /** 
+         * The glowy mesh
+         */
+        mesh: Mesh;
+        /**
+         * The mesh render callback use to prevent stencil use
+         */
+        beforeRender: Observer<Mesh>;
+        /**
+         * The mesh render callback use to restore previous stencil use
+         */
+        afterRender: Observer<Mesh>;
+    }
+
+    /**
      * The highlight layer Helps adding a glow effect around a mesh.
      * 
      * Once instantiated in a scene, simply use the pushMesh or removeMesh method to add or remove
@@ -117,6 +135,7 @@
         private _maxSize: number = 0;
         private _shouldRender = false;
         private _instanceGlowingMeshStencilReference = HighlightLayer.glowingMeshStencilReference++;
+        private _excludedMeshes: { [id: string]: IHighlightLayerExcludedMesh } = {};
 
         /**
          * Specifies whether or not the inner glow is ACTIVE in the layer.
@@ -129,9 +148,9 @@
         public outerGlow: boolean = true;
 
         /**
-         * Specifies the listof mesh excluded during the generation of the highlight layer.
+         * Helps enabling disabling the highlight depending on the layers being rendered.
          */
-        public excludedMeshes: Mesh[] = [];
+        public layerMask = 0xFFFFFFFF;
 
         /**
          * Specifies the horizontal size of the blur.
@@ -353,7 +372,7 @@
                 }
 
                 // Excluded Mesh
-                if (this.excludedMeshes.indexOf(mesh) > -1) {
+                if (this._excludedMeshes[mesh.id]) {
                     return;
                 };
 
@@ -600,6 +619,39 @@
         }
 
         /**
+         * Add a mesh in the exclusion list to prevent it to impact or being impacted by the highlight layer.
+         * @param mesh The mesh to exclude from the highlight layer
+         */
+        public addExcludedMesh(mesh: Mesh) {
+            var meshExcluded = this._excludedMeshes[mesh.id];
+            if (!meshExcluded) {
+                this._excludedMeshes[mesh.id] = {
+                    mesh: mesh,
+                    beforeRender: mesh.onBeforeRenderObservable.add((mesh: Mesh) => {
+                        mesh.getEngine().setStencilBuffer(false);
+                    }),
+                    afterRender: mesh.onAfterRenderObservable.add((mesh: Mesh) => {
+                        mesh.getEngine().setStencilBuffer(true);
+                    }),
+                }
+            }
+        }
+
+        /**
+          * Remove a mesh from the exclusion list to let it impact or being impacted by the highlight layer.
+          * @param mesh The mesh to highlight
+          */
+        public removeExcludedMesh(mesh: Mesh) {
+            var meshExcluded = this._excludedMeshes[mesh.id];
+            if (meshExcluded) {
+                mesh.onBeforeRenderObservable.remove(meshExcluded.beforeRender);
+                mesh.onAfterRenderObservable.remove(meshExcluded.afterRender);
+            }
+
+            this._excludedMeshes[mesh.id] = undefined;
+        }
+
+        /**
          * Add a mesh in the highlight layer in order to make it glow with the chosen color.
          * @param mesh The mesh to highlight
          * @param color The color of the highlight
@@ -616,7 +668,7 @@
                     color: color,
                     // Lambda required for capture due to Observable this context
                     observerHighlight: mesh.onBeforeRenderObservable.add((mesh: Mesh) => {
-                        if (this.excludedMeshes.indexOf(mesh) > -1) {
+                        if (this._excludedMeshes[mesh.id]) {
                             this.defaultStencilReference(mesh);
                         }
                         else {
@@ -710,14 +762,22 @@
             this.disposeTextureAndPostProcesses();
 
             // Clean mesh references 
-            for (var id in this._meshes) {
-                var meshHighlight = this._meshes[id];
+            for (let id in this._meshes) {
+                let meshHighlight = this._meshes[id];
                 if (meshHighlight && meshHighlight.mesh) {
                     meshHighlight.mesh.onBeforeRenderObservable.remove(meshHighlight.observerHighlight);
                     meshHighlight.mesh.onAfterRenderObservable.remove(meshHighlight.observerDefault);
                 }
             }
             this._meshes = null;
+            for (let id in this._excludedMeshes) {
+                let meshHighlight = this._excludedMeshes[id];
+                if (meshHighlight) {
+                    meshHighlight.mesh.onBeforeRenderObservable.remove(meshHighlight.beforeRender);
+                    meshHighlight.mesh.onAfterRenderObservable.remove(meshHighlight.afterRender);
+                }
+            }
+            this._excludedMeshes = null;
 
             // Remove from scene
             var index = this._scene.highlightLayers.indexOf(this, 0);

+ 4 - 3
src/Mesh/babylon.mesh.ts

@@ -439,7 +439,7 @@
             if (!this._geometry) {
                 var result = [];
                 if (this._delayInfo) {
-                    this._delayInfo.forEach( function(kind, index, array) {
+                    this._delayInfo.forEach(function (kind, index, array) {
                         result.push(kind);
                     });
                 }
@@ -759,7 +759,7 @@
 
             var geometry = this._geometry.copy(Geometry.RandomId());
 
-			oldGeometry.releaseForMesh(this, true);
+            oldGeometry.releaseForMesh(this, true);
             geometry.applyToMesh(this);
         }
 
@@ -1346,6 +1346,7 @@
                 let highlightLayer = highlightLayers[i];
                 if (highlightLayer) {
                     highlightLayer.removeMesh(this);
+                    highlightLayer.removeExcludedMesh(this);
                 }
             }
 
@@ -2582,7 +2583,7 @@
         public static MinMax(meshes: AbstractMesh[]): { min: Vector3; max: Vector3 } {
             var minVector: Vector3 = null;
             var maxVector: Vector3 = null;
-            meshes.forEach( function(mesh, index, array) {
+            meshes.forEach(function (mesh, index, array) {
                 var boundingBox = mesh.getBoundingInfo().boundingBox;
                 if (!minVector) {
                     minVector = boundingBox.minimumWorld;

+ 22 - 21
src/babylon.scene.ts

@@ -34,7 +34,7 @@
     export class PointerInfoBase {
         constructor(public type: number, public event: PointerEvent | MouseWheelEvent) {
         }
-        
+
     }
 
     /**
@@ -104,7 +104,7 @@
         public animationsEnabled = true;
         public constantlyUpdateMeshUnderPointer = false;
         public useRightHandedSystem = false;
-        
+
         public hoverCursor = "pointer";
 
         // Events
@@ -412,7 +412,7 @@
          * @type {BABYLON.ActionManager}
         */
         public actionManager: ActionManager;
-     
+
         public _actionManagers = new Array<ActionManager>();
         private _meshesForIntersections = new SmartArray<AbstractMesh>(256);
 
@@ -433,20 +433,20 @@
         private _engine: Engine;
 
         // Performance counters
-        private _totalMeshesCounter           = new PerfCounter();
-        private _totalLightsCounter           = new PerfCounter();
-        private _totalMaterialsCounter        = new PerfCounter();
-        private _totalTexturesCounter         = new PerfCounter();
-        private _totalVertices                = new PerfCounter();
-        public  _activeIndices                = new PerfCounter();
-        public  _activeParticles              = new PerfCounter();
-        private _lastFrameDuration            = new PerfCounter();
+        private _totalMeshesCounter = new PerfCounter();
+        private _totalLightsCounter = new PerfCounter();
+        private _totalMaterialsCounter = new PerfCounter();
+        private _totalTexturesCounter = new PerfCounter();
+        private _totalVertices = new PerfCounter();
+        public _activeIndices = new PerfCounter();
+        public _activeParticles = new PerfCounter();
+        private _lastFrameDuration = new PerfCounter();
         private _evaluateActiveMeshesDuration = new PerfCounter();
-        private _renderTargetsDuration        = new PerfCounter();
-        public  _particlesDuration            = new PerfCounter();
-        private _renderDuration               = new PerfCounter();
-        public  _spritesDuration              = new PerfCounter();
-        public  _activeBones                  = new PerfCounter();
+        private _renderTargetsDuration = new PerfCounter();
+        public _particlesDuration = new PerfCounter();
+        private _renderDuration = new PerfCounter();
+        public _spritesDuration = new PerfCounter();
+        public _activeBones = new PerfCounter();
 
         private _animationRatio: number;
 
@@ -1925,7 +1925,7 @@
             this._particlesDuration.endMonitoring(false);
         }
 
-        private _activeMesh(sourceMesh:AbstractMesh, mesh: AbstractMesh): void {
+        private _activeMesh(sourceMesh: AbstractMesh, mesh: AbstractMesh): void {
             if (mesh.skeleton && this.skeletonsEnabled) {
                 if (this._activeSkeletons.pushNoDuplicate(mesh.skeleton)) {
                     mesh.skeleton.prepare();
@@ -2054,7 +2054,8 @@
             var renderhighlights = false;
             if (this.highlightLayers && this.highlightLayers.length > 0) {
                 for (let i = 0; i < this.highlightLayers.length; i++) {
-                    if (this.highlightLayers[i].shouldRender()) {
+                    let highlightLayer = this.highlightLayers[i];
+                    if ((highlightLayer.layerMask & camera.layerMask) && highlightLayer.shouldRender()) {
                         renderhighlights = true;
                         this._engine.setStencilBuffer(true);
                         break;
@@ -2229,7 +2230,7 @@
 
             // Before render
             this.onBeforeRenderObservable.notifyObservers(this);
-            
+
             // Customs render targets
             this._renderTargetsDuration.beginMonitoring();
             var beforeRenderTargetDate = Tools.Now;
@@ -2989,7 +2990,7 @@
             opaqueSortCompareFn: (a: SubMesh, b: SubMesh) => number = null,
             alphaTestSortCompareFn: (a: SubMesh, b: SubMesh) => number = null,
             transparentSortCompareFn: (a: SubMesh, b: SubMesh) => number = null): void {
-            
+
             this._renderingManager.setRenderingOrder(renderingGroupId,
                 opaqueSortCompareFn,
                 alphaTestSortCompareFn,
@@ -3002,7 +3003,7 @@
          * @param renderingGroupId The rendering group id corresponding to its index
          * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
          */
-        public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean): void {            
+        public setRenderingAutoClearDepthStencil(renderingGroupId: number, autoClearDepthStencil: boolean): void {
             this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
         }
     }