mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
172 lines
7.4 KiB
C++
172 lines
7.4 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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 _SCENEZONECULLINGSTATE_H_
|
|
#define _SCENEZONECULLINGSTATE_H_
|
|
|
|
#ifndef _SCENECULLINGVOLUME_H_
|
|
#include "scene/culling/sceneCullingVolume.h"
|
|
#endif
|
|
|
|
|
|
/// Culling state for a zone.
|
|
///
|
|
/// Zone states keep track of the culling volumes that are generated during traversal
|
|
/// for a particular zone in a scene.
|
|
///
|
|
/// @note This class has no meaningful constructor; the memory for all zone states is
|
|
/// cleared en bloc.
|
|
class SceneZoneCullingState
|
|
{
|
|
public:
|
|
|
|
friend class SceneCullingState; // mCullingVolumes
|
|
|
|
/// Result of a culling test in a zone.
|
|
enum CullingTestResult
|
|
{
|
|
/// An includer tested positive on the bounding volume.
|
|
CullingTestPositiveByInclusion,
|
|
|
|
/// An occluder tested positive on the bounding volume.
|
|
CullingTestPositiveByOcclusion,
|
|
|
|
/// None of the culling volumes included or excluded the bounding volume.
|
|
CullingTestNegative
|
|
};
|
|
|
|
/// A culling volume linked to a zone.
|
|
///
|
|
/// @note Memory for CullingVolumeLink instances is maintained by SceneCullingState.
|
|
struct CullingVolumeLink
|
|
{
|
|
/// Culling volume.
|
|
SceneCullingVolume mVolume;
|
|
|
|
/// Next culling volume linked to the zone.
|
|
CullingVolumeLink* mNext;
|
|
|
|
CullingVolumeLink( const SceneCullingVolume& volume )
|
|
: mVolume( volume ) {mNext=NULL;}
|
|
};
|
|
|
|
/// Iterator over the culling volumes assigned to a zone.
|
|
struct CullingVolumeIterator
|
|
{
|
|
CullingVolumeIterator( const SceneZoneCullingState& state )
|
|
: mCurrent( state.getCullingVolumes() ) {}
|
|
|
|
bool isValid() const { return mCurrent != NULL; }
|
|
const SceneCullingVolume& operator *() const
|
|
{
|
|
AssertFatal( isValid(), "SceneCullingState::ZoneState::CullingVolumeIterator::operator* - Invalid iterator" );
|
|
return mCurrent->mVolume;
|
|
}
|
|
const SceneCullingVolume* operator ->() const
|
|
{
|
|
AssertFatal( isValid(), "SceneCullingState::ZoneState::CullingVolumeIterator::operator-> - Invalid iterator" );
|
|
return &mCurrent->mVolume;
|
|
}
|
|
CullingVolumeIterator& operator ++()
|
|
{
|
|
AssertFatal( isValid(), "SceneCullingState::ZoneState::CullingVolumeIterator::operator++ - Invalid iterator" );
|
|
mCurrent = mCurrent->mNext;
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
CullingVolumeLink* mCurrent;
|
|
};
|
|
|
|
protected:
|
|
|
|
/// Whether tests can be short-circuited, i.e. the first culler that rejects or accepts
|
|
/// will cause the test to terminate. This is the case if there are no includers inside
|
|
/// occluders, i.e. if occluders can be trusted to fully exclude any space they cover.
|
|
bool mCanShortcuit;//RDTODO: implement this
|
|
|
|
/// Link of culling volumes defining the visibility state of the zone. Since there may be
|
|
/// multiple portals leading into a zone or multiple occluders inside a zone, we may have multiple
|
|
/// culling volumes.
|
|
mutable CullingVolumeLink* mCullingVolumes;
|
|
|
|
/// Whether culling volumes for this zone state have already been sorted.
|
|
mutable bool mHaveSortedVolumes;
|
|
|
|
/// Whether there are inclusion volumes on this state.
|
|
bool mHaveIncluders;
|
|
|
|
/// Whether there are occlusion volumes on this state.
|
|
bool mHaveOccluders;
|
|
|
|
/// Culling volume test abstracted over bounding volume type.
|
|
template< typename T > CullingTestResult _testVolumes( T bounds, bool occludersOnly ) const;
|
|
|
|
/// Sort the culling volumes such that the volumes with the highest probability
|
|
/// of rejecting objects come first in the list. Also, make sure that all
|
|
/// occluders come before all includers so that occlusion is handled correctly.
|
|
void _sortVolumes() const;
|
|
|
|
/// Insert the volume in @a link at the proper position in the list represented
|
|
/// by @a head and @a tail.
|
|
static void _insertSorted( CullingVolumeLink*& head, CullingVolumeLink*& tail, CullingVolumeLink* link );
|
|
|
|
public:
|
|
|
|
/// Zone states are constructed by SceneCullingState. This constructor should not
|
|
/// be used otherwise. It is public due to the use through Vector in SceneCullingState.
|
|
SceneZoneCullingState():mCanShortcuit(false), mCullingVolumes(NULL), mHaveSortedVolumes(false), mHaveIncluders(false), mHaveOccluders(false){}
|
|
|
|
/// Return true if the zone is visible. This is the case if any
|
|
/// includers have been added to the zone's rendering state.
|
|
bool isZoneVisible() const { return mHaveIncluders; }
|
|
|
|
/// Return the list of culling volumes attached to the zone.
|
|
CullingVolumeLink* getCullingVolumes() const { _sortVolumes(); return mCullingVolumes; }
|
|
|
|
/// Test whether the culling volumes added to the zone test positive on the
|
|
/// given AABB, i.e. whether they include or exclude the given AABB.
|
|
CullingTestResult testVolumes( const Box3F& aabb, bool occludersOnly = false ) const;
|
|
|
|
/// Test whether the culling volumes added to the zone test positive on the
|
|
/// given OBB, i.e. whether they include or exclude the given OBB.
|
|
///
|
|
/// @param obb An OBB described by 8 points.
|
|
/// @param invertedOnly If true, only inverted cullers are tested.
|
|
CullingTestResult testVolumes( const OrientedBox3F& obb, bool occludersOnly = false ) const;
|
|
|
|
/// Test whether the culling volumes added to the zone test positive on the
|
|
/// given sphere, i.e. whether they include or exclude the given sphere.
|
|
CullingTestResult testVolumes( const SphereF& sphere, bool occludersOnly = false ) const;
|
|
|
|
/// Return true if the zone has more than one culling volume assigned to it.
|
|
bool hasMultipleVolumes() const { return ( mCullingVolumes && mCullingVolumes->mNext ); }
|
|
|
|
/// Return true if the zone has inclusion volumes assigned to it.
|
|
bool hasIncluders() const { return mHaveIncluders; }
|
|
|
|
/// Return true if the zone has occlusion volumes assigned to it.
|
|
bool hasOccluders() const { return mHaveOccluders; }
|
|
};
|
|
|
|
#endif // !_SCENEZONECULLINGSTATE_H_
|