sceneZoneCullingState.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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 _SCENEZONECULLINGSTATE_H_
  23. #define _SCENEZONECULLINGSTATE_H_
  24. #ifndef _SCENECULLINGVOLUME_H_
  25. #include "scene/culling/sceneCullingVolume.h"
  26. #endif
  27. /// Culling state for a zone.
  28. ///
  29. /// Zone states keep track of the culling volumes that are generated during traversal
  30. /// for a particular zone in a scene.
  31. ///
  32. /// @note This class has no meaningful constructor; the memory for all zone states is
  33. /// cleared en bloc.
  34. class SceneZoneCullingState
  35. {
  36. public:
  37. friend class SceneCullingState; // mCullingVolumes
  38. /// Result of a culling test in a zone.
  39. enum CullingTestResult
  40. {
  41. /// An includer tested positive on the bounding volume.
  42. CullingTestPositiveByInclusion,
  43. /// An occluder tested positive on the bounding volume.
  44. CullingTestPositiveByOcclusion,
  45. /// None of the culling volumes included or excluded the bounding volume.
  46. CullingTestNegative
  47. };
  48. /// A culling volume linked to a zone.
  49. ///
  50. /// @note Memory for CullingVolumeLink instances is maintained by SceneCullingState.
  51. struct CullingVolumeLink
  52. {
  53. /// Culling volume.
  54. SceneCullingVolume mVolume;
  55. /// Next culling volume linked to the zone.
  56. CullingVolumeLink* mNext;
  57. CullingVolumeLink( const SceneCullingVolume& volume )
  58. : mVolume( volume ) {}
  59. };
  60. /// Iterator over the culling volumes assigned to a zone.
  61. struct CullingVolumeIterator
  62. {
  63. CullingVolumeIterator( const SceneZoneCullingState& state )
  64. : mCurrent( state.getCullingVolumes() ) {}
  65. bool isValid() const { return mCurrent != NULL; }
  66. const SceneCullingVolume& operator *() const
  67. {
  68. AssertFatal( isValid(), "SceneCullingState::ZoneState::CullingVolumeIterator::operator* - Invalid iterator" );
  69. return mCurrent->mVolume;
  70. }
  71. const SceneCullingVolume* operator ->() const
  72. {
  73. AssertFatal( isValid(), "SceneCullingState::ZoneState::CullingVolumeIterator::operator-> - Invalid iterator" );
  74. return &mCurrent->mVolume;
  75. }
  76. CullingVolumeIterator& operator ++()
  77. {
  78. AssertFatal( isValid(), "SceneCullingState::ZoneState::CullingVolumeIterator::operator++ - Invalid iterator" );
  79. mCurrent = mCurrent->mNext;
  80. return *this;
  81. }
  82. private:
  83. CullingVolumeLink* mCurrent;
  84. };
  85. protected:
  86. /// Whether tests can be short-circuited, i.e. the first culler that rejects or accepts
  87. /// will cause the test to terminate. This is the case if there are no includers inside
  88. /// occluders, i.e. if occluders can be trusted to fully exclude any space they cover.
  89. bool mCanShortcuit;//RDTODO: implement this
  90. /// Link of culling volumes defining the visibility state of the zone. Since there may be
  91. /// multiple portals leading into a zone or multiple occluders inside a zone, we may have multiple
  92. /// culling volumes.
  93. mutable CullingVolumeLink* mCullingVolumes;
  94. /// Whether culling volumes for this zone state have already been sorted.
  95. mutable bool mHaveSortedVolumes;
  96. /// Whether there are inclusion volumes on this state.
  97. bool mHaveIncluders;
  98. /// Whether there are occlusion volumes on this state.
  99. bool mHaveOccluders;
  100. /// Culling volume test abstracted over bounding volume type.
  101. template< typename T > CullingTestResult _testVolumes( T bounds, bool occludersOnly ) const;
  102. /// Sort the culling volumes such that the volumes with the highest probability
  103. /// of rejecting objects come first in the list. Also, make sure that all
  104. /// occluders come before all includers so that occlusion is handled correctly.
  105. void _sortVolumes() const;
  106. /// Insert the volume in @a link at the proper position in the list represented
  107. /// by @a head and @a tail.
  108. static void _insertSorted( CullingVolumeLink*& head, CullingVolumeLink*& tail, CullingVolumeLink* link );
  109. public:
  110. /// Zone states are constructed by SceneCullingState. This constructor should not
  111. /// be used otherwise. It is public due to the use through Vector in SceneCullingState.
  112. SceneZoneCullingState() {}
  113. /// Return true if the zone is visible. This is the case if any
  114. /// includers have been added to the zone's rendering state.
  115. bool isZoneVisible() const { return mHaveIncluders; }
  116. /// Return the list of culling volumes attached to the zone.
  117. CullingVolumeLink* getCullingVolumes() const { _sortVolumes(); return mCullingVolumes; }
  118. /// Test whether the culling volumes added to the zone test positive on the
  119. /// given AABB, i.e. whether they include or exclude the given AABB.
  120. CullingTestResult testVolumes( const Box3F& aabb, bool occludersOnly = false ) const;
  121. /// Test whether the culling volumes added to the zone test positive on the
  122. /// given OBB, i.e. whether they include or exclude the given OBB.
  123. ///
  124. /// @param obb An OBB described by 8 points.
  125. /// @param invertedOnly If true, only inverted cullers are tested.
  126. CullingTestResult testVolumes( const OrientedBox3F& obb, bool occludersOnly = false ) const;
  127. /// Test whether the culling volumes added to the zone test positive on the
  128. /// given sphere, i.e. whether they include or exclude the given sphere.
  129. CullingTestResult testVolumes( const SphereF& sphere, bool occludersOnly = false ) const;
  130. /// Return true if the zone has more than one culling volume assigned to it.
  131. bool hasMultipleVolumes() const { return ( mCullingVolumes && mCullingVolumes->mNext ); }
  132. /// Return true if the zone has inclusion volumes assigned to it.
  133. bool hasIncluders() const { return mHaveIncluders; }
  134. /// Return true if the zone has occlusion volumes assigned to it.
  135. bool hasOccluders() const { return mHaveOccluders; }
  136. };
  137. #endif // !_SCENEZONECULLINGSTATE_H_