//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. #ifndef OSG_SHADOWVOLUMEOCCLUDER #define OSG_SHADOWVOLUMEOCCLUDER 1 #include #include #include #include namespace osg { /** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */ class SG_EXPORT ShadowVolumeOccluder { public: typedef std::vector HoleList; ShadowVolumeOccluder(const ShadowVolumeOccluder& soc): _quality(soc._quality), _nodePath(soc._nodePath), _occluderVolume(soc._occluderVolume), _holeList(soc._holeList) {} ShadowVolumeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MV,const Matrix& P) { computeOccluder(nodePath,occluder,MV,P); } /** compute the shadow volume occluder. */ void computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MV,const Matrix& P); inline void disableResultMasks(); inline void pushCurrentMask(); inline void popCurrentMask(); /** Set the NodePath which describes the which node in the scene graph * that this occluder was attached to.*/ inline void setNodePath(NodePath& nodePath) { _nodePath = nodePath; } inline NodePath& getNodePath() { return _nodePath; } inline const NodePath& getNodePath() const { return _nodePath; } float quality() { return _quality; } /** return true if the specified vertex list is contaned entirely * within this shadow occluder volume.*/ bool contains(const std::vector& vertices); /** return true if the specified bounding sphere is contaned entirely * within this shadow occluder volume.*/ bool contains(const BoundingSphere& bound); /** return true if the specified bounding box is contained entirely * within this shadow occluder volume.*/ bool contains(const BoundingBox& bound); inline void transformProvidingInverse(const osg::Matrix& matrix) { _occluderVolume.transformProvidingInverse(matrix); for(HoleList::iterator itr=_holeList.begin(); itr!=_holeList.end(); ++itr) { itr->transformProvidingInverse(matrix); } } protected: float _quality; NodePath _nodePath; Polytope _occluderVolume; HoleList _holeList; }; inline void ShadowVolumeOccluder::disableResultMasks() { _occluderVolume.setResultMask(0); for(HoleList::iterator itr=_holeList.begin(); itr!=_holeList.end(); ++itr) { itr->setResultMask(0); } } inline void ShadowVolumeOccluder::pushCurrentMask() { _occluderVolume.pushCurrentMask(); if (!_holeList.empty()) { for(HoleList::iterator itr=_holeList.begin(); itr!=_holeList.end(); ++itr) { itr->pushCurrentMask(); } } } inline void ShadowVolumeOccluder::popCurrentMask() { _occluderVolume.popCurrentMask(); if (!_holeList.empty()) { for(HoleList::iterator itr=_holeList.begin(); itr!=_holeList.end(); ++itr) { itr->popCurrentMask(); } } } } // end of namespace #endif