Browse Source

feature Oprtimistic inclusion culling process

Jérôme Bousquié 6 years ago
parent
commit
b649691bad

+ 16 - 5
src/Culling/babylon.boundingInfo.ts

@@ -146,22 +146,33 @@ module BABYLON {
         }
 
         /**
-         * Returns `true` if the bounding info is within the frustum defined by the passed array of planes.
-         * @param frustumPlanes defines the frustum to test
-         * @param strategy defines the strategy to use for the culling (default is BABYLON.Scene.CULLINGSTRATEGY_STANDARD)
-         * @returns true if the bounding info is in the frustum planes
+         * Returns `true` if the bounding info is within the frustum defined by the passed array of planes.  
+         * @param frustumPlanes defines the frustum to test  
+         * @param strategy defines the strategy to use for the culling (default is BABYLON.Scene.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY)  
+         * @returns true if the bounding info is in the frustum planes  
          */
         public isInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>, strategy: number = AbstractMesh.CULLINGSTRATEGY_STANDARD): boolean {
+            let inclusionTest = (strategy === AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION || strategy === AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY);
+            let bSphereOnlyTest = (strategy === AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY || strategy === AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY);
+            
+            if (inclusionTest) {
+                if (this.boundingSphere.isCenterInFrustum(frustumPlanes)) {
+                    return true;
+                }
+            }
+            
             if (!this.boundingSphere.isInFrustum(frustumPlanes)) {
                 return false;
             }
 
-            if (strategy === AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY) {
+            if (bSphereOnlyTest) {
                 return true;
             }
+
             return this.boundingBox.isInFrustum(frustumPlanes);
         }
 
+
         /**
 		 * Gets the world distance between the min and max points of the bounding box
 		 */

+ 20 - 3
src/Culling/babylon.boundingSphere.ts

@@ -105,16 +105,33 @@ module BABYLON {
          * @returns true if there is an intersection
          */
         public isInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {
-            for (var i = 0; i < 6; i++) {
-                if (frustumPlanes[i].dotCoordinate(this.centerWorld) <= -this.radiusWorld) {
+            let center = this.centerWorld;
+            let radius = this.radiusWorld;
+            for (let i = 0; i < 6; i++) {
+                if (frustumPlanes[i].dotCoordinate(center) <= -radius) {
                     return false;
                 }
             }
-
             return true;
         }
 
         /**
+         * Tests if the bounding sphere center is inbetween the frustum planes.
+         * Used for optimistic fast inclusion.
+         * @param frustumPlanes defines the frustum planes to test
+         * @returns true if the sphere center is inbetween the frustum planes
+         */
+        public isCenterInFrustum(frustumPlanes: Array<DeepImmutable<Plane>>): boolean {
+            let center = this.centerWorld;
+            for (let i = 0; i < 6; i++) {
+                if (frustumPlanes[i].dotCoordinate(center) >= 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
          * Tests if a point is inside the bounding sphere
          * @param point defines the point to test
          * @returns true if the point is inside the bounding sphere

+ 43 - 3
src/Mesh/babylon.abstractMesh.ts

@@ -44,10 +44,41 @@ module BABYLON {
         /** Use a conservative occlusion algorithm */
         public static OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE = 1;
 
-        /** Default culling strategy with bounding box and bounding sphere and then frustum culling */
+        /** Default culling strategy : this is an exclusion test and it's the more accurate.   
+         *  Test order :  
+         *  Is the bounding sphere outside the frustum ?  
+         *  If not, are the bounding box vertices outside the frustum ?  
+         *  It not, then the cullable object is in the frustum.  
+         */
         public static readonly CULLINGSTRATEGY_STANDARD = 0;
-        /** Culling strategy with bounding sphere only and then frustum culling */
+        /** Culling strategy : Bounding Sphere Only.  
+         *  This is an exclusion test. It's faster than the standard strategy because the bounding box is not tested.  
+         *  It's also less accurate than the standard because some not visible objects can still be selected.  
+         *  Test : is the bounding sphere outside the frustum ?  
+         *  If not, then the cullable object is in the frustum.  
+         */
         public static readonly CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY = 1;
+        /** Culling strategy : Optimistic Inclusion.  
+         *  This in an inclusion test first, then the standard exclusion test.  
+         *  This can be faster when a cullable object is expected to be almost always in the camera frustum.  
+         *  This can also be a little slower than the standard test when the tested object center is not the frustum.  
+         *  Anyway, it's as accurate as the standard strategy.  
+         *  Test :  
+         *  Is the cullable object bounding sphere center in the frustum ?  
+         *  If not, apply the default culling strategy.  
+         */
+        public static readonly CULLINGSTRATEGY_OPTIMISTIC_INCLUSION = 2;
+        /** Culling strategy : Optimistic Inclusion then Bounding Sphere Only.  
+         *  This in an inclusion test first, then the bounding sphere only exclusion test.  
+         *  This can be the fastest test when a cullable object is expected to be almost always in the camera frustum.  
+         *  This can also be a little slower than the BoundingSphereOnly stratagy when the tested object center is not in the frustum.   
+         *  It's less accurate than the standard strategy and as accurate as the BoundingSphereOnly strategy.  
+         *  Test :  
+         *  Is the cullable object bounding sphere center in the frustum ?  
+         *  If not, apply the Bounding Sphere Only strategy. No Bounding Box is tested here.  
+         */
+        public static readonly CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY = 3;
+
 
         /**
          * No billboard
@@ -78,7 +109,16 @@ module BABYLON {
 
         private _facetData = new _FacetDataStorage();
 
-        /** Gets ot sets the culling strategy to use to find visible meshes */
+        /** 
+         * The culling strategy to use to check whether the mesh must be rendered or not.  
+         * This value can be changed at any time and will be used on the next render mesh selection.  
+         * The possible values are :   
+         * - AbstractMesh.CULLINGSTRATEGY_STANDARD  
+         * - AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY  
+         * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION  
+         * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY   
+         * Please read each static variable documentation to get details about the culling process.  
+         * */
         public cullingStrategy = AbstractMesh.CULLINGSTRATEGY_STANDARD;
 
         /**