Преглед изворни кода

Optimize container bin lookups

James Urquhart пре 2 година
родитељ
комит
596d13f9a4

+ 0 - 1
Engine/source/T3D/accumulationVolume.cpp

@@ -39,7 +39,6 @@
 #include "console/console.h"
 #include "console/engineAPI.h"
 #include "gfx/gfxTextureHandle.h"
-#include "scene/sceneContainer.h"
 
 #include "math/mPolyhedron.impl.h"
 

+ 1 - 0
Engine/source/collision/convex.cpp

@@ -27,6 +27,7 @@
 #include "core/dataChunker.h"
 #include "collision/collision.h"
 #include "scene/sceneObject.h"
+#include "scene/sceneContainer.h"
 #include "collision/gjk.h"
 #include "collision/concretePolyList.h"
 #include "platform/profiler.h"

+ 1 - 0
Engine/source/forest/editor/forestBrushTool.cpp

@@ -39,6 +39,7 @@
 #include "core/strings/stringUnit.h"
 #include "math/mRandomDeck.h"
 #include "math/mRandomSet.h"
+#include "scene/sceneContainer.h"
 
 
 bool ForestBrushTool::protectedSetSize( void *object, const char *index, const char *data )

+ 1 - 0
Engine/source/forest/editor/forestEditorCtrl.cpp

@@ -30,6 +30,7 @@
 #include "windowManager/platformCursorController.h"
 #include "forest/editor/forestUndo.h"
 #include "gui/worldEditor/undoActions.h"
+#include "scene/sceneContainer.h"
 
 
 IMPLEMENT_CONOBJECT( ForestEditorCtrl );

Разлика између датотеке није приказан због своје велике величине
+ 452 - 278
Engine/source/scene/sceneContainer.cpp


+ 345 - 100
Engine/source/scene/sceneContainer.h

@@ -48,6 +48,10 @@
 #include "console/simObject.h"
 #endif
 
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+
 
 /// @file
 /// SceneObject database.
@@ -61,78 +65,307 @@ class Point3F;
 
 struct RayInfo;
 
+inline U32 dCalcBlocks(U32 value, U32 blockSize)
+{
+   U32 curBlock = value / blockSize;
+   U32 nextBlock = curBlock + 1;
+   return nextBlock * blockSize;
+}
 
-template< typename T >
-class SceneObjectRefBase
+/// Allocates a list of T in blocks of mBlockSize, doesn't shrink unless forced
+template<typename T> class LazyItemAllocator
 {
-   public:
+protected:
+   T* mItems;
+   U32 mSize;
+   U32 mBlockSize;
 
-      /// Object that is referenced in the link.
-      SceneObject* object;
+public:
+   LazyItemAllocator(U32 blockSize) : mItems(NULL), mSize(0), mBlockSize(blockSize)
+   {
+   }
+
+   ~LazyItemAllocator()
+   {
+      if (mItems)
+         delete mItems;
+   }
+
+   inline bool isNull() const
+   {
+      return mItems == NULL;
+   }
+
+   inline T* getPtr()
+   {
+      return mItems;
+   }
+
+   inline bool canFit(U32 count) const
+   {
+      return count < mSize;
+   }
+
+   void realloc(U32 requiredItems, bool force)
+   {
+      U32 requiredSize = dCalcBlocks(requiredItems, mBlockSize);
+      if (mSize < requiredSize || (force && (mSize != requiredSize)))
+      {
+         if (mItems == NULL)
+            mItems = (T*)dMalloc(sizeof(T) * requiredSize);
+         else
+            dRealloc(mItems, sizeof(T) * requiredSize);
 
-      /// Next link in chain of container.
-      T* nextInBin;
+         mSize = requiredSize;
+      }
+   }
+};
 
-      /// Previous link in chain of container.
-      T* prevInBin;
+/// Maintains a set of bin lists for SceneObjects
+/// Use allocList to allocate a list. freeList frees the list, 
+/// and reallocList handles reallocating an existing list handle.
+template<typename T> class SceneContainerBinRefList
+{
+public:
 
-      /// Next link in chain that is associated with #object.
-      T* nextInObj;
-};
+   /// Index type for a bin reference
+   typedef T BinValue;
 
+   /// Type for number of bins used by a reference list
+   typedef T BinCount;
 
-/// Reference to a scene object.
-class SceneObjectRef : public SceneObjectRefBase< SceneObjectRef > {};
+   /// Handle used for bin lists
+   typedef U32 ListHandle;
 
+   // Defaults
+   enum
+   {
+      /// Chunk size of reference lists
+      ReserveSize = 20000,
+      
+      /// Chunk count of reference list entries
+      DataReserveSize = 20000*4,
 
-/// A contextual hint passed to the polylist methods which
-/// allows it to return the appropriate geometry.
-enum PolyListContext
-{
-   /// A hint that the polyist is intended 
-   /// for collision testing.
-   PLC_Collision,
-   
-   /// A hint that the polyist is for decal
-   /// geometry generation.
-   PLC_Decal,
-
-   /// A hint that the polyist is used for
-   /// selection from an editor or other tool.
-   PLC_Selection,
-
-   /// A hint that the polylist is used for
-   /// building a representation of the environment
-   /// used for navigation.
-   PLC_Navigation,
-
-   /// A hint that the polyist will be used
-   /// to export geometry and would like to have
-   /// texture coords and materials.   
-   PLC_Export
-};
+      /// Number of unused references when compaction should occur
+      CompactionThreshold = 4096
+   };
 
+protected:
 
-/// For simple queries.  Simply creates a vector of the objects
-class SimpleQueryList
-{
-   public:
+#pragma pack(2)
+   struct BinList
+   {
+      // Start reference
+      U32 startValue;
+
+      /// References allocated
+      BinCount numValues;
+   };
+#pragma pack()
+
+   /// List of bin lists
+   Vector<BinList> mBinLists;
+
+   /// Current bin values
+   LazyItemAllocator<BinValue> mBinValues;
+
+   /// Temporary compaction list
+   LazyItemAllocator<BinValue> mCompactData;
+
+   /// Offset (+1) of first free mBinLists
+   U32 mFreeListStart;
+
+   /// Chunks of mRefList to allocate
+   U32 mListChunkSize;
+
+   /// Current used ref count (in mBinValues)
+   U32 mUsedValues;
 
-      Vector< SceneObject* > mList;
+   /// Current reference index we are writing
+   U32 mLastValueIdx;
 
-      SimpleQueryList() 
+public:
+
+   SceneContainerBinRefList() :
+      mBinValues(DataReserveSize),
+      mCompactData(DataReserveSize),
+      mFreeListStart(0),
+      mListChunkSize(ReserveSize),
+      mUsedValues(0),
+      mLastValueIdx(0)
+   {
+   }
+
+   ~SceneContainerBinRefList()
+   {
+   }
+
+   /// Resets the SceneContainerBinRefList
+   void clear()
+   {
+      mBinLists.clear();
+      mBinValues.realloc(0, true);
+      mCompactData.realloc(0, true);
+
+      mFreeListStart = 0;
+      mUsedValues = 0;
+      mLastValueIdx = 0;
+   }
+
+   /// Gets a BinValue list based on a ListHandle.
+   BinValue* getValues(ListHandle handle, U32& numValues)
+   {
+      if (handle == 0)
       {
-         VECTOR_SET_ASSOCIATION( mList );
+         numValues = 0;
+         return NULL;
       }
 
-      void insertObject( SceneObject* obj ) { mList.push_back(obj); }
-      static void insertionCallback( SceneObject* obj, void* key )
+      U32 realIDX = handle - 1;
+      BinList& list = mBinLists[realIDX];
+      numValues = list.numValues;
+
+      return mBinValues.getPtr() + list.startValue;
+   }
+
+protected:
+
+   /// Gets a free entry from the free entry list.
+   bool getFreeEntry(ListHandle& outIDX)
+   {
+      if (mFreeListStart > 0)
       {
-         SimpleQueryList* pList = reinterpret_cast< SimpleQueryList* >( key );
-         pList->insertObject( obj );
+         outIDX = mFreeListStart - 1;
+         mFreeListStart = mBinLists[outIDX].startValue;
+         return true;
+      }
+
+      return false;
+   }
+
+public:
+
+   /// Allocates a new ListHandle with numValue values copied from values.
+   ListHandle allocList(BinCount numValues, BinValue* values)
+   {
+      BinList list;
+      ListHandle retHandle = 0;
+      
+      list.numValues = numValues;
+      list.startValue = mLastValueIdx;
+
+      mLastValueIdx += numValues;
+      mUsedValues += numValues;
+
+      // Use free list or push new entry
+      if (!getFreeEntry(retHandle))
+      {
+         mBinLists.push_back(list);
+         retHandle = mBinLists.size();
+      }
+      else
+      {
+         mBinLists[retHandle++] = list;
+      }
+
+      // Manage lists
+      mBinLists.reserve(dCalcBlocks(mBinLists.size(), mListChunkSize));
+      mBinValues.realloc(mLastValueIdx, false);
+
+      // Copy data
+      dCopyArray(mBinValues.getPtr() + list.startValue, values, numValues);
+      return retHandle;
+   }
+
+   /// Reallocates an existing ListHandle.
+   /// Existing memory will be used if numValues is the same, 
+   /// otherwise new list memory will be allocated.
+   void reallocList(ListHandle handle, BinCount numValues, BinValue* values)
+   {
+      if (handle == 0)
+         return;
+
+      U32 realIDX = handle - 1;
+      BinList& list = mBinLists[realIDX];
+
+      if (list.numValues != numValues)
+      {
+         // Allocate new entry
+         mUsedValues -= list.numValues;
+         mUsedValues += numValues;
+
+         list.numValues = numValues;
+         list.startValue = mLastValueIdx;
+         
+         mLastValueIdx += numValues;
+         mBinValues.realloc(mLastValueIdx, false);
       }
-};
 
+      dCopyArray(mBinValues.getPtr() + list.startValue, values, numValues);
+   }
+
+   /// Frees an existing ListHandle
+   void freeList(ListHandle handle)
+   {
+      if (handle == 0)
+         return;
+
+      U32 realIDX = handle - 1;
+      BinList& list = mBinLists[realIDX];
+
+      mUsedValues -= list.numValues;
+      list.numValues = 0;
+
+      // Add to free list
+      list.startValue = mFreeListStart;
+      // Next
+      mFreeListStart = handle;
+
+      AssertFatal(mLastValueIdx >= mUsedValues, "ref overflow");
+
+      // Automatically compact if we have enough free items
+      if ((mLastValueIdx - mUsedValues) > CompactionThreshold)
+      {
+         compact();
+      }
+   }
+
+   /// Compacts the BinValue lists. 
+   /// This will automatically be called by freeList usually
+   /// once CompactionThreshold list values have been freed.
+   void compact()
+   {
+      if (mBinValues.isNull())
+         return;
+
+      mCompactData.realloc(mUsedValues, false);
+      BinValue* outPtr = mCompactData.getPtr();
+      U32 newOutStart = 0;
+
+      // Copy list values to scratch list
+      for (BinList& list : mBinLists)
+      {
+         if (list.numValues == 0)
+            continue;
+
+         const BinValue* inPtr = mBinValues.getPtr() + list.startValue;
+         dCopyArray(outPtr, inPtr, list.numValues);
+
+         // Update counters
+         list.startValue = newOutStart;
+         outPtr += list.numValues;
+         newOutStart += list.numValues;
+      }
+
+      AssertFatal(newOutStart == mUsedValues, "value count mismatch");
+
+      mLastValueIdx = mUsedValues;
+      mBinValues.realloc(mLastValueIdx, true);
+
+      const U32 copySize = newOutStart * sizeof(BinValue);
+      memcpy(mBinValues.getPtr(), mCompactData.getPtr(), copySize);
+   }
+};
 
 //----------------------------------------------------------------------------
 
@@ -141,6 +374,7 @@ class SimpleQueryList
 /// ScenceContainer implements a grid-based spatial subdivision for the contents of a scene.
 class SceneContainer
 {
+   public:
       enum CastRayType
       {
          CollisionGeometry,
@@ -149,14 +383,16 @@ class SceneContainer
 
    public:
 
-      struct Link
-      {
-         Link* mNext;
-         Link* mPrev;
-         Link();
-         void unlink();
-         void linkAfter(Link* ptr);
-      };
+      typedef SceneContainerBinRefList<U16> BinValueList;
+
+      /// Base object list type, should conform to Vector
+      typedef Vector<SceneObject*> ObjectList;
+
+      /// Type to reference a bin list
+      typedef U32 BinListIndex;
+
+      /// Type to reference a bin. This should be changed if there are more than 65536 bins.
+      typedef U16 BinRef;
 
       struct CallbackInfo 
       {
@@ -169,9 +405,6 @@ class SceneContainer
 
    private:
 
-      Link mStart;
-      Link mEnd;
-
       /// Container queries based on #mCurrSeqKey are are not re-entrant;
       /// this is used to detect when it happens.
       bool mSearchInProgress;
@@ -179,23 +412,40 @@ class SceneContainer
       /// Current sequence key.
       U32 mCurrSeqKey;
 
-      SceneObjectRef* mFreeRefPool;
-      Vector< SceneObjectRef* > mRefPoolBlocks;
+      /// Binned object lists
+      ObjectList* mBinArray;
 
-      SceneObjectRef* mBinArray;
-      SceneObjectRef mOverflowBin;
+      /// Large objects
+      ObjectList mOverflowBin;
+
+      /// Every single object not categorized by bin
+      ObjectList mGlobalList;
 
       /// A vector that contains just the water and physical zone
       /// object types which is used to optimize searches.
-      Vector< SceneObject* > mWaterAndZones;
+      ObjectList mWaterAndZones;
 
       /// Vector that contains just the terrain objects in the container.
-      Vector< SceneObject* > mTerrains;
+      ObjectList mTerrains;
+
+      /// Temporary list for value insert
+      Vector<BinValueList::BinValue> mBinValueList;
+
+      /// Maintains a list of bin references
+      BinValueList mBinRefLists;
 
-      static const U32 csmNumBins;
+   public:
+      /// World units of side of bin
       static const F32 csmBinSize;
-      static const F32 csmTotalBinSize;
-      static const U32 csmRefPoolBlockSize;
+      /// World units of entire side of bin grid
+      static const F32 csmTotalAxisBinSize;
+
+      /// Size of grid on any axis
+      static const U32 csmNumAxisBins;
+      /// Index used to store overflow entries
+      static const U32 csmOverflowBinIdx;
+      /// Total number of bin lists to allocate
+      static const U32 csmTotalNumBins;
 
    public:
 
@@ -273,9 +523,6 @@ class SceneContainer
       /// @param object A SceneObject.
       bool removeObject( SceneObject* object );
 
-      void addRefPoolBlock();
-      SceneObjectRef* allocateObjectRef();
-      void freeObjectRef(SceneObjectRef*);
       void insertIntoBins( SceneObject* object );
       void removeFromBins( SceneObject* object );
 
@@ -283,7 +530,7 @@ class SceneContainer
       /// where it came from.  The overloaded insertInto is so we don't calculate
       /// the ranges twice.
       void checkBins( SceneObject* object );
-      void insertIntoBins(SceneObject*, U32, U32, U32, U32);
+      void insertIntoBins(SceneObject*, const SceneBinRange& range);
 
       void initRadiusSearch(const Point3F& searchPoint,
          const F32      searchRadius,
@@ -308,40 +555,38 @@ class SceneContainer
       void _findSpecialObjects( const Vector< SceneObject* >& vector, U32 mask, FindCallback, void *key = NULL );
       void _findSpecialObjects( const Vector< SceneObject* >& vector, const Box3F &box, U32 mask, FindCallback callback, void *key = NULL );   
 
+
+public:
+
+      static inline void getBinRange( const Point2F minExtents, const Point2F maxExtents, SceneBinRange& outRange )
+      {
+         U32 outMin, outMax;
+         getBinRange(minExtents.x, maxExtents.x, outMin, outMax);
+         outRange.minCoord[0] = outMin;
+         outRange.maxCoord[0] = outMax;
+         getBinRange(minExtents.y, maxExtents.y, outMin, outMax);
+         outRange.minCoord[1] = outMin;
+         outRange.maxCoord[1] = outMax;
+      }
+
       static void getBinRange( const F32 min, const F32 max, U32& minBin, U32& maxBin );
 public:
       Vector<SimObjectPtr<SceneObject>*>& getRadiusSearchList() { return mSearchList; }
-};
 
-//-----------------------------------------------------------------------------
-
-extern SceneContainer gServerContainer;
-extern SceneContainer gClientContainer;
+};
 
 //-----------------------------------------------------------------------------
 
-inline void SceneContainer::freeObjectRef(SceneObjectRef* trash)
+inline bool SceneBinRange::shouldOverflow() const
 {
-   trash->object = NULL;
-   trash->nextInBin = NULL;
-   trash->prevInBin = NULL;
-   trash->nextInObj = mFreeRefPool;
-   mFreeRefPool     = trash;
+   return
+      ((getWidth() + 1) >= SceneContainer::csmNumAxisBins ||
+         ((getHeight() + 1) >= SceneContainer::csmNumAxisBins));
 }
 
 //-----------------------------------------------------------------------------
 
-inline SceneObjectRef* SceneContainer::allocateObjectRef()
-{
-   if( mFreeRefPool == NULL )
-      addRefPoolBlock();
-   AssertFatal( mFreeRefPool!=NULL, "Error, should always have a free reference here!" );
-
-   SceneObjectRef* ret = mFreeRefPool;
-   mFreeRefPool = mFreeRefPool->nextInObj;
-
-   ret->nextInObj = NULL;
-   return ret;
-}
+extern SceneContainer gServerContainer;
+extern SceneContainer gClientContainer;
 
-#endif // !_SCENECONTAINER_H_
+#endif // !_SCENECONTAINER_H_

+ 4 - 0
Engine/source/scene/sceneManager.h

@@ -59,6 +59,10 @@
 #include "core/util/tSignal.h"
 #endif
 
+#ifndef _SCENECONTAINER_H_
+#include "scene/sceneContainer.h"
+#endif
+
 
 class LightManager;
 class SceneRootZone;

+ 3 - 8
Engine/source/scene/sceneObject.cpp

@@ -126,18 +126,12 @@ SceneObject::SceneObject()
 
    mContainerSeqKey = 0;
 
-   mBinRefHead = NULL;
-
    mSceneManager = NULL;
 
    mNumCurrZones = 0;
    mZoneRefHead = NULL;
    mZoneRefDirty = false;
 
-   mBinMinX = 0xFFFFFFFF;
-   mBinMaxX = 0xFFFFFFFF;
-   mBinMinY = 0xFFFFFFFF;
-   mBinMaxY = 0xFFFFFFFF;
    mLightPlugin = NULL;
 
    mMount.object = NULL;
@@ -172,13 +166,14 @@ SceneObject::SceneObject()
 
 SceneObject::~SceneObject()
 {
-   AssertFatal( mZoneRefHead == NULL && mBinRefHead == NULL,
+   AssertFatal(mContainer == NULL,
+      "SceneObject::~SceneObject - Object still in container!");
+   AssertFatal( mZoneRefHead == NULL,
       "SceneObject::~SceneObject - Object still linked in reference lists!");
    AssertFatal( !mSceneObjectLinks,
       "SceneObject::~SceneObject() - object is still linked to SceneTrackers" );
 
    mAccuTex = NULL;
-   unlink();
 }
 
 //-----------------------------------------------------------------------------

+ 28 - 16
Engine/source/scene/sceneObject.h

@@ -52,10 +52,6 @@
 #include "T3D/gameBase/processList.h"
 #endif
 
-#ifndef _SCENECONTAINER_H_
-#include "scene/sceneContainer.h"
-#endif
-
 #ifndef _GFXDEVICE_H_
 #include "gfx/gfxDevice.h"
 #endif
@@ -74,6 +70,11 @@
 #include "T3D/assets/GameObjectAsset.h"
 #endif
 
+#ifndef _SCENEQUERY_UTIL_H_
+#include "scene/sceneQueryUtil.h"
+#endif
+
+
 class SceneManager;
 class SceneRenderState;
 class SceneTraversalState;
@@ -87,7 +88,7 @@ class SFXAmbience;
 
 struct ObjectRenderInst;
 struct Move;
-
+struct SceneRayHelper;
 
 /// A 3D object.
 ///
@@ -112,7 +113,7 @@ struct Move;
 ///
 /// @see http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3217
 ///      for a copy of Melv's example.
-class SceneObject : public NetObject, private SceneContainer::Link, public ProcessObject
+class SceneObject : public NetObject, public ProcessObject
 {
    public:
 
@@ -123,6 +124,7 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
       friend class SceneZoneSpaceManager;
       friend class SceneCullingState; // _getZoneRefHead
       friend class SceneObjectLink; // mSceneObjectLinks
+      friend struct SceneRayHelper;
 
       enum 
       {
@@ -223,10 +225,22 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
       /// @{
 
       /// Bidirectional link between a zone manager and its objects.
-      struct ZoneRef : public SceneObjectRefBase< ZoneRef >
+      struct ZoneRef
       {
          /// ID of zone.
          U32 zone;
+
+         /// Object that is referenced in the link.
+         SceneObject* object;
+
+         /// Next link in chain of container.
+         ZoneRef* nextInBin;
+
+         /// Previous link in chain of container.
+         ZoneRef* prevInBin;
+
+         /// Next link in chain that is associated with #object.
+         ZoneRef* nextInObj;
       };
 
       /// Iterator over the zones that the object is assigned to.
@@ -360,16 +374,14 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
       /// Container database that the object is assigned to.
       SceneContainer* mContainer;
 
-      /// SceneContainer sequence key.
-      U32 mContainerSeqKey;
+      /// Assigned container index
+      U32 mContainerIndex;
 
-      ///
-      SceneObjectRef* mBinRefHead;
+      /// Lookup Info
+      SceneBinListLookup mContainerLookup;
 
-      U32 mBinMinX;
-      U32 mBinMaxX;
-      U32 mBinMinY;
-      U32 mBinMaxY;
+      /// SceneContainer sequence key.
+      U32 mContainerSeqKey;
 
       /// Returns the container sequence key.
       U32 getContainerSeqKey() const { return mContainerSeqKey; }
@@ -464,7 +476,7 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
       virtual void enableCollision();
 
       /// Returns true if collisions are enabled
-      bool isCollisionEnabled() const { return mCollisionCount == 0; }
+      inline bool isCollisionEnabled() const { return mCollisionCount == 0; }
 
       /// This gets called when an object collides with this object.
       /// @param   object   Object colliding with this object

+ 115 - 0
Engine/source/scene/sceneQueryUtil.h

@@ -0,0 +1,115 @@
+#ifndef _SCENEQUERY_UTIL_H_
+#define _SCENEQUERY_UTIL_H_
+
+/// A contextual hint passed to the polylist methods which
+/// allows it to return the appropriate geometry.
+enum PolyListContext
+{
+   /// A hint that the polyist is intended 
+   /// for collision testing.
+   PLC_Collision,
+
+   /// A hint that the polyist is for decal
+   /// geometry generation.
+   PLC_Decal,
+
+   /// A hint that the polyist is used for
+   /// selection from an editor or other tool.
+   PLC_Selection,
+
+   /// A hint that the polylist is used for
+   /// building a representation of the environment
+   /// used for navigation.
+   PLC_Navigation,
+
+   /// A hint that the polyist will be used
+   /// to export geometry and would like to have
+   /// texture coords and materials.   
+   PLC_Export
+};
+
+struct SceneBinRange
+{
+   U16 minCoord[2];
+   U16 maxCoord[2];
+
+   inline U32 getWidth() const
+   {
+      return maxCoord[0] - minCoord[0];
+   }
+
+   inline U32 getHeight() const
+   {
+      return maxCoord[1] - minCoord[1];
+   }
+
+   inline void setGlobal()
+   {
+      minCoord[0] = 0;
+      minCoord[1] = 0;
+      maxCoord[0] = 0xFFFF;
+      maxCoord[1] = 0xFFFF;
+   }
+
+   static SceneBinRange makeFromBin(U32 minX, U32 maxX, U32 minY, U32 maxY)
+   {
+      SceneBinRange outRange;
+      outRange.minCoord[0] = minX;
+      outRange.minCoord[1] = minY;
+      outRange.maxCoord[0] = maxX;
+      outRange.maxCoord[1] = maxY;
+      return outRange;
+   }
+
+   static SceneBinRange makeGlobal()
+   {
+      SceneBinRange outRange;
+      outRange.setGlobal();
+      return outRange;
+   }
+
+   inline bool isGlobal() const
+   {
+      return minCoord[0] == 0 &&
+         minCoord[0] == 0 &&
+         maxCoord[0] == 0xFFFF &&
+         maxCoord[1] == 0xFFFF;
+   }
+
+   inline bool shouldOverflow() const;
+
+   inline bool operator==(const SceneBinRange& other) const
+   {
+      return memcmp(minCoord, other.minCoord, sizeof(minCoord)) == 0 &&
+         memcmp(maxCoord, other.maxCoord, sizeof(maxCoord)) == 0;
+   }
+};
+
+/// Lookup for bins assigned to SceneObject
+struct SceneBinListLookup
+{
+   SceneBinRange mRange; ///< Range object is placed in
+   U32 mListHandle;      ///< Handle for ref list
+};
+
+/// For simple queries.  Simply creates a vector of the objects
+class SimpleQueryList
+{
+public:
+
+   Vector< SceneObject* > mList;
+
+   SimpleQueryList()
+   {
+      VECTOR_SET_ASSOCIATION(mList);
+   }
+
+   void insertObject(SceneObject* obj) { mList.push_back(obj); }
+   static void insertionCallback(SceneObject* obj, void* key)
+   {
+      SimpleQueryList* pList = reinterpret_cast<SimpleQueryList*>(key);
+      pList->insertObject(obj);
+   }
+};
+
+#endif

+ 1 - 0
Engine/source/scene/sceneTracker.cpp

@@ -21,6 +21,7 @@
 //-----------------------------------------------------------------------------
 
 #include "scene/sceneTracker.h"
+#include "scene/sceneContainer.h"
 
 
 //=============================================================================

+ 1 - 1
Engine/source/scene/zones/sceneZoneSpaceManager.cpp

@@ -25,9 +25,9 @@
 
 #include "platform/profiler.h"
 #include "platform/platformMemory.h"
-#include "scene/sceneContainer.h"
 #include "scene/zones/sceneRootZone.h"
 #include "scene/zones/sceneZoneSpace.h"
+#include "scene/sceneContainer.h"
 
 
 // Uncomment to enable verification code for debugging.  This slows the

Неке датотеке нису приказане због велике количине промена