2003-01-22 00:45:36 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
|
|
|
*
|
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
2002-05-29 07:43:22 +08:00
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
#ifndef OSG_SHADOWVOLUMEOCCLUDER
|
|
|
|
#define OSG_SHADOWVOLUMEOCCLUDER 1
|
2002-05-29 07:43:22 +08:00
|
|
|
|
2002-06-03 23:39:41 +08:00
|
|
|
#include <osg/Polytope>
|
2002-08-29 19:02:01 +08:00
|
|
|
#include <osg/ConvexPlanarOccluder>
|
2002-06-09 03:58:05 +08:00
|
|
|
#include <osg/Node>
|
2002-05-29 07:43:22 +08:00
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
2002-06-14 00:21:00 +08:00
|
|
|
class CullStack;
|
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
/** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */
|
|
|
|
class SG_EXPORT ShadowVolumeOccluder
|
2002-05-29 07:43:22 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
2002-06-03 23:39:41 +08:00
|
|
|
typedef std::vector<Polytope> HoleList;
|
|
|
|
|
2002-06-14 00:21:00 +08:00
|
|
|
ShadowVolumeOccluder(const ShadowVolumeOccluder& svo):
|
|
|
|
_volume(svo._volume),
|
|
|
|
_nodePath(svo._nodePath),
|
|
|
|
_projectionMatrix(svo._projectionMatrix),
|
|
|
|
_occluderVolume(svo._occluderVolume),
|
|
|
|
_holeList(svo._holeList) {}
|
|
|
|
|
|
|
|
ShadowVolumeOccluder():
|
|
|
|
_volume(0.0f) {}
|
2002-06-04 23:21:24 +08:00
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
|
2002-06-19 06:35:48 +08:00
|
|
|
bool operator < (const ShadowVolumeOccluder& svo) const { return getVolume()>svo.getVolume(); } // not greater volume first.
|
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
/** compute the shadow volume occluder. */
|
2002-08-29 19:02:01 +08:00
|
|
|
bool computeOccluder(const NodePath& nodePath,const ConvexPlanarOccluder& occluder,CullStack& cullStack,bool createDrawables=false);
|
2002-05-29 07:43:22 +08:00
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
|
2002-06-09 03:58:05 +08:00
|
|
|
inline void disableResultMasks();
|
|
|
|
|
2002-06-03 23:39:41 +08:00
|
|
|
inline void pushCurrentMask();
|
|
|
|
inline void popCurrentMask();
|
2002-06-14 00:21:00 +08:00
|
|
|
|
|
|
|
|
2004-09-03 03:10:33 +08:00
|
|
|
/** return true if the matrix passed in matches the projection matrix that this ShadowVolumeOccluder is
|
2002-06-14 00:21:00 +08:00
|
|
|
* associated with.*/
|
|
|
|
bool matchProjectionMatrix(const osg::Matrix& matrix) const
|
|
|
|
{
|
|
|
|
if (_projectionMatrix.valid()) return matrix==*_projectionMatrix;
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
2002-06-03 23:39:41 +08:00
|
|
|
|
2004-09-03 03:10:33 +08:00
|
|
|
/** Set the NodePath which describes which node in the scene graph
|
|
|
|
* that this occluder is attached to. */
|
2002-06-09 03:58:05 +08:00
|
|
|
inline void setNodePath(NodePath& nodePath) { _nodePath = nodePath; }
|
|
|
|
inline NodePath& getNodePath() { return _nodePath; }
|
|
|
|
inline const NodePath& getNodePath() const { return _nodePath; }
|
|
|
|
|
2002-06-19 18:19:10 +08:00
|
|
|
|
|
|
|
/** get the volume of the occluder minus its holes, in eye coords, the volume is normalized by dividing by
|
|
|
|
* the volume of the view frustum in eye coords.*/
|
2002-06-15 20:14:42 +08:00
|
|
|
float getVolume() const { return _volume; }
|
2002-06-14 00:21:00 +08:00
|
|
|
|
2002-06-19 18:19:10 +08:00
|
|
|
/** return the occluder polytope.*/
|
|
|
|
Polytope& getOccluder() { return _occluderVolume; }
|
|
|
|
|
|
|
|
/** return the const occluder polytope.*/
|
|
|
|
const Polytope& getOccluder() const { return _occluderVolume; }
|
|
|
|
|
|
|
|
/** return the list of holes.*/
|
|
|
|
HoleList& getHoleList() { return _holeList; }
|
|
|
|
|
|
|
|
/** return the const list of holes.*/
|
|
|
|
const HoleList& getHoleList() const { return _holeList; }
|
2002-06-14 00:21:00 +08:00
|
|
|
|
2002-06-09 03:58:05 +08:00
|
|
|
|
2004-09-03 03:10:33 +08:00
|
|
|
/** return true if the specified vertex list is contained entirely
|
2002-06-12 17:22:30 +08:00
|
|
|
* within this shadow occluder volume.*/
|
|
|
|
bool contains(const std::vector<Vec3>& vertices);
|
|
|
|
|
2004-09-03 03:10:33 +08:00
|
|
|
/** return true if the specified bounding sphere is contained entirely
|
2002-05-29 07:43:22 +08:00
|
|
|
* within this shadow occluder volume.*/
|
2002-06-03 23:39:41 +08:00
|
|
|
bool contains(const BoundingSphere& bound);
|
2002-05-29 07:43:22 +08:00
|
|
|
|
|
|
|
/** return true if the specified bounding box is contained entirely
|
|
|
|
* within this shadow occluder volume.*/
|
2002-06-03 23:39:41 +08:00
|
|
|
bool contains(const BoundingBox& bound);
|
2002-05-29 07:43:22 +08:00
|
|
|
|
2002-06-04 01:49:28 +08:00
|
|
|
inline void transformProvidingInverse(const osg::Matrix& matrix)
|
|
|
|
{
|
|
|
|
_occluderVolume.transformProvidingInverse(matrix);
|
|
|
|
for(HoleList::iterator itr=_holeList.begin();
|
|
|
|
itr!=_holeList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->transformProvidingInverse(matrix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-06-19 18:19:10 +08:00
|
|
|
protected:
|
2002-06-09 03:58:05 +08:00
|
|
|
|
2003-01-10 17:25:42 +08:00
|
|
|
float _volume;
|
|
|
|
NodePath _nodePath;
|
|
|
|
ref_ptr<const RefMatrix> _projectionMatrix;
|
|
|
|
Polytope _occluderVolume;
|
|
|
|
HoleList _holeList;
|
2002-05-29 07:43:22 +08:00
|
|
|
};
|
|
|
|
|
2002-06-14 00:21:00 +08:00
|
|
|
|
|
|
|
/** A list of ShadowVolumeOccluder, used by CollectOccluderVisitor and CullVistor's.*/
|
|
|
|
typedef std::vector<ShadowVolumeOccluder> ShadowVolumeOccluderList;
|
|
|
|
|
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
inline void ShadowVolumeOccluder::disableResultMasks()
|
2002-06-09 03:58:05 +08:00
|
|
|
{
|
2002-06-17 17:10:26 +08:00
|
|
|
//std::cout<<"ShadowVolumeOccluder::disableResultMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
|
2002-06-09 03:58:05 +08:00
|
|
|
_occluderVolume.setResultMask(0);
|
|
|
|
for(HoleList::iterator itr=_holeList.begin();
|
|
|
|
itr!=_holeList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->setResultMask(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
inline void ShadowVolumeOccluder::pushCurrentMask()
|
2002-06-03 23:39:41 +08:00
|
|
|
{
|
2002-06-17 17:10:26 +08:00
|
|
|
//std::cout<<"ShadowVolumeOccluder::pushCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
|
2002-06-03 23:39:41 +08:00
|
|
|
_occluderVolume.pushCurrentMask();
|
|
|
|
if (!_holeList.empty())
|
|
|
|
{
|
|
|
|
for(HoleList::iterator itr=_holeList.begin();
|
|
|
|
itr!=_holeList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->pushCurrentMask();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-10 19:21:21 +08:00
|
|
|
inline void ShadowVolumeOccluder::popCurrentMask()
|
2002-06-03 23:39:41 +08:00
|
|
|
{
|
|
|
|
_occluderVolume.popCurrentMask();
|
|
|
|
if (!_holeList.empty())
|
|
|
|
{
|
|
|
|
for(HoleList::iterator itr=_holeList.begin();
|
|
|
|
itr!=_holeList.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->popCurrentMask();
|
|
|
|
}
|
|
|
|
}
|
2002-06-17 17:10:26 +08:00
|
|
|
//std::cout<<"ShadowVolumeOccluder::popCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
|
2002-06-03 23:39:41 +08:00
|
|
|
}
|
|
|
|
|
2002-05-29 07:43:22 +08:00
|
|
|
} // end of namespace
|
|
|
|
|
|
|
|
#endif
|