Browse Source

Do not use octree query to find zone. Instead mark the drawable's zone inconclusive (temporary) if necessary.

Lasse Öörni 13 years ago
parent
commit
dbbf2f3310
4 changed files with 30 additions and 38 deletions
  1. 11 2
      Engine/Graphics/Drawable.cpp
  2. 3 1
      Engine/Graphics/Drawable.h
  3. 16 33
      Engine/Graphics/View.cpp
  4. 0 2
      Engine/Graphics/View.h

+ 11 - 2
Engine/Graphics/Drawable.cpp

@@ -63,7 +63,8 @@ Drawable::Drawable(Context* context) :
     octant_(0),
     firstLight_(0),
     viewFrame_(0),
-    viewCamera_(0)
+    viewCamera_(0),
+    temporaryZone_(false)
 {
 }
 
@@ -209,10 +210,11 @@ const BoundingBox& Drawable::GetWorldBoundingBox()
     return worldBoundingBox_;
 }
 
-void Drawable::SetZone(Zone* zone)
+void Drawable::SetZone(Zone* zone, bool temporary)
 {
     zone_ = zone;
     lastZone_ = zone;
+    temporaryZone_ = temporary;
 }
 
 void Drawable::SetSortValue(float value)
@@ -224,6 +226,13 @@ void Drawable::MarkInView(const FrameInfo& frame, bool mainView)
 {
     if (mainView)
     {
+        // Reset zone assignment now if was temporary
+        if (temporaryZone_)
+        {
+            zone_.Reset();
+            temporaryZone_ = false;
+        }
+        
         viewFrameNumber_ = frame.frameNumber_;
         viewFrame_ = &frame;
         viewCamera_ = frame.camera_;

+ 3 - 1
Engine/Graphics/Drawable.h

@@ -168,7 +168,7 @@ public:
     bool IsOccludee() const { return occludee_; }
     
     /// %Set new zone.
-    void SetZone(Zone* zone);
+    void SetZone(Zone* zone, bool temporary = false);
     /// %Set sorting value.
     void SetSortValue(float value);
     /// Mark in view (either the main camera, or a shadow camera view) this frame.
@@ -284,6 +284,8 @@ protected:
     const FrameInfo* viewFrame_;
     /// Last view's camera. Not safe to dereference.
     Camera* viewCamera_;
+    /// Zone assignment temporary flag.
+    bool temporaryZone_;
 };
 
 inline bool CompareDrawables(Drawable* lhs, Drawable* rhs)

+ 16 - 33
Engine/Graphics/View.cpp

@@ -301,9 +301,8 @@ View::View(Context* context) :
 {
     frame_.camera_ = 0;
     
-    // Create octree query vectors for each thread
+    // Create octree query vector for each thread
     tempDrawables_.Resize(GetSubsystem<WorkQueue>()->GetNumThreads() + 1);
-    tempZones_.Resize(GetSubsystem<WorkQueue>()->GetNumThreads() + 1);
 }
 
 View::~View()
@@ -2220,46 +2219,30 @@ void View::FindZone(Drawable* drawable, unsigned threadIndex)
     int bestPriority = M_MIN_INT;
     Zone* newZone = 0;
     
-    // If bounding box center is in view, can use the visible zones. Else must query via the octree
-    if (camera_->GetFrustum().IsInside(center))
-    {
-        // First check if the last zone remains a conclusive result
-        Zone* lastZone = drawable->GetLastZone();
-        if (lastZone && lastZone->IsInside(center) && (drawable->GetZoneMask() & lastZone->GetZoneMask()) &&
-            lastZone->GetPriority() >= highestZonePriority_)
-            newZone = lastZone;
-        else
-        {
-            for (PODVector<Zone*>::Iterator i = zones_.Begin(); i != zones_.End(); ++i)
-            {
-                int priority = (*i)->GetPriority();
-                if ((*i)->IsInside(center) && (drawable->GetZoneMask() & (*i)->GetZoneMask()) && priority > bestPriority)
-                {
-                    newZone = *i;
-                    bestPriority = priority;
-                }
-            }
-        }
-    }
+    // If bounding box center is in view, the zone assignment is conclusive also for next frames. Otherwise it is temporary
+    // (possibly incorrect) and must be re-evaluated on the next frame
+    bool temporary = !camera_->GetFrustum().IsInside(center);
+    
+    // First check if the last zone remains a conclusive result
+    Zone* lastZone = drawable->GetLastZone();
+    if (lastZone && lastZone->IsInside(center) && (drawable->GetZoneMask() & lastZone->GetZoneMask()) &&
+        lastZone->GetPriority() >= highestZonePriority_)
+        newZone = lastZone;
     else
     {
-        PODVector<Zone*>& tempZones = tempZones_[threadIndex];
-        PointOctreeQuery query(reinterpret_cast<PODVector<Drawable*>&>(tempZones), center, DRAWABLE_ZONE);
-        octree_->GetDrawables(query);
-        
-        bestPriority = M_MIN_INT;
-        for (PODVector<Zone*>::Iterator i = tempZones.Begin(); i != tempZones.End(); ++i)
+        for (PODVector<Zone*>::Iterator i = zones_.Begin(); i != zones_.End(); ++i)
         {
-            int priority = (*i)->GetPriority();
-            if ((*i)->IsInside(center) && (drawable->GetZoneMask() & (*i)->GetZoneMask()) && priority > bestPriority)
+            Zone* zone = *i;
+            int priority = zone->GetPriority();
+            if (zone->IsInside(center) && (drawable->GetZoneMask() & zone->GetZoneMask()) && priority > bestPriority)
             {
-                newZone = *i;
+                newZone = zone;
                 bestPriority = priority;
             }
         }
     }
     
-    drawable->SetZone(newZone);
+    drawable->SetZone(newZone, temporary);
 }
 
 Zone* View::GetZone(Drawable* drawable)

+ 0 - 2
Engine/Graphics/View.h

@@ -222,8 +222,6 @@ private:
     PODVector<Texture2D*> screenBuffers_;
     /// Per-thread octree query results.
     Vector<PODVector<Drawable*> > tempDrawables_;
-    /// Per-thread octree zone query results.
-    Vector<PODVector<Zone*> > tempZones_;
     /// Visible zones.
     PODVector<Zone*> zones_;
     /// Visible geometry objects.