Browse Source

Refactor of the OctreeQuery class. Use a separate subclass for shadowcaster-only queries.

Lasse Öörni 13 years ago
parent
commit
6c1536627e

+ 1 - 0
Engine/Graphics/OcclusionBuffer.cpp

@@ -376,6 +376,7 @@ bool OcclusionBuffer::IsVisible(const BoundingBox& worldSpaceBox) const
     if (rect.bottom_ >= height_)
     if (rect.bottom_ >= height_)
         rect.bottom_ = height_ - 1;
         rect.bottom_ = height_ - 1;
     
     
+    // Convert depth to integer and apply final bias
     int z = (int)(minZ + 0.5f) - OCCLUSION_FIXED_BIAS;
     int z = (int)(minZ + 0.5f) - OCCLUSION_FIXED_BIAS;
     
     
     if (!depthHierarchyDirty_)
     if (!depthHierarchyDirty_)

+ 7 - 8
Engine/Graphics/Octree.cpp

@@ -215,12 +215,11 @@ void Octant::GetDrawablesInternal(OctreeQuery& query, bool inside) const
     {
     {
         Drawable* drawable = *i;
         Drawable* drawable = *i;
         
         
-        if (!(drawable->GetDrawableFlags() & query.drawableFlags_) || !(drawable->GetViewMask() & query.viewMask_) ||
-            (query.shadowCastersOnly_ && !drawable->GetCastShadows()) ||
-            !drawable->IsVisible())
+        if (!(drawable->GetDrawableFlags() & query.drawableFlags_) || !drawable->IsVisible() ||
+            !(drawable->GetViewMask() & query.viewMask_))
             continue;
             continue;
         
         
-        if (query.TestDrawable(drawable->GetWorldBoundingBox(), inside) != OUTSIDE)
+        if (query.TestDrawable(drawable, inside) != OUTSIDE)
             query.result_.Push(drawable);
             query.result_.Push(drawable);
     }
     }
     
     
@@ -245,8 +244,8 @@ void Octant::GetDrawablesInternal(RayOctreeQuery& query) const
         Drawable* drawable = *i;
         Drawable* drawable = *i;
         unsigned drawableFlags = drawable->GetDrawableFlags();
         unsigned drawableFlags = drawable->GetDrawableFlags();
         
         
-        if (!(drawable->GetDrawableFlags() & query.drawableFlags_) || !(drawable->GetViewMask() & query.viewMask_) ||
-            !drawable->IsVisible() || (query.shadowCastersOnly_ && !drawable->GetCastShadows()))
+        if (!(drawable->GetDrawableFlags() & query.drawableFlags_) || !drawable->IsVisible() ||
+            !(drawable->GetViewMask() & query.viewMask_))
             continue;
             continue;
         
         
         drawable->ProcessRayQuery(query, query.result_);
         drawable->ProcessRayQuery(query, query.result_);
@@ -273,8 +272,8 @@ void Octant::GetDrawablesOnlyInternal(RayOctreeQuery& query, PODVector<Drawable*
         Drawable* drawable = *i;
         Drawable* drawable = *i;
         unsigned drawableFlags = drawable->GetDrawableFlags();
         unsigned drawableFlags = drawable->GetDrawableFlags();
         
         
-        if (!(drawable->GetDrawableFlags() & query.drawableFlags_) || !(drawable->GetViewMask() & query.viewMask_) ||
-            !drawable->IsVisible() || (query.shadowCastersOnly_ && !drawable->GetCastShadows()))
+        if (!(drawable->GetDrawableFlags() & query.drawableFlags_) || !drawable->IsVisible() ||
+            !(drawable->GetViewMask() & query.viewMask_))
             continue;
             continue;
         
         
         drawables.Push(drawable);
         drawables.Push(drawable);

+ 30 - 8
Engine/Graphics/OctreeQuery.cpp

@@ -33,10 +33,10 @@ Intersection PointOctreeQuery::TestOctant(const BoundingBox& box, bool inside) c
         return INSIDE;
         return INSIDE;
 }
 }
 
 
-Intersection PointOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
+Intersection PointOctreeQuery::TestDrawable(Drawable* drawable, bool inside) const
 {
 {
     if (!inside)
     if (!inside)
-        return box.IsInside(point_);
+        return drawable->GetWorldBoundingBox().IsInside(point_);
     else
     else
         return INSIDE;
         return INSIDE;
 }
 }
@@ -49,10 +49,10 @@ Intersection SphereOctreeQuery::TestOctant(const BoundingBox& box, bool inside)
         return INSIDE;
         return INSIDE;
 }
 }
 
 
-Intersection SphereOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
+Intersection SphereOctreeQuery::TestDrawable(Drawable* drawable, bool inside) const
 {
 {
     if (!inside)
     if (!inside)
-        return sphere_.IsInsideFast(box);
+        return sphere_.IsInsideFast(drawable->GetWorldBoundingBox());
     else
     else
         return INSIDE;
         return INSIDE;
 }
 }
@@ -65,10 +65,10 @@ Intersection BoxOctreeQuery::TestOctant(const BoundingBox& box, bool inside) con
         return INSIDE;
         return INSIDE;
 }
 }
 
 
-Intersection BoxOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
+Intersection BoxOctreeQuery::TestDrawable(Drawable* drawable, bool inside) const
 {
 {
     if (!inside)
     if (!inside)
-        return box_.IsInsideFast(box);
+        return box_.IsInsideFast(drawable->GetWorldBoundingBox());
     else
     else
         return INSIDE;
         return INSIDE;
 }
 }
@@ -81,10 +81,32 @@ Intersection FrustumOctreeQuery::TestOctant(const BoundingBox& box, bool inside)
         return INSIDE;
         return INSIDE;
 }
 }
 
 
-Intersection FrustumOctreeQuery::TestDrawable(const BoundingBox& box, bool inside) const
+Intersection FrustumOctreeQuery::TestDrawable(Drawable* drawable, bool inside) const
 {
 {
     if (!inside)
     if (!inside)
-        return frustum_.IsInsideFast(box);
+        return frustum_.IsInsideFast(drawable->GetWorldBoundingBox());
     else
     else
         return INSIDE;
         return INSIDE;
 }
 }
+
+Intersection ShadowCasterFrustumOctreeQuery::TestOctant(const BoundingBox& box, bool inside) const
+{
+    if (!inside)
+        return frustum_.IsInside(box);
+    else
+        return INSIDE;
+}
+
+Intersection ShadowCasterFrustumOctreeQuery::TestDrawable(Drawable* drawable, bool inside) const
+{
+    if (!drawable->GetCastShadows())
+        return OUTSIDE;
+    else
+    {
+        if (!inside)
+            return frustum_.IsInsideFast(drawable->GetWorldBoundingBox());
+        else
+            return INSIDE;
+    }
+}
+

+ 39 - 24
Engine/Graphics/OctreeQuery.h

@@ -37,11 +37,10 @@ class OctreeQuery
 {
 {
 public:
 public:
     /// Construct with query parameters.
     /// Construct with query parameters.
-    OctreeQuery(PODVector<Drawable*>& result, unsigned char drawableFlags, unsigned viewMask, bool shadowCastersOnly) :
+    OctreeQuery(PODVector<Drawable*>& result, unsigned char drawableFlags, unsigned viewMask) :
         result_(result),
         result_(result),
         drawableFlags_(drawableFlags),
         drawableFlags_(drawableFlags),
-        viewMask_(viewMask),
-        shadowCastersOnly_(shadowCastersOnly)
+        viewMask_(viewMask)
     {
     {
     }
     }
     
     
@@ -53,7 +52,7 @@ public:
     /// Intersection test for an octant.
     /// Intersection test for an octant.
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const = 0;
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const = 0;
     /// Intersection test for a drawable.
     /// Intersection test for a drawable.
-    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const = 0;
+    virtual Intersection TestDrawable(Drawable* drawable, bool inside) const = 0;
     
     
     /// Result vector reference.
     /// Result vector reference.
     PODVector<Drawable*>& result_;
     PODVector<Drawable*>& result_;
@@ -61,8 +60,6 @@ public:
     unsigned char drawableFlags_;
     unsigned char drawableFlags_;
     /// Drawable layers to include.
     /// Drawable layers to include.
     unsigned viewMask_;
     unsigned viewMask_;
-    /// Get shadowcasters only flag.
-    bool shadowCastersOnly_;
 };
 };
 
 
 /// Point octree query.
 /// Point octree query.
@@ -71,8 +68,8 @@ class PointOctreeQuery : public OctreeQuery
 public:
 public:
     /// Construct with point and query parameters.
     /// Construct with point and query parameters.
     PointOctreeQuery(PODVector<Drawable*>& result, const Vector3& point, unsigned char drawableFlags = DRAWABLE_ANY,
     PointOctreeQuery(PODVector<Drawable*>& result, const Vector3& point, unsigned char drawableFlags = DRAWABLE_ANY,
-        unsigned viewMask = DEFAULT_VIEWMASK, bool shadowCastersOnly = false) :
-        OctreeQuery(result, drawableFlags, viewMask, shadowCastersOnly),
+        unsigned viewMask = DEFAULT_VIEWMASK) :
+        OctreeQuery(result, drawableFlags, viewMask),
         point_(point)
         point_(point)
     {
     {
     }
     }
@@ -80,7 +77,7 @@ public:
     /// Intersection test for an octant.
     /// Intersection test for an octant.
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable.
     /// Intersection test for a drawable.
-    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
+    virtual Intersection TestDrawable(Drawable* drawable, bool inside) const;
     
     
     /// Point.
     /// Point.
     Vector3 point_;
     Vector3 point_;
@@ -92,8 +89,8 @@ class SphereOctreeQuery : public OctreeQuery
 public:
 public:
     /// Construct with sphere and query parameters.
     /// Construct with sphere and query parameters.
     SphereOctreeQuery(PODVector<Drawable*>& result, const Sphere& sphere, unsigned char drawableFlags = DRAWABLE_ANY,
     SphereOctreeQuery(PODVector<Drawable*>& result, const Sphere& sphere, unsigned char drawableFlags = DRAWABLE_ANY,
-        unsigned viewMask = DEFAULT_VIEWMASK, bool shadowCastersOnly = false) :
-        OctreeQuery(result, drawableFlags, viewMask, shadowCastersOnly),
+        unsigned viewMask = DEFAULT_VIEWMASK) :
+        OctreeQuery(result, drawableFlags, viewMask),
         sphere_(sphere)
         sphere_(sphere)
     {
     {
     }
     }
@@ -101,7 +98,7 @@ public:
     /// Intersection test for an octant.
     /// Intersection test for an octant.
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable.
     /// Intersection test for a drawable.
-    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
+    virtual Intersection TestDrawable(Drawable* drawable, bool inside) const;
     
     
     /// Sphere.
     /// Sphere.
     Sphere sphere_;
     Sphere sphere_;
@@ -113,8 +110,8 @@ class BoxOctreeQuery : public OctreeQuery
 public:
 public:
     /// Construct with bounding box and query parameters.
     /// Construct with bounding box and query parameters.
     BoxOctreeQuery(PODVector<Drawable*>& result, const BoundingBox& box, unsigned char drawableFlags = DRAWABLE_ANY,
     BoxOctreeQuery(PODVector<Drawable*>& result, const BoundingBox& box, unsigned char drawableFlags = DRAWABLE_ANY,
-        unsigned viewMask = DEFAULT_VIEWMASK, bool shadowCastersOnly = false) :
-        OctreeQuery(result, drawableFlags, viewMask, shadowCastersOnly),
+        unsigned viewMask = DEFAULT_VIEWMASK) :
+        OctreeQuery(result, drawableFlags, viewMask),
         box_(box)
         box_(box)
     {
     {
     }
     }
@@ -122,7 +119,7 @@ public:
     /// Intersection test for an octant.
     /// Intersection test for an octant.
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable.
     /// Intersection test for a drawable.
-    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
+    virtual Intersection TestDrawable(Drawable* drawable, bool inside) const;
     
     
     /// Bounding box.
     /// Bounding box.
     BoundingBox box_;
     BoundingBox box_;
@@ -134,21 +131,43 @@ class FrustumOctreeQuery : public OctreeQuery
 public:
 public:
     /// Construct with frustum and query parameters.
     /// Construct with frustum and query parameters.
     FrustumOctreeQuery(PODVector<Drawable*>& result, const Frustum& frustum, unsigned char drawableFlags = DRAWABLE_ANY,
     FrustumOctreeQuery(PODVector<Drawable*>& result, const Frustum& frustum, unsigned char drawableFlags = DRAWABLE_ANY,
-        unsigned viewMask = DEFAULT_VIEWMASK, bool shadowCastersOnly = false) :
-        OctreeQuery(result, drawableFlags, viewMask, shadowCastersOnly),
+        unsigned viewMask = DEFAULT_VIEWMASK) :
+        OctreeQuery(result, drawableFlags, viewMask),
         frustum_(frustum)
         frustum_(frustum)
     {
     {
     }
     }
     
     
     /// Intersection test for an octant.
     /// Intersection test for an octant.
-    virtual Intersection TestDrawable(const BoundingBox& box, bool inside) const;
+    virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     /// Intersection test for a drawable.
     /// Intersection test for a drawable.
+    virtual Intersection TestDrawable(Drawable* drawable, bool inside) const;
+    
+    /// Frustum.
+    Frustum frustum_;
+};
+
+/// %Frustum octree query for shadowcasters.
+class ShadowCasterFrustumOctreeQuery : public OctreeQuery
+{
+public:
+    /// Construct with frustum and query parameters.
+    ShadowCasterFrustumOctreeQuery(PODVector<Drawable*>& result, const Frustum& frustum, unsigned char drawableFlags = DRAWABLE_ANY,
+        unsigned viewMask = DEFAULT_VIEWMASK) :
+        OctreeQuery(result, drawableFlags, viewMask),
+        frustum_(frustum)
+    {
+    }
+    
+    /// Intersection test for an octant.
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
     virtual Intersection TestOctant(const BoundingBox& box, bool inside) const;
+    /// Intersection test for a drawable.
+    virtual Intersection TestDrawable(Drawable* drawable, bool inside) const;
     
     
     /// Frustum.
     /// Frustum.
     Frustum frustum_;
     Frustum frustum_;
 };
 };
 
 
+
 /// Graphics raycast detail level.
 /// Graphics raycast detail level.
 enum RayQueryLevel
 enum RayQueryLevel
 {
 {
@@ -177,15 +196,13 @@ class RayOctreeQuery
 public:
 public:
     /// Construct with ray and query parameters.
     /// Construct with ray and query parameters.
     RayOctreeQuery(PODVector<RayQueryResult>& result, const Ray& ray, RayQueryLevel level = RAY_TRIANGLE,
     RayOctreeQuery(PODVector<RayQueryResult>& result, const Ray& ray, RayQueryLevel level = RAY_TRIANGLE,
-        float maxDistance = M_INFINITY, unsigned char drawableFlags = DRAWABLE_ANY, unsigned viewMask = DEFAULT_VIEWMASK,
-        bool shadowCastersOnly = false) :
+        float maxDistance = M_INFINITY, unsigned char drawableFlags = DRAWABLE_ANY, unsigned viewMask = DEFAULT_VIEWMASK) :
         result_(result),
         result_(result),
         ray_(ray),
         ray_(ray),
         level_(level),
         level_(level),
         maxDistance_(maxDistance),
         maxDistance_(maxDistance),
         drawableFlags_(drawableFlags),
         drawableFlags_(drawableFlags),
-        viewMask_(viewMask),
-        shadowCastersOnly_(shadowCastersOnly)
+        viewMask_(viewMask)
     {
     {
     }
     }
     
     
@@ -197,8 +214,6 @@ public:
     unsigned char drawableFlags_;
     unsigned char drawableFlags_;
     /// Drawable layers to include.
     /// Drawable layers to include.
     unsigned viewMask_;
     unsigned viewMask_;
-    /// Get shadowcasters only flag.
-    bool shadowCastersOnly_;
     /// Maximum ray distance.
     /// Maximum ray distance.
     float maxDistance_;
     float maxDistance_;
     /// Raycast detail level.
     /// Raycast detail level.

+ 2 - 1
Engine/Graphics/View.cpp

@@ -1630,7 +1630,8 @@ void View::ProcessLight(LightQueryResult& query, unsigned threadIndex)
         // Reuse lit geometry query for all except directional lights
         // Reuse lit geometry query for all except directional lights
         if (type == LIGHT_DIRECTIONAL)
         if (type == LIGHT_DIRECTIONAL)
         {
         {
-            FrustumOctreeQuery octreeQuery(tempDrawables, shadowCameraFrustum, DRAWABLE_GEOMETRY, camera_->GetViewMask(), true);
+            ShadowCasterFrustumOctreeQuery octreeQuery(tempDrawables, shadowCameraFrustum, DRAWABLE_GEOMETRY,
+                camera_->GetViewMask());
             octree_->GetDrawables(octreeQuery);
             octree_->GetDrawables(octreeQuery);
         }
         }