Torque3D Documentation / _generateds / sceneZoneSpaceManager.h

sceneZoneSpaceManager.h

Engine/source/scene/zones/sceneZoneSpaceManager.h

More...

Classes:

class

Object that manages zone spaces in a scene.

class

Iterator for the contents of a given zone.

Detailed Description

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _SCENEZONESPACEMANAGER_H_
 25#define _SCENEZONESPACEMANAGER_H_
 26
 27#ifndef _SCENEOBJECT_H_
 28#include "scene/sceneObject.h"
 29#endif
 30
 31#ifndef _TVECTOR_H_
 32#include "core/util/tVector.h"
 33#endif
 34
 35#ifndef _TSIGNAL_H_
 36#include "core/util/tSignal.h"
 37#endif
 38
 39#ifndef _DATACHUNKER_H_
 40#include "core/dataChunker.h"
 41#endif
 42
 43
 44
 45class SceneContainer;
 46class SceneRootZone;
 47class SceneZoneSpace;
 48
 49
 50/// Object that manages zone spaces in a scene.
 51class SceneZoneSpaceManager
 52{
 53   public:
 54
 55      class ZoneContentIterator;
 56
 57      friend class SceneZoneSpace; // mZoneLists
 58      friend class ZoneContentIterator; // mZoneLists
 59
 60      /// A signal used to notify that the zone setup of the scene has changed.
 61      ///
 62      /// @note If you use this signal to maintain state that depends on the zoning
 63      ///   setup, it's best to not immediately update the sate in response to this
 64      ///   signal.  The reason is that during loading and editing, the signal may
 65      ///   be fired a lot and continuously updating dependent data may waste a lot
 66      ///   of time.
 67      typedef Signal< void( SceneZoneSpaceManager* ) > ZoningChangedSignal;
 68
 69      enum : <a href="/coding/file/types_8h/#types_8h_1ac3df7cf3c8cb172a588adec881447d68">U32</a>
 70      {
 71         /// Zone ID of the exterior zone.
 72         RootZoneId = 0,
 73
 74         /// Constant to indicate an invalid zone ID.
 75         InvalidZoneId = 0xFFFFFFFF,
 76      };
 77
 78      /// Iterator for the contents of a given zone.
 79      class ZoneContentIterator
 80      {
 81         public:
 82
 83            ZoneContentIterator( SceneZoneSpaceManager* manager, S32 zoneId, bool upToDate = true )
 84            {
 85               AssertFatal( zoneId < manager->getNumZones(), "SceneZoneSpaceManager::ZoneContentIterator - Zone ID out of range" );
 86
 87               if( upToDate )
 88               {
 89                  // Since zoning is updated lazily, the zone contents may actually
 90                  // be out of date.  Force an update by triggering rezoning on the
 91                  // zone object.  This is brute-force but this iterator is not meant
 92                  // to be used for high-frequency code anyway.
 93                  //
 94                  // Use the area-based rezoning so that we can also properly iterate
 95                  // over the contents of SceneRootZone.
 96                  manager->_rezoneObjects( ( ( SceneObject* ) manager->getZoneOwner( zoneId ) )->getWorldBox() );
 97               }
 98
 99               mCurrent = manager->mZoneLists[ zoneId ]->nextInBin; // Skip zone object entry.
100            }
101
102            bool isValid() const
103            {
104               return ( mCurrent != NULL );
105            }
106            bool operator!() const
107            {
108               return ( mCurrent == NULL );
109            }
110            ZoneContentIterator& operator++()
111            {
112               if( mCurrent )
113                  mCurrent = mCurrent->nextInBin;
114               return *this;
115            }
116            ZoneContentIterator& operator--()
117            {
118               if( mCurrent )
119                  mCurrent = mCurrent->prevInBin;
120               return *this;
121            }
122            SceneObject* operator*() const
123            {
124               AssertFatal( mCurrent != NULL, "SceneManager::ZoneContentIterator::operator* - Invalid iterator" );
125               return mCurrent->object;
126            }
127            SceneObject* operator->() const
128            {
129               AssertFatal( mCurrent != NULL, "SceneManager::ZoneContentIterator::operator-> - Invalid iterator" );
130               return mCurrent->object;
131            }
132
133         private:
134
135            SceneObject::ZoneRef* mCurrent;
136      };
137
138   protected:
139
140      /// The root and outdoor zone of the scene.
141      SceneRootZone* mRootZone;
142
143      /// Scene container that holds the zone spaces we are managing.
144      SceneContainer* mContainer;
145
146      /// Collection of objects that manage zones.
147      Vector< SceneZoneSpace*> mZoneSpaces;
148
149      /// Total number of zones that have been allocated in the scene.
150      U32 mNumTotalAllocatedZones;
151
152      /// Number of zone IDs that are in active use.
153      U32 mNumActiveZones;
154
155      /// Object list for each zone in the scene.
156      /// First entry in the list points back to the zone manager.
157      Vector< SceneObject::ZoneRef*> mZoneLists;
158
159      /// Vector used repeatedly for zone space queries on the container.
160      mutable Vector< SceneObject*> mZoneSpacesQueryList;
161
162      /// Allocator for ZoneRefs.
163      static ClassChunker< SceneObject::ZoneRef> smZoneRefChunker;
164
165      /// @name Dirty Lists
166      /// Updating the zoning state of a scene is done en block rather than
167      /// individually for each object as it changes transforms or size.
168      /// @{
169
170      /// Area of the scene that needs to be rezoned.
171      Box3F mDirtyArea;
172
173      /// List of zone spaces that have changed state and need updating.
174      Vector< SceneZoneSpace*> mDirtyZoneSpaces;
175
176      /// List of objects (non-zone spaces) that have changed state and need
177      /// updating.
178      Vector< SceneObject*> mDirtyObjects;
179
180      /// @}
181
182      /// Check to see if we have accumulated a lot of unallocate zone IDs and if so,
183      /// compact the zoning lists by reassigning IDs.
184      ///
185      /// @warn This method may alter all zone IDs in the scene!
186      void _compactZonesCheck();
187
188      /// Return the index into #mZoneSpaces for the given object or -1 if
189      /// @object is not a zone manager.
190      S32 _getZoneSpaceIndex( SceneZoneSpace* object ) const;
191
192      /// Attach zoning state to the given object.
193      void _zoneInsert( SceneObject* object, bool queryListInitialized = false );
194
195      /// Detach zoning state from the given object.
196      void _zoneRemove( SceneObject* object );
197
198      /// Add to given object to the zone list of the given zone.
199      void _addToZoneList( U32 zoneId, SceneObject* object );
200
201      /// Clear all objects assigned to the given zone.
202      /// @note This does not remove the first link in the zone list which is the link
203      ///   back to the zone manager.
204      void _clearZoneList( U32 zoneId );
205
206      /// Find the given object in the zone list of the given zone.
207      SceneObject::ZoneRef* _findInZoneList( U32 zoneId, SceneObject* object ) const;
208
209      /// Assign the given object to the outdoor zone.
210      void _addToOutdoorZone( SceneObject* object );
211
212      /// Rezone all objects in the given area.
213      void _rezoneObjects( const Box3F& area );
214
215      /// Update the zoning state of the given object.
216      void _rezoneObject( SceneObject* object );
217
218      /// Fill #mZoneSpacesQueryList with all ZoneObjectType objects in the given area.
219      void _queryZoneSpaces( const Box3F& area ) const;
220
221   public:
222
223      SceneZoneSpaceManager( SceneContainer* container );
224      ~SceneZoneSpaceManager();
225
226      /// Bring the zoning state of the scene up to date.  This will cause objects
227      /// that have moved or have been resized to be rezoned and will updated regions
228      /// of the scene that had their zoning setup changed.
229      ///
230      /// @note This method depends on proper use of notifyObjectChanged().
231      void updateZoningState();
232
233      /// @name Objects
234      /// @{
235
236      /// Add zoning state to the given object.
237      void registerObject( SceneObject* object );
238
239      /// Remove the given object from the zoning state.
240      void unregisterObject( SceneObject* object );
241
242      /// Let the manager know that state relevant to zoning of the given
243      /// object has changed.
244      void notifyObjectChanged( SceneObject* object );
245
246      /// Update the zoning state of the given object.
247      void updateObject( SceneObject* object );
248
249      /// @}
250
251      /// @name Zones
252      /// @{
253
254      /// Return the root zone of the scene.
255      SceneRootZone* getRootZone() const { return mRootZone; }
256
257      /// Register a zone manager.
258      ///
259      /// @param object SceneZoneSpace object that contains zones.
260      /// @param numZones Number of zones that @a object contains.
261      void registerZones( SceneZoneSpace* object, U32 numZones );
262
263      /// Unregister a zone manager.
264      ///
265      /// @param object Object that contains zones.
266      void unregisterZones( SceneZoneSpace* object );
267
268      /// Return true if the given ID belongs to a currently registered zone.
269      bool isValidZoneId( const U32 zoneId ) const
270      {
271         return ( zoneId < mNumTotalAllocatedZones && mZoneLists[ zoneId ] );
272      }
273
274      /// Get the scene object that contains the zone with the given ID.
275      ///
276      /// @param zoneId ID of the zone.  Must be valid.
277      /// @return The zone space that has registered the given zone.
278      SceneZoneSpace* getZoneOwner( const U32 zoneId ) const
279      {
280         AssertFatal( isValidZoneId( zoneId ), "SceneManager::getZoneOwner - Invalid zone ID!");
281         return ( SceneZoneSpace* ) mZoneLists[ zoneId ]->object;
282      }
283
284      /// Return the total number of zones in the scene.
285      U32 getNumZones() const { return mNumTotalAllocatedZones; }
286
287      /// Return the effective amount of used zone IDs in the scene.
288      U32 getNumActiveZones() const { return mNumActiveZones; }
289
290      /// Return the total number of objects in the scene that manage zones.
291      U32 getNumZoneSpaces() const { return mZoneSpaces.size(); }
292
293      /// Find the zone that contains the given point.
294      ///
295      /// Note that the result can be <em>any</em> zone containing the given
296      /// point.
297      void findZone( const Point3F& point, SceneZoneSpace*& outZoneSpace, U32& outZoneID ) const;
298
299      /// Collect the IDs of all zones that overlap the given area.
300      ///
301      /// @param area AABB of scene space to query.
302      /// @param outZones IDs of all overlapped zones are added to this vector.
303      ///
304      /// @return Number of zones that have been added to @a outZones.  Always at least
305      ///   1 as at least the outdoor zone always overlaps the given area (though if another zone
306      ///   manager fully contains @a area, the outdoor zone will not be added to the list).
307      U32 findZones( const Box3F& area, Vector< U32>& outZones ) const;
308
309      static ZoningChangedSignal& getZoningChangedSignal()
310      {
311         static ZoningChangedSignal sSignal;
312         return sSignal;
313      }
314
315      /// @name Debugging
316      /// @{
317
318      /// Verify the current zoning state.  This makes sure all the connectivity
319      /// information and all the zone assignments appear to be correct.
320      void verifyState();
321
322      /// Dump the current state of all zone spaces in the scene to the console.
323      /// @param update If true, zoning state states are updated first; if false, zoning is
324      ///   dumped as is.
325      void dumpZoneStates( bool update = true );
326
327      /// @}
328
329      /// @}
330};
331
332#endif // !_SCENEZONESPACEMANAGER_H_
333