You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.9 KiB
172 lines
5.9 KiB
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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. |
|
*/ |
|
|
|
#ifndef OSG_SHADOWVOLUMEOCCLUDER |
|
#define OSG_SHADOWVOLUMEOCCLUDER 1 |
|
|
|
#include <osg/Polytope> |
|
#include <osg/ConvexPlanarOccluder> |
|
#include <osg/Node> |
|
|
|
namespace osg { |
|
|
|
class CullStack; |
|
|
|
/** ShadowVolumeOccluder is a helper class for implementing shadow occlusion culling. */ |
|
class OSG_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 ConvexPlanarOccluder& 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 ShadowVolumeOccluder is |
|
* associated with.*/ |
|
bool matchProjectionMatrix(const osg::Matrix& matrix) const |
|
{ |
|
if (_projectionMatrix.valid()) return matrix==*_projectionMatrix; |
|
else return false; |
|
} |
|
|
|
|
|
/** Set the NodePath which describes which node in the scene graph |
|
* that this occluder is attached to. */ |
|
inline void setNodePath(NodePath& nodePath) { _nodePath = nodePath; } |
|
inline NodePath& getNodePath() { return _nodePath; } |
|
inline const NodePath& getNodePath() const { return _nodePath; } |
|
|
|
|
|
/** 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.*/ |
|
float getVolume() const { return _volume; } |
|
|
|
/** 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; } |
|
|
|
|
|
/** return true if the specified vertex list is contained entirely |
|
* within this shadow occluder volume.*/ |
|
bool contains(const std::vector<Vec3>& vertices); |
|
|
|
/** return true if the specified bounding sphere is contained 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 RefMatrix> _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
|
|
|