ShadowVolumeOccluder 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSG_SHADOWVOLUMEOCCLUDER
  14. #define OSG_SHADOWVOLUMEOCCLUDER 1
  15. #include <osg/Polytope>
  16. #include <osg/ConvexPlanarOccluder>
  17. #include <osg/Node>
  18. namespace osg {
  19. class CullStack;
  20. /** ShadowVolumeOccluder is a helper class for implementing shadow occlusion culling. */
  21. class OSG_EXPORT ShadowVolumeOccluder
  22. {
  23. public:
  24. typedef std::vector<Polytope> HoleList;
  25. ShadowVolumeOccluder(const ShadowVolumeOccluder& svo):
  26. _volume(svo._volume),
  27. _nodePath(svo._nodePath),
  28. _projectionMatrix(svo._projectionMatrix),
  29. _occluderVolume(svo._occluderVolume),
  30. _holeList(svo._holeList) {}
  31. ShadowVolumeOccluder():
  32. _volume(0.0f) {}
  33. bool operator < (const ShadowVolumeOccluder& svo) const { return getVolume()>svo.getVolume(); } // not greater volume first.
  34. /** compute the shadow volume occluder. */
  35. bool computeOccluder(const NodePath& nodePath,const ConvexPlanarOccluder& occluder,CullStack& cullStack,bool createDrawables=false);
  36. inline void disableResultMasks();
  37. inline void pushCurrentMask();
  38. inline void popCurrentMask();
  39. /** return true if the matrix passed in matches the projection matrix that this ShadowVolumeOccluder is
  40. * associated with.*/
  41. bool matchProjectionMatrix(const osg::Matrix& matrix) const
  42. {
  43. if (_projectionMatrix.valid()) return matrix==*_projectionMatrix;
  44. else return false;
  45. }
  46. /** Set the NodePath which describes which node in the scene graph
  47. * that this occluder is attached to. */
  48. inline void setNodePath(NodePath& nodePath) { _nodePath = nodePath; }
  49. inline NodePath& getNodePath() { return _nodePath; }
  50. inline const NodePath& getNodePath() const { return _nodePath; }
  51. /** get the volume of the occluder minus its holes, in eye coords, the volume is normalized by dividing by
  52. * the volume of the view frustum in eye coords.*/
  53. float getVolume() const { return _volume; }
  54. /** return the occluder polytope.*/
  55. Polytope& getOccluder() { return _occluderVolume; }
  56. /** return the const occluder polytope.*/
  57. const Polytope& getOccluder() const { return _occluderVolume; }
  58. /** return the list of holes.*/
  59. HoleList& getHoleList() { return _holeList; }
  60. /** return the const list of holes.*/
  61. const HoleList& getHoleList() const { return _holeList; }
  62. /** return true if the specified vertex list is contained entirely
  63. * within this shadow occluder volume.*/
  64. bool contains(const std::vector<Vec3>& vertices);
  65. /** return true if the specified bounding sphere is contained entirely
  66. * within this shadow occluder volume.*/
  67. bool contains(const BoundingSphere& bound);
  68. /** return true if the specified bounding box is contained entirely
  69. * within this shadow occluder volume.*/
  70. bool contains(const BoundingBox& bound);
  71. inline void transformProvidingInverse(const osg::Matrix& matrix)
  72. {
  73. _occluderVolume.transformProvidingInverse(matrix);
  74. for(HoleList::iterator itr=_holeList.begin();
  75. itr!=_holeList.end();
  76. ++itr)
  77. {
  78. itr->transformProvidingInverse(matrix);
  79. }
  80. }
  81. protected:
  82. float _volume;
  83. NodePath _nodePath;
  84. ref_ptr<const RefMatrix> _projectionMatrix;
  85. Polytope _occluderVolume;
  86. HoleList _holeList;
  87. };
  88. /** A list of ShadowVolumeOccluder, used by CollectOccluderVisitor and CullVistor's.*/
  89. typedef std::vector<ShadowVolumeOccluder> ShadowVolumeOccluderList;
  90. inline void ShadowVolumeOccluder::disableResultMasks()
  91. {
  92. //std::cout<<"ShadowVolumeOccluder::disableResultMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
  93. _occluderVolume.setResultMask(0);
  94. for(HoleList::iterator itr=_holeList.begin();
  95. itr!=_holeList.end();
  96. ++itr)
  97. {
  98. itr->setResultMask(0);
  99. }
  100. }
  101. inline void ShadowVolumeOccluder::pushCurrentMask()
  102. {
  103. //std::cout<<"ShadowVolumeOccluder::pushCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
  104. _occluderVolume.pushCurrentMask();
  105. if (!_holeList.empty())
  106. {
  107. for(HoleList::iterator itr=_holeList.begin();
  108. itr!=_holeList.end();
  109. ++itr)
  110. {
  111. itr->pushCurrentMask();
  112. }
  113. }
  114. }
  115. inline void ShadowVolumeOccluder::popCurrentMask()
  116. {
  117. _occluderVolume.popCurrentMask();
  118. if (!_holeList.empty())
  119. {
  120. for(HoleList::iterator itr=_holeList.begin();
  121. itr!=_holeList.end();
  122. ++itr)
  123. {
  124. itr->popCurrentMask();
  125. }
  126. }
  127. //std::cout<<"ShadowVolumeOccluder::popCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
  128. }
  129. } // end of namespace
  130. #endif