mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 00:24:40 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
310
Engine/source/scene/culling/sceneCullingState.h
Normal file
310
Engine/source/scene/culling/sceneCullingState.h
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _SCENECULLINGSTATE_H_
|
||||
#define _SCENECULLINGSTATE_H_
|
||||
|
||||
#ifndef _SCENEZONECULLINGSTATE_H_
|
||||
#include "scene/culling/sceneZoneCullingState.h"
|
||||
#endif
|
||||
|
||||
#ifndef _MATHUTIL_FRUSTUM_H_
|
||||
#include "math/util/frustum.h"
|
||||
#endif
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
|
||||
#ifndef _SCENECAMERASTATE_H_
|
||||
#include "scene/sceneCameraState.h"
|
||||
#endif
|
||||
|
||||
#ifndef _DATACHUNKER_H_
|
||||
#include "core/dataChunker.h"
|
||||
#endif
|
||||
|
||||
#ifndef _BITVECTOR_H_
|
||||
#include "core/bitVector.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SceneObject;
|
||||
class SceneManager;
|
||||
|
||||
|
||||
/// An object that gathers the culling state for a scene.
|
||||
class SceneCullingState
|
||||
{
|
||||
public:
|
||||
|
||||
/// Used to disable the somewhat expensive terrain occlusion testing
|
||||
/// done in during scene culling.
|
||||
static bool smDisableTerrainOcclusion;
|
||||
|
||||
/// Whether to force zone culling to off by default.
|
||||
static bool smDisableZoneCulling;
|
||||
|
||||
/// @name Occluder Restrictions
|
||||
/// Size restrictions on occlusion culling volumes. Any occlusion volume
|
||||
/// that does not meet these minimum requirements is not accepted into the
|
||||
/// rendering state.
|
||||
///
|
||||
/// Having independent restrictions on both width and height allows filtering
|
||||
/// out occluders that might have a lot of area but only by covering very thin
|
||||
/// stretches of the screen.
|
||||
/// @{
|
||||
|
||||
/// If more than this number of occlusion volumes are added to a ZoneState,
|
||||
/// then the occlusions volumes corresponding to the smallest amount of screen
|
||||
/// real estate get dropped such as to never exceed this total number of occlusion
|
||||
/// volumes.
|
||||
static U32 smMaxOccludersPerZone;
|
||||
|
||||
/// Percentage of camera-space frustum near plane height that an occlusion culler must
|
||||
/// at least fill in order to not be rejected.
|
||||
/// @note The height computed for occluders is only an estimate.
|
||||
static F32 smOccluderMinHeightPercentage;
|
||||
|
||||
/// Percentage of camera-space frustum near plane width that an occlusion culler must
|
||||
/// at least fill in order to not be rejected.
|
||||
/// @note The width computed for occluders is only an estimate.
|
||||
static F32 smOccluderMinWidthPercentage;
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
|
||||
/// Scene which is being culled.
|
||||
SceneManager* mSceneManager;
|
||||
|
||||
/// The viewing state that defines how the scene is being viewed.
|
||||
SceneCameraState mCameraState;
|
||||
|
||||
/// The root culling volume corresponding to the camera frustum.
|
||||
SceneCullingVolume mRootVolume;
|
||||
|
||||
/// Occluders that have been added to this render state. Adding an occluder does not
|
||||
/// necessarily result in an occluder volume being added. To not repeatedly try to
|
||||
/// process the same occluder object, all objects that are added are recorded here.
|
||||
Vector< SceneObject* > mAddedOccluderObjects;
|
||||
|
||||
///
|
||||
BitVector mZoneVisibilityFlags;
|
||||
|
||||
/// ZoneState entries for all zones in the scene.
|
||||
Vector< SceneZoneCullingState > mZoneStates;
|
||||
|
||||
/// Allocator for culling data that can be freed in one go when
|
||||
/// the culling state is freed.
|
||||
DataChunker mDataChunker;
|
||||
|
||||
/// If true, occlusion checks will not be done against the terrains
|
||||
/// in the scene.
|
||||
bool mDisableTerrainOcclusion;
|
||||
|
||||
/// If true, all objects will only be tested against the root
|
||||
/// frustum.
|
||||
bool mDisableZoneCulling;
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
SceneCullingState( SceneManager* sceneManager,
|
||||
const SceneCameraState& cameraState );
|
||||
|
||||
/// Return the scene which is being culled in this state.
|
||||
SceneManager* getSceneManager() const { return mSceneManager; }
|
||||
|
||||
/// Return the root frustum which is used to set up scene visibility.
|
||||
const Frustum& getFrustum() const { return getCameraState().getFrustum(); }
|
||||
|
||||
/// Return the viewing state that defines how the scene is being viewed.
|
||||
const SceneCameraState& getCameraState() const { return mCameraState; }
|
||||
|
||||
/// Return the root culling volume that corresponds to the camera frustum.
|
||||
/// @note This volume omits the near and far plane of the frustum's polyhedron
|
||||
/// as these will be tested separately during culling. Testing them repeatedly
|
||||
/// just wastes time.
|
||||
const SceneCullingVolume& getRootVolume() const { return mRootVolume; }
|
||||
|
||||
/// @name Visibility and Occlusion
|
||||
/// @{
|
||||
|
||||
enum CullOptions
|
||||
{
|
||||
/// Cull objects that have their SceneObject::DisableCullingInEditorFlag set.
|
||||
/// By default, these objects will not get culled if the editor is active.
|
||||
CullEditorOverrides = BIT( 0 ),
|
||||
|
||||
/// Do not cull objects that are render-disabled.
|
||||
/// @see SceneObject::isRenderEnabled()
|
||||
DontCullRenderDisabled = BIT( 1 )
|
||||
};
|
||||
|
||||
/// Cull the given list of objects according to the current culling state.
|
||||
///
|
||||
/// @param object Array of objects. This array will be modified in place.
|
||||
/// @param numObjects Number of objects in @a objects.
|
||||
/// @param cullOptions Combination of CullOptions.
|
||||
///
|
||||
/// @return Number of objects remaining in the list.
|
||||
U32 cullObjects( SceneObject** objects, U32 numObjects, U32 cullOptions = 0 ) const;
|
||||
|
||||
/// Return true if the given object is culled according to the current culling state.
|
||||
bool isCulled( SceneObject* object ) const { return ( cullObjects( &object, 1 ) == 0 ); }
|
||||
|
||||
/// Return true if the given AABB is culled in any of the given zones.
|
||||
bool isCulled( const Box3F& aabb, const U32* zones, U32 numZones ) const;
|
||||
|
||||
/// Return true if the given OBB is culled in any of the given zones.
|
||||
bool isCulled( const OrientedBox3F& obb, const U32* zones, U32 numZones ) const;
|
||||
|
||||
/// Return true if the given sphere is culled in any of the given zones.
|
||||
bool isCulled( const SphereF& sphere, const U32* zones, U32 numZones ) const;
|
||||
|
||||
/// Return true if the given object is occluded according to the current culling state.
|
||||
bool isOccluded( SceneObject* object ) const;
|
||||
|
||||
/// Return true if the given AABB is occluded according to the current culling state.
|
||||
bool isOccluded( const Box3F& aabb, const U32* zones, U32 numZones ) const;
|
||||
|
||||
/// Return true if the given OBB is occluded according to the current culling state.
|
||||
bool isOccluded( const OrientedBox3F& obb, const U32* zones, U32 numZones ) const;
|
||||
|
||||
/// Return true if the given sphere is occluded according to the current culling state.
|
||||
bool isOccluded( const SphereF& sphere, const U32* zones, U32 numZones ) const;
|
||||
|
||||
/// Add the occlusion information contained in the given object.
|
||||
///
|
||||
/// @note This should only be called after all positive frustums have been added
|
||||
/// to the zone state.
|
||||
void addOccluder( SceneObject* object );
|
||||
|
||||
/// Test whether the given object is occluded by any of the terrains
|
||||
/// in the scene.
|
||||
bool isOccludedByTerrain( SceneObject* object ) const;
|
||||
|
||||
/// Set whether isCulled() should do terrain occlusion checks or not.
|
||||
void setDisableTerrainOcclusion( bool value ) { mDisableTerrainOcclusion = value; }
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Zones
|
||||
/// @{
|
||||
|
||||
/// If true, culling will only be performed against the root frustum
|
||||
/// and not against frustums of individual zones.
|
||||
///
|
||||
/// @note This also disables occluders as these are added to the zone frustums.
|
||||
bool disableZoneCulling() const { return mDisableZoneCulling; }
|
||||
void disableZoneCulling( bool value ) { mDisableZoneCulling = value; }
|
||||
|
||||
/// Return true if any of the zones that the object is currently are
|
||||
/// visible.
|
||||
bool isWithinVisibleZone( SceneObject* object ) const;
|
||||
|
||||
/// Return a bit vector with one bit for each zone in the scene. If the bit is set,
|
||||
/// the zone has includer culling volumes attached to it and thus is visible.
|
||||
const BitVector& getZoneVisibilityFlags() const { return mZoneVisibilityFlags; }
|
||||
|
||||
/// Return the culling state for a particular zone.
|
||||
/// @param zoneId Numeric ID of zone.
|
||||
const SceneZoneCullingState& getZoneState( U32 zoneId ) const
|
||||
{
|
||||
AssertFatal( zoneId < ( U32 ) mZoneStates.size(), "SceneCullingState::getZoneState - Index out of bounds" );
|
||||
return mZoneStates[ zoneId ];
|
||||
}
|
||||
|
||||
/// Returns the culling state for a particular zone.
|
||||
/// @param zoneId Numeric ID of zone.
|
||||
SceneZoneCullingState& getZoneState( U32 zoneId )
|
||||
{
|
||||
return const_cast< SceneZoneCullingState& >( static_cast< const SceneCullingState* >( this )->getZoneState( zoneId ) );
|
||||
}
|
||||
|
||||
/// Add a culling volume to the visibility state of the given zone.
|
||||
///
|
||||
/// @param zoneId ID of zone to which to add the given frustum's visibility information.
|
||||
/// @param volume A culling volume. Note that the data in the volume must have
|
||||
/// a lifetime at least as long as the culling state.
|
||||
///
|
||||
/// @return True if the visibility state of the zone has changed, i.e. if the volume
|
||||
/// was either added in whole or merged with an existing set of planes. If the visibility
|
||||
/// state of the zone has not changed, returns false.
|
||||
bool addCullingVolumeToZone( U32 zoneId, const SceneCullingVolume& volume );
|
||||
|
||||
/// Copy the data from the given polyhedron to the culling state, create
|
||||
/// a new culling volume it and add it to the current culling state of the given zone.
|
||||
///
|
||||
/// @param zoneId ID of zone to which to add the given frustum's visibility information.
|
||||
/// @param type Which type of culling volume to add.
|
||||
/// @param polyhedron Polyhedron describing the space of the culling volume.
|
||||
bool addCullingVolumeToZone( U32 zoneId, SceneCullingVolume::Type type, const AnyPolyhedron& polyhedron );
|
||||
|
||||
/// Create a new culling volume by extruding the given polygon away from the viewpoint.
|
||||
///
|
||||
/// @param vertices Array of polygon vertices.
|
||||
/// @param numVertices Number of vertices in @a vertices.
|
||||
/// @param type Type of culling volume to create.
|
||||
/// @param outVolume (out) Receives the generated volume, if successful.
|
||||
///
|
||||
/// @return True if a volume could be generated from the given polygon or false if not.
|
||||
bool createCullingVolume( const Point3F* vertices, U32 numVertices, SceneCullingVolume::Type type, SceneCullingVolume& outVolume );
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Memory Management
|
||||
///
|
||||
/// Rather than allocating a lot of individual point and plane data for the culling volumes,
|
||||
/// it is more efficient to batch allocate chunks of memory and then release all the memory
|
||||
/// for all culling volumes in one go. This is facilitated by this interface.
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Allocate memory from this culling state. The memory is freed when the
|
||||
/// culling state is destroyed.
|
||||
void* allocateData( U32 size ) { return mDataChunker.alloc( size ); }
|
||||
|
||||
/// Allocate memory for @a num instances of T from this culling state.
|
||||
template< typename T >
|
||||
T* allocateData( U32 num ) { return reinterpret_cast< T* >( allocateData( sizeof( T ) * num ) ); }
|
||||
|
||||
/// @}
|
||||
|
||||
/// Queue debug visualizations of the culling volumes of all currently selected zones
|
||||
/// (or, if no zone is selected, all volumes in the outdoor zone) to the debug drawer.
|
||||
void debugRenderCullingVolumes() const;
|
||||
|
||||
private:
|
||||
|
||||
typedef SceneZoneCullingState::CullingTestResult CullingTestResult;
|
||||
|
||||
// Helper methods to avoid code duplication.
|
||||
|
||||
template< bool OCCLUDERS_ONLY, typename T > CullingTestResult _test( const T& bounds, const U32* zones, U32 numZones ) const;
|
||||
template< typename T, typename Iter > CullingTestResult _test
|
||||
( const T& bounds, Iter iter, const PlaneF& nearPlane, const PlaneF& farPlane ) const;
|
||||
template< typename T, typename Iter > CullingTestResult _testOccludersOnly( const T& bounds, Iter iter ) const;
|
||||
};
|
||||
|
||||
#endif // !_SCENECULLINGSTATE_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue