//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 { class CullStack; /** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */ class SG_EXPORT ShadowVolumeOccluder { public: typedef std::vector HoleList; ShadowVolumeOccluder(const ShadowVolumeOccluder& svo): _volume(svo._volume), _nodePath(svo._nodePath), _projectionMatrix(svo._projectionMatrix), _occluderVolume(svo._occluderVolume), _holeList(svo._holeList) {} ShadowVolumeOccluder(): _volume(0.0f) {} /** compute the shadow volume occluder. */ bool computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack,bool createDrawables=false); inline void disableResultMasks(); inline void pushCurrentMask(); inline void popCurrentMask(); /** return true if the matrix passed in matches the projection matrix that this ShaowVolumeOccluder is * associated with.*/ bool matchProjectionMatrix(const osg::Matrix& matrix) const { if (_projectionMatrix.valid()) return matrix==*_projectionMatrix; else return false; } /** 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 volume() { return _volume; } /** 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 _volume; NodePath _nodePath; ref_ptr _projectionMatrix; Polytope _occluderVolume; HoleList _holeList; }; /** A list of ShadowVolumeOccluder, used by CollectOccluderVisitor and CullVistor's.*/ typedef std::vector ShadowVolumeOccluderList; 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