OpenSceneGraph/include/osg/ShadowVolumeOccluder
Robert Osfield 5e85cd59ab Added support for occluders occluding other occluders, which helps reduce
the number of occluder that will be used in cull traversal to only the
ones that will be effective. Note. Holes in occluders arn't handled in
this occluder occlusion test, will implement this later.
2002-06-18 22:35:48 +00:00

150 lines
4.8 KiB
Plaintext

//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 <osg/Polytope>
#include <osg/ConvexPlanerOccluder>
#include <osg/Node>
namespace osg {
class CullStack;
/** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */
class SG_EXPORT ShadowVolumeOccluder
{
public:
typedef std::vector<Polytope> HoleList;
ShadowVolumeOccluder(const ShadowVolumeOccluder& svo):
_volume(svo._volume),
_nodePath(svo._nodePath),
_projectionMatrix(svo._projectionMatrix),
_occluderVolume(svo._occluderVolume),
_holeList(svo._holeList) {}
ShadowVolumeOccluder():
_volume(0.0f) {}
bool operator < (const ShadowVolumeOccluder& svo) const { return getVolume()>svo.getVolume(); } // not greater volume first.
/** 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 getVolume() const { return _volume; }
/** return true if the specified vertex list is contaned entirely
* within this shadow occluder volume.*/
bool contains(const std::vector<Vec3>& 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<const Matrix> _projectionMatrix;
Polytope _occluderVolume;
HoleList _holeList;
};
/** A list of ShadowVolumeOccluder, used by CollectOccluderVisitor and CullVistor's.*/
typedef std::vector<ShadowVolumeOccluder> ShadowVolumeOccluderList;
inline void ShadowVolumeOccluder::disableResultMasks()
{
//std::cout<<"ShadowVolumeOccluder::disableResultMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
_occluderVolume.setResultMask(0);
for(HoleList::iterator itr=_holeList.begin();
itr!=_holeList.end();
++itr)
{
itr->setResultMask(0);
}
}
inline void ShadowVolumeOccluder::pushCurrentMask()
{
//std::cout<<"ShadowVolumeOccluder::pushCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
_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();
}
}
//std::cout<<"ShadowVolumeOccluder::popCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
}
} // end of namespace
#endif