Browse Source

Removed counterproductive frustum side masking from culling tests.

Lasse Öörni 14 năm trước cách đây
mục cha
commit
0ea42a9762

+ 10 - 15
Engine/Graphics/Octree.cpp

@@ -168,22 +168,17 @@ void Octant::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
     }
 }
 
-void Octant::GetDrawablesInternal(OctreeQuery& query, unsigned mask) const
+void Octant::GetDrawablesInternal(OctreeQuery& query, bool inside) const
 {
     if (!numDrawables_)
         return;
     
-    if (mask != M_MAX_UNSIGNED)
-    {
-        Intersection res = query.TestOctant(cullingBox_, mask);
-        
-        if (res == OUTSIDE && this != root_)
-            // Fully outside, so cull this octant, its children & drawables
-            return;
-        if (res == INSIDE) 
-            // Fully inside, no culling checks necessary for children & drawables
-            mask = M_MAX_UNSIGNED;
-    }
+    Intersection res = query.TestOctant(cullingBox_, inside);
+    if (res == OUTSIDE && this != root_)
+        // Fully outside, so cull this octant, its children & drawables
+        return;
+    if (res == INSIDE)
+        inside = true;
     
     for (PODVector<Drawable*>::ConstIterator i = drawables_.Begin(); i != drawables_.End(); ++i)
     {
@@ -197,14 +192,14 @@ void Octant::GetDrawablesInternal(OctreeQuery& query, unsigned mask) const
         if (query.shadowCastersOnly_ && !drawable->GetCastShadows())
             continue;
         
-        if (query.TestDrawable(drawable->GetWorldBoundingBox(), mask) != OUTSIDE)
+        if (query.TestDrawable(drawable->GetWorldBoundingBox(), inside) != OUTSIDE)
             query.result_.Push(drawable);
     }
     
     for (unsigned i = 0; i < NUM_OCTANTS; ++i)
     {
         if (children_[i])
-            children_[i]->GetDrawablesInternal(query, mask);
+            children_[i]->GetDrawablesInternal(query, inside);
     }
 }
 
@@ -378,7 +373,7 @@ void Octree::GetDrawables(OctreeQuery& query) const
     PROFILE(OctreeQuery);
     
     query.result_.Clear();
-    GetDrawablesInternal(query, 0);
+    GetDrawablesInternal(query, false);
 }
 
 void Octree::GetDrawables(RayOctreeQuery& query) const

+ 1 - 1
Engine/Graphics/Octree.h

@@ -97,7 +97,7 @@ public:
     
 protected:
     /// Return drawable objects by a query, called internally
-    void GetDrawablesInternal(OctreeQuery& query, unsigned mask) const;
+    void GetDrawablesInternal(OctreeQuery& query, bool inside) const;
     /// Return drawable objects by a ray query, called internally
     void GetDrawablesInternal(RayOctreeQuery& query) const;
     /// Free child octants. If drawable objects still exist, move them to root

+ 43 - 38
Engine/Graphics/OctreeQuery.cpp

@@ -26,74 +26,82 @@
 #include "OctreeQuery.h"
 #include "DebugNew.h"
 
-Intersection PointOctreeQuery::TestOctant(const BoundingBox& box, unsigned& mask) const
+Intersection PointOctreeQuery::TestOctant(const BoundingBox& box, bool inside) const
 {
-    return box.IsInside(point_);
+    if (!inside)
+        return box.IsInside(point_);
+    else
+        return INSIDE;
 }
 
-Intersection PointOctreeQuery::TestDrawable(const BoundingBox& box, unsigned& mask) const
+Intersection PointOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
 {
-    return box.IsInside(point_);
+    if (!inside)
+        return box.IsInside(point_);
+    else
+        return INSIDE;
 }
 
-Intersection SphereOctreeQuery::TestOctant(const BoundingBox& box, unsigned& mask) const
+Intersection SphereOctreeQuery::TestOctant(const BoundingBox& box, bool inside) const
 {
-    if (mask == M_MAX_UNSIGNED)
+    if (!inside)
+        return sphere_.IsInside(box);
+    else
         return INSIDE;
-    
-    return sphere_.IsInside(box);
 }
 
-Intersection SphereOctreeQuery::TestDrawable(const BoundingBox& box, unsigned& mask) const
+Intersection SphereOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
 {
-    if (mask == M_MAX_UNSIGNED)
+    if (!inside)
+        return sphere_.IsInsideFast(box);
+    else
         return INSIDE;
-    
-    return sphere_.IsInsideFast(box);
 }
 
-Intersection BoxOctreeQuery::TestOctant(const BoundingBox& box, unsigned& mask) const
+Intersection BoxOctreeQuery::TestOctant(const BoundingBox& box, bool inside) const
 {
-    if (mask == M_MAX_UNSIGNED)
+    if (!inside)
+        return box_.IsInside(box);
+    else
         return INSIDE;
-    
-    return box_.IsInside(box);
 }
 
-Intersection BoxOctreeQuery::TestDrawable(const BoundingBox& box, unsigned& mask) const
+Intersection BoxOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
 {
-    if (mask == M_MAX_UNSIGNED)
+    if (!inside)
+        return box_.IsInsideFast(box);
+    else
         return INSIDE;
-    
-    return box_.IsInsideFast(box);
 }
 
-Intersection FrustumOctreeQuery::TestOctant(const BoundingBox& box, unsigned& mask) const
+Intersection FrustumOctreeQuery::TestOctant(const BoundingBox& box, bool inside) const
 {
-    if (mask == M_MAX_UNSIGNED)
+    if (!inside)
+        return frustum_.IsInside(box);
+    else
         return INSIDE;
-    
-    return frustum_.IsInsideMasked(box, mask);
 }
 
-Intersection FrustumOctreeQuery::TestDrawable(const BoundingBox& box, unsigned& mask) const
+Intersection FrustumOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
 {
-    if (mask == M_MAX_UNSIGNED)
+    if (!inside)
+        return frustum_.IsInsideFast(box);
+    else
         return INSIDE;
-    
-    return frustum_.IsInsideFastMasked(box, mask);
 }
 
-Intersection OccludedFrustumOctreeQuery::TestOctant(const BoundingBox& box, unsigned& mask) const
+Intersection OccludedFrustumOctreeQuery::TestOctant(const BoundingBox& box, bool inside) const
 {
     // First check the frustum
-    Intersection frustumRes = INSIDE;
-    if (mask != M_MAX_UNSIGNED)
+    Intersection frustumRes;
+    if (!inside)
     {
-        frustumRes = frustum_.IsInsideMasked(box, mask);
+        frustumRes = frustum_.IsInside(box);
         if (frustumRes == OUTSIDE)
             return OUTSIDE;
     }
+    else
+        frustumRes = INSIDE;
     
     // Then check occlusion
     if (buffer_->IsVisible(box))
@@ -102,14 +110,11 @@ Intersection OccludedFrustumOctreeQuery::TestOctant(const BoundingBox& box, unsi
         return OUTSIDE;
 }
 
-Intersection OccludedFrustumOctreeQuery::TestDrawable(const BoundingBox& box, unsigned& mask) const
+Intersection OccludedFrustumOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
 {
     // First check the frustum
-    if (mask != M_MAX_UNSIGNED)
-    {
-        if (frustum_.IsInsideFastMasked(box, mask) == OUTSIDE)
-            return OUTSIDE;
-    }
+    if (!inside && frustum_.IsInsideFast(box) == OUTSIDE)
+        return OUTSIDE;
     
     // Then check occlusion
     if (buffer_->IsVisible(box))

+ 12 - 12
Engine/Graphics/OctreeQuery.h

@@ -51,9 +51,9 @@ public:
     }
     
     /// Intersection test for an octant
-    virtual Intersection TestOctant(const BoundingBox& box, unsigned& mask) const = 0;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const = 0;
     /// Intersection test for a drawable
-    virtual Intersection TestDrawable(const BoundingBox& box, unsigned& mask) const = 0;
+    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const = 0;
     
     /// Result vector reference
     PODVector<Drawable*>& result_;
@@ -78,9 +78,9 @@ public:
     }
     
     /// Intersection test for an octant
-    virtual Intersection TestOctant(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable
-    virtual Intersection TestDrawable(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
     
     /// Point
     Vector3 point_;
@@ -99,9 +99,9 @@ public:
     }
     
     /// Intersection test for an octant
-    virtual Intersection TestOctant(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable
-    virtual Intersection TestDrawable(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
     
     /// Sphere
     Sphere sphere_;
@@ -120,9 +120,9 @@ public:
     }
     
     /// Intersection test for an octant
-    virtual Intersection TestOctant(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable
-    virtual Intersection TestDrawable(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
     
     /// Bounding box
     BoundingBox box_;
@@ -141,9 +141,9 @@ public:
     }
     
     /// Intersection test for an octant
-    virtual Intersection TestDrawable(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable
-    virtual Intersection TestOctant(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     
     /// Frustum
     Frustum frustum_;
@@ -163,9 +163,9 @@ public:
     }
     
     /// Intersection test for an octant
-    virtual Intersection TestOctant(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable
-    virtual Intersection TestDrawable(const BoundingBox& box, unsigned& mask) const;
+    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
     
     /// Frustum
     Frustum frustum_;

+ 0 - 49
Engine/Math/Frustum.h

@@ -151,55 +151,6 @@ public:
         return INSIDE;
     }
     
-    /// Test if a bounding box is inside, outside or intersects. Use (and update) a plane bitmask to speed up testing a box hierarchy
-    Intersection IsInsideMasked(const BoundingBox& box, unsigned& mask) const
-    {
-        Vector3 center = box.Center();
-        Vector3 edge = center - box.min_;
-        bool allInside = true;
-        
-        for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
-        {
-            unsigned bit = 1 << i;
-            if (!(mask & bit))
-            {
-                float dist = planes_[i].Distance(center);
-                float absDist = planes_[i].AbsDistanceFast(edge);
-                
-                if (dist < -absDist)
-                    return OUTSIDE;
-                if (dist < absDist)
-                    allInside = false;
-                else
-                    mask |= bit;
-            }
-        }
-        
-        return allInside ? INSIDE : INTERSECTS;
-    }
-    
-    /// Test if a bounding box is (partially) inside or outside. Use a bitmask to skip unnecessary planes
-    Intersection IsInsideFastMasked(const BoundingBox& box, unsigned mask) const
-    {
-        Vector3 center = box.Center();
-        Vector3 edge = center - box.min_;
-        
-        for (unsigned i = 0; i < NUM_FRUSTUM_PLANES; ++i)
-        {
-            unsigned bit = 1 << i;
-            if (!(mask & bit))
-            {
-                float dist = planes_[i].Distance(center);
-                float absDist = planes_[i].AbsDistanceFast(edge);
-                
-                if (dist < -absDist)
-                    return OUTSIDE;
-            }
-        }
-        
-        return INSIDE;
-    }
-    
     /// Return transformed by a 3x3 matrix
     Frustum Transformed(const Matrix3& transform) const;
     /// Return transformed by a 4x3 matrix