sceneZoneSpaceManager.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _SCENEZONESPACEMANAGER_H_
  23. #define _SCENEZONESPACEMANAGER_H_
  24. #ifndef _SCENEOBJECT_H_
  25. #include "scene/sceneObject.h"
  26. #endif
  27. #ifndef _TVECTOR_H_
  28. #include "core/util/tVector.h"
  29. #endif
  30. #ifndef _TSIGNAL_H_
  31. #include "core/util/tSignal.h"
  32. #endif
  33. #ifndef _DATACHUNKER_H_
  34. #include "core/dataChunker.h"
  35. #endif
  36. #ifndef _SCENECONTAINER_H_
  37. #include "scene/sceneContainer.h"
  38. #endif
  39. class SceneContainer;
  40. class SceneRootZone;
  41. class SceneZoneSpace;
  42. class Zone;
  43. /// Object that manages zone spaces in a scene.
  44. class SceneZoneSpaceManager
  45. {
  46. public:
  47. friend class SceneZoneSpace; // mZoneLists
  48. friend class Zone;
  49. /// A signal used to notify that the zone setup of the scene has changed.
  50. ///
  51. /// @note If you use this signal to maintain state that depends on the zoning
  52. /// setup, it's best to not immediately update the sate in response to this
  53. /// signal. The reason is that during loading and editing, the signal may
  54. /// be fired a lot and continuously updating dependent data may waste a lot
  55. /// of time.
  56. typedef Signal< void( SceneZoneSpaceManager* ) > ZoningChangedSignal;
  57. typedef SceneContainerBinRefList<U32> ZoneValueList;
  58. typedef SceneContainerBinRefList<U32>::ValueIterator ObjectZoneValueIterator;
  59. enum : U32
  60. {
  61. /// Zone ID of the exterior zone.
  62. RootZoneId = 0,
  63. /// Constant to indicate an invalid zone ID.
  64. InvalidZoneId = 0xFFFFFFFF,
  65. };
  66. class ZoneObjectList
  67. {
  68. protected:
  69. friend class SceneZoneSpaceManager;
  70. SceneObject* mManager;
  71. Vector<SceneObject*> mObjects;
  72. public:
  73. ZoneObjectList(SceneObject* manager) : mManager(manager) { ; }
  74. inline SceneObject* getManager() const { return mManager; }
  75. inline Vector<SceneObject*>& getObjects() { return mObjects; }
  76. };
  77. protected:
  78. /// The root and outdoor zone of the scene.
  79. SceneRootZone* mRootZone;
  80. /// Scene container that holds the zone spaces we are managing.
  81. SceneContainer* mContainer;
  82. /// Collection of objects that manage zones.
  83. Vector< SceneZoneSpace* > mZoneSpaces;
  84. /// Total number of zones that have been allocated in the scene.
  85. U32 mNumTotalAllocatedZones;
  86. /// Number of zone IDs that are in active use.
  87. U32 mNumActiveZones;
  88. /// Object list for each zone in the scene.
  89. /// First entry in the list points back to the zone manager.
  90. Vector< ZoneObjectList* > mZoneLists;
  91. /// Free zone pool
  92. Vector< ZoneObjectList* > mZoneListPool;
  93. /// Pool for allocating object zone lists
  94. ZoneValueList mObjectZoneLists;
  95. /// Vector used repeatedly for zone space queries on the container.
  96. mutable Vector< SceneObject* > mZoneSpacesQueryList;
  97. struct TempZoneRecord
  98. {
  99. SceneZoneSpace* space;
  100. U32 startZone;
  101. U32 numZones;
  102. };
  103. Vector<TempZoneRecord> mTempObjectZones;
  104. /// @name Dirty Lists
  105. /// Updating the zoning state of a scene is done en block rather than
  106. /// individually for each object as it changes transforms or size.
  107. /// @{
  108. /// Area of the scene that needs to be rezoned.
  109. Box3F mDirtyArea;
  110. /// List of zone spaces that have changed state and need updating.
  111. Vector< SceneZoneSpace* > mDirtyZoneSpaces;
  112. /// List of objects (non-zone spaces) that have changed state and need
  113. /// updating.
  114. Vector< SceneObject* > mDirtyObjects;
  115. /// @}
  116. /// Check to see if we have accumulated a lot of unallocate zone IDs and if so,
  117. /// compact the zoning lists by reassigning IDs.
  118. ///
  119. /// @warn This method may alter all zone IDs in the scene!
  120. void _compactZonesCheck();
  121. /// Return the index into #mZoneSpaces for the given object or -1 if
  122. /// @object is not a zone manager.
  123. S32 _getZoneSpaceIndex( SceneZoneSpace* object ) const;
  124. /// Attach zoning state to the given object.
  125. void _zoneInsert( SceneObject* object, bool queryListInitialized = false );
  126. /// Detach zoning state from the given object.
  127. void _zoneRemove( SceneObject* object, bool freeList = true );
  128. /// Realloc zoning state to the given object.
  129. void _zoneRealloc(SceneObject* object, bool queryListInitialized = false);
  130. /// Sets the entire zone list for an object
  131. void _setObjectZoneList( SceneObject* object, U32 numZones, U32* zoneList );
  132. /// Clear all objects assigned to the given zone.
  133. /// @note This does not remove the first link in the zone list which is the link
  134. /// back to the zone manager.
  135. void _clearZoneList( U32 zoneId );
  136. /// Find the given object in the zone list of the given zone.
  137. bool _isInZoneList( U32 zoneId, SceneObject* object ) const;
  138. /// Rezone all objects in the given area.
  139. void _rezoneObjects( const Box3F& area );
  140. /// Update the zoning state of the given object.
  141. void _rezoneObject( SceneObject* object );
  142. /// Fill #mZoneSpacesQueryList with all ZoneObjectType objects in the given area.
  143. void _queryZoneSpaces( const Box3F& area ) const;
  144. ZoneObjectList* _allocZoneList(SceneZoneSpace* space);
  145. void _freeZoneList(ZoneObjectList* list);
  146. public:
  147. SceneZoneSpaceManager( SceneContainer* container );
  148. ~SceneZoneSpaceManager();
  149. /// Bring the zoning state of the scene up to date. This will cause objects
  150. /// that have moved or have been resized to be rezoned and will updated regions
  151. /// of the scene that had their zoning setup changed.
  152. ///
  153. /// @note This method depends on proper use of notifyObjectChanged().
  154. void updateZoningState();
  155. /// @name Objects
  156. /// @{
  157. /// Add zoning state to the given object.
  158. void registerObject( SceneObject* object );
  159. /// Remove the given object from the zoning state.
  160. void unregisterObject( SceneObject* object );
  161. /// Let the manager know that state relevant to zoning of the given
  162. /// object has changed.
  163. void notifyObjectChanged( SceneObject* object );
  164. /// Update the zoning state of the given object.
  165. void updateObject( SceneObject* object );
  166. /// @}
  167. /// @name Zones
  168. /// @{
  169. /// Return the root zone of the scene.
  170. SceneRootZone* getRootZone() const { return mRootZone; }
  171. /// Register a zone manager.
  172. ///
  173. /// @param object SceneZoneSpace object that contains zones.
  174. /// @param numZones Number of zones that @a object contains.
  175. void registerZones( SceneZoneSpace* object, U32 numZones );
  176. /// Unregister a zone manager.
  177. ///
  178. /// @param object Object that contains zones.
  179. void unregisterZones( SceneZoneSpace* object );
  180. /// Return true if the given ID belongs to a currently registered zone.
  181. bool isValidZoneId( const U32 zoneId ) const
  182. {
  183. return ( zoneId < mNumTotalAllocatedZones && mZoneLists[ zoneId ] );
  184. }
  185. /// Get the scene object that contains the zone with the given ID.
  186. ///
  187. /// @param zoneId ID of the zone. Must be valid.
  188. /// @return The zone space that has registered the given zone.
  189. SceneZoneSpace* getZoneOwner( const U32 zoneId ) const
  190. {
  191. AssertFatal( isValidZoneId( zoneId ), "SceneManager::getZoneOwner - Invalid zone ID!");
  192. ZoneObjectList* list = mZoneLists[zoneId];
  193. return ( SceneZoneSpace* )(list ? list->getManager() : NULL);
  194. }
  195. Vector<SceneObject*>* getZoneObjects(const U32 zoneId) const
  196. {
  197. AssertFatal(isValidZoneId(zoneId), "SceneManager::getZoneOwner - Invalid zone ID!");
  198. ZoneObjectList* list = mZoneLists[zoneId];
  199. return (list ? &list->getObjects() : NULL);
  200. }
  201. /// Return the total number of zones in the scene.
  202. U32 getNumZones() const { return mNumTotalAllocatedZones; }
  203. /// Return the effective amount of used zone IDs in the scene.
  204. U32 getNumActiveZones() const { return mNumActiveZones; }
  205. /// Return the total number of objects in the scene that manage zones.
  206. U32 getNumZoneSpaces() const { return mZoneSpaces.size(); }
  207. /// Find the zone that contains the given point.
  208. ///
  209. /// Note that the result can be <em>any</em> zone containing the given
  210. /// point.
  211. void findZone( const Point3F& point, SceneZoneSpace*& outZoneSpace, U32& outZoneID ) const;
  212. /// Collect the IDs of all zones that overlap the given area.
  213. ///
  214. /// @param area AABB of scene space to query.
  215. /// @param outZones IDs of all overlapped zones are added to this vector.
  216. ///
  217. /// @return Number of zones that have been added to @a outZones. Always at least
  218. /// 1 as at least the outdoor zone always overlaps the given area (though if another zone
  219. /// manager fully contains @a area, the outdoor zone will not be added to the list).
  220. U32 findZones( const Box3F& area, Vector< U32 >& outZones ) const;
  221. static ZoningChangedSignal& getZoningChangedSignal()
  222. {
  223. static ZoningChangedSignal sSignal;
  224. return sSignal;
  225. }
  226. /// @name Debugging
  227. /// @{
  228. /// Verify the current zoning state. This makes sure all the connectivity
  229. /// information and all the zone assignments appear to be correct.
  230. void verifyState();
  231. /// Dump the current state of all zone spaces in the scene to the console.
  232. /// @param update If true, zoning state states are updated first; if false, zoning is
  233. /// dumped as is.
  234. void dumpZoneStates( bool update = true );
  235. /// @}
  236. inline U32* getZoneIDS(SceneObject* object, U32& numZones)
  237. {
  238. return mObjectZoneLists.getValues(object->mZoneListHandle, numZones);
  239. }
  240. ObjectZoneValueIterator makeObjectZoneValueIterator(SceneObject* obj)
  241. {
  242. return mObjectZoneLists.getValueIterator(obj->mZoneListHandle);
  243. }
  244. void getObjectZoneValueIterators(SceneObject* obj, ObjectZoneValueIterator& start, ObjectZoneValueIterator& end)
  245. {
  246. mObjectZoneLists.getValueIterators(obj->mZoneListHandle, start, end);
  247. }
  248. /// @}
  249. };
  250. #endif // !_SCENEZONESPACEMANAGER_H_