Torque3D Documentation / _generateds / sceneCullingState.h

sceneCullingState.h

Engine/source/scene/culling/sceneCullingState.h

More...

Classes:

class

An object that gathers the culling state for a scene.

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 _SCENECULLINGSTATE_H_
 25#define _SCENECULLINGSTATE_H_
 26
 27#ifndef _SCENEZONECULLINGSTATE_H_
 28#include "scene/culling/sceneZoneCullingState.h"
 29#endif
 30
 31#ifndef _MATHUTIL_FRUSTUM_H_
 32#include "math/util/frustum.h"
 33#endif
 34
 35#ifndef _TVECTOR_H_
 36#include "core/util/tVector.h"
 37#endif
 38
 39#ifndef _SCENECAMERASTATE_H_
 40#include "scene/sceneCameraState.h"
 41#endif
 42
 43#ifndef _DATACHUNKER_H_
 44#include "core/dataChunker.h"
 45#endif
 46
 47#ifndef _BITVECTOR_H_
 48#include "core/bitVector.h"
 49#endif
 50
 51
 52class SceneObject;
 53class SceneManager;
 54
 55
 56/// An object that gathers the culling state for a scene.
 57class SceneCullingState
 58{
 59   public:
 60
 61      /// Used to disable the somewhat expensive terrain occlusion testing
 62      /// done in during scene culling.
 63      static bool smDisableTerrainOcclusion;
 64
 65      /// Whether to force zone culling to off by default.
 66      static bool smDisableZoneCulling;
 67
 68      /// @name Occluder Restrictions
 69      /// Size restrictions on occlusion culling volumes.  Any occlusion volume
 70      /// that does not meet these minimum requirements is not accepted into the
 71      /// rendering state.
 72      ///
 73      /// Having independent restrictions on both width and height allows filtering
 74      /// out occluders that might have a lot of area but only by covering very thin
 75      /// stretches of the screen.
 76      /// @{
 77
 78      /// If more than this number of occlusion volumes are added to a ZoneState,
 79      /// then the occlusions volumes corresponding to the smallest amount of screen
 80      /// real estate get dropped such as to never exceed this total number of occlusion
 81      /// volumes.
 82      static U32 smMaxOccludersPerZone;
 83
 84      /// Percentage of camera-space frustum near plane height that an occlusion culler must
 85      /// at least fill in order to not be rejected.
 86      /// @note The height computed for occluders is only an estimate.
 87      static F32 smOccluderMinHeightPercentage;
 88
 89      /// Percentage of camera-space frustum near plane width that an occlusion culler must
 90      /// at least fill in order to not be rejected.
 91      /// @note The width computed for occluders is only an estimate.
 92      static F32 smOccluderMinWidthPercentage;
 93
 94      /// @}
 95
 96   protected:
 97
 98      /// Scene which is being culled.
 99      SceneManager* mSceneManager;
100
101      /// The viewing state that defines how the scene is being viewed.
102      SceneCameraState mCameraState;
103
104      /// The root culling volume corresponding to the culling frustum.
105      SceneCullingVolume mRootVolume;
106
107      /// The root culling frustum, which may be different from the camera frustum
108      Frustum mCullingFrustum;
109
110      /// Extra planes for culling.
111      PlaneSetF mExtraPlanesCull;
112
113      /// Occluders that have been added to this render state.  Adding an occluder does not
114      /// necessarily result in an occluder volume being added.  To not repeatedly try to
115      /// process the same occluder object, all objects that are added are recorded here.
116      Vector< SceneObject*> mAddedOccluderObjects;
117
118      ///
119      BitVector mZoneVisibilityFlags;
120
121      /// ZoneState entries for all zones in the scene.
122      Vector< SceneZoneCullingState> mZoneStates;
123
124      /// Allocator for culling data that can be freed in one go when
125      /// the culling state is freed.
126      DataChunker mDataChunker;
127
128      /// If true, occlusion checks will not be done against the terrains
129      /// in the scene.
130      bool mDisableTerrainOcclusion;
131
132      /// If true, all objects will only be tested against the root
133      /// frustum.
134      bool mDisableZoneCulling;
135
136   public:
137
138      ///
139      SceneCullingState( SceneManager* sceneManager,
140                         const SceneCameraState& cameraState );
141
142      /// Return the scene which is being culled in this state.
143      SceneManager* getSceneManager() const { return mSceneManager; }
144
145      /// Return the root frustum which is used to set up scene visibility.
146      const Frustum& getCullingFrustum() const { return mCullingFrustum; }
147
148      /// Return the root frustum which is used to set up scene visibility.
149      const Frustum& getCameraFrustum() const { return getCameraState().getFrustum(); }
150
151      /// Return the viewing state that defines how the scene is being viewed.
152      const SceneCameraState& getCameraState() const { return mCameraState; }
153      
154      /// Return the root culling volume that corresponds to the camera frustum.
155      /// @note This volume omits the near and far plane of the frustum's polyhedron
156      ///   as these will be tested separately during culling.  Testing them repeatedly
157      ///   just wastes time.
158      const SceneCullingVolume& getRootVolume() const { return mRootVolume; }
159
160      /// @name Visibility and Occlusion
161      /// @{
162
163      enum CullOptions
164      {
165         /// Cull objects that have their SceneObject::DisableCullingInEditorFlag set.
166         /// By default, these objects will not get culled if the editor is active.
167         CullEditorOverrides = BIT( 0 ),
168
169         /// Do not cull objects that are render-disabled.
170         /// @see SceneObject::isRenderEnabled()
171         DontCullRenderDisabled = BIT( 1 )
172      };
173
174      /// Cull the given list of objects according to the current culling state.
175      ///
176      /// @param object Array of objects.  This array will be modified in place.
177      /// @param numObjects Number of objects in @a objects.
178      /// @param cullOptions Combination of CullOptions.
179      ///
180      /// @return Number of objects remaining in the list.
181      U32 cullObjects( SceneObject** objects, U32 numObjects, U32 cullOptions = 0 ) const;
182
183      /// Return true if the given object is culled according to the current culling state.
184      bool isCulled( SceneObject* object ) const { return ( cullObjects( &object, 1 ) == 0 ); }
185
186      /// Return true if the given AABB is culled in any of the given zones.
187      bool isCulled( const Box3F& aabb, const U32* zones, U32 numZones ) const;
188
189      /// Return true if the given OBB is culled in any of the given zones.
190      bool isCulled( const OrientedBox3F& obb, const U32* zones, U32 numZones ) const;
191
192      /// Return true if the given sphere is culled in any of the given zones.
193      bool isCulled( const SphereF& sphere, const U32* zones, U32 numZones ) const;
194
195      /// Return true if the given object is occluded according to the current culling state.
196      bool isOccluded( SceneObject* object ) const;
197
198      /// Return true if the given AABB is occluded according to the current culling state.
199      bool isOccluded( const Box3F& aabb, const U32* zones, U32 numZones ) const;
200
201      /// Return true if the given OBB is occluded according to the current culling state.
202      bool isOccluded( const OrientedBox3F& obb, const U32* zones, U32 numZones ) const;
203
204      /// Return true if the given sphere is occluded according to the current culling state.
205      bool isOccluded( const SphereF& sphere, const U32* zones, U32 numZones ) const;
206
207      /// Add the occlusion information contained in the given object.
208      ///
209      /// @note This should only be called after all positive frustums have been added
210      ///   to the zone state.
211      void addOccluder( SceneObject* object );
212
213      /// Test whether the given object is occluded by any of the terrains
214      /// in the scene.
215      bool isOccludedByTerrain( SceneObject* object ) const;
216
217      /// Set whether isCulled() should do terrain occlusion checks or not.
218      void setDisableTerrainOcclusion( bool value ) { mDisableTerrainOcclusion = value; }
219
220      /// @}
221
222      /// @name Zones
223      /// @{
224
225      /// If true, culling will only be performed against the root frustum
226      /// and not against frustums of individual zones.
227      ///
228      /// @note This also disables occluders as these are added to the zone frustums.
229      bool disableZoneCulling() const { return mDisableZoneCulling; }
230      void disableZoneCulling( bool value ) { mDisableZoneCulling = value; }
231
232      /// Return true if any of the zones that the object is currently are
233      /// visible.
234      bool isWithinVisibleZone( SceneObject* object ) const;
235
236      /// Return a bit vector with one bit for each zone in the scene.  If the bit is set,
237      /// the zone has includer culling volumes attached to it and thus is visible.
238      const BitVector& getZoneVisibilityFlags() const { return mZoneVisibilityFlags; }
239
240      /// Return the culling state for a particular zone.
241      /// @param zoneId Numeric ID of zone.
242      const SceneZoneCullingState& getZoneState( U32 zoneId ) const
243      {
244         AssertFatal( zoneId < ( U32 ) mZoneStates.size(), "SceneCullingState::getZoneState - Index out of bounds" );
245         return mZoneStates[ zoneId ];
246      }
247
248      /// Returns the culling state for a particular zone.
249      /// @param zoneId Numeric ID of zone.
250      SceneZoneCullingState& getZoneState( U32 zoneId )
251      {
252         return const_cast< SceneZoneCullingState& >( static_cast< const SceneCullingState* >( this )->getZoneState( zoneId ) );
253      }
254
255      /// Add a culling volume to the visibility state of the given zone.
256      ///
257      /// @param zoneId ID of zone to which to add the given frustum's visibility information.
258      /// @param volume A culling volume.  Note that the data in the volume must have
259      ///   a lifetime at least as long as the culling state.
260      ///
261      /// @return True if the visibility state of the zone has changed, i.e. if the volume
262      ///   was either added in whole or merged with an existing set of planes.  If the visibility
263      ///   state of the zone has not changed, returns false.
264      bool addCullingVolumeToZone( U32 zoneId, const SceneCullingVolume& volume );
265
266      /// Copy the data from the given polyhedron to the culling state, create
267      /// a new culling volume it and add it to the current culling state of the given zone.
268      ///
269      /// @param zoneId ID of zone to which to add the given frustum's visibility information.
270      /// @param type Which type of culling volume to add.
271      /// @param polyhedron Polyhedron describing the space of the culling volume.
272      bool addCullingVolumeToZone( U32 zoneId, SceneCullingVolume::Type type, const AnyPolyhedron& polyhedron );
273
274      /// Create a new culling volume by extruding the given polygon away from the viewpoint.
275      ///
276      /// @param vertices Array of polygon vertices.
277      /// @param numVertices Number of vertices in @a vertices.
278      /// @param type Type of culling volume to create.
279      /// @param outVolume (out) Receives the generated volume, if successful.
280      ///
281      /// @return True if a volume could be generated from the given polygon or false if not.
282      bool createCullingVolume( const Point3F* vertices, U32 numVertices, SceneCullingVolume::Type type, SceneCullingVolume& outVolume );
283
284      /// @}
285
286      /// @name Memory Management
287      ///
288      /// Rather than allocating a lot of individual point and plane data for the culling volumes,
289      /// it is more efficient to batch allocate chunks of memory and then release all the memory
290      /// for all culling volumes in one go.  This is facilitated by this interface.
291      ///
292      /// @{
293
294      /// Allocate memory from this culling state.  The memory is freed when the
295      /// culling state is destroyed.
296      void* allocateData( U32 size ) { return mDataChunker.alloc( size ); }
297
298      /// Allocate memory for @a num instances of T from this culling state.
299      template< typename T >
300      T* allocateData( U32 num ) { return reinterpret_cast< T* >( allocateData( sizeof( T ) * num ) ); }
301
302      /// @}
303
304      /// Queue debug visualizations of the culling volumes of all currently selected zones
305      /// (or, if no zone is selected, all volumes in the outdoor zone) to the debug drawer.
306      void debugRenderCullingVolumes() const;
307
308      /// Set planes for extra culling
309      void setExtraPlanesCull( const PlaneSetF &cull) { mExtraPlanesCull = cull; }
310
311      /// Clear planes for extra culling.
312      void clearExtraPlanesCull() { mExtraPlanesCull = PlaneSetF(NULL, 0); }
313
314      /// Check extra planes culling
315      bool isOccludedWithExtraPlanesCull(const Box3F &box) const
316      {
317         if(mExtraPlanesCull.getNumPlanes())
318            return mExtraPlanesCull.testPotentialIntersection( box ) == GeometryOutside;
319
320         return false;
321      }
322
323   private:
324
325      typedef SceneZoneCullingState::CullingTestResult CullingTestResult;
326
327      // Helper methods to avoid code duplication.
328
329      template< bool OCCLUDERS_ONLY, typename T > CullingTestResult _test( const T& bounds, const U32* zones, U32 numZones ) const;
330      template< typename T, typename Iter > CullingTestResult _test
331         ( const T& bounds, Iter iter, const PlaneF& nearPlane, const PlaneF& farPlane ) const;
332      template< typename T, typename Iter > CullingTestResult _testOccludersOnly( const T& bounds, Iter iter ) const;
333};
334
335#endif // !_SCENECULLINGSTATE_H_
336