1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
14#ifndef OSG_SHADOWVOLUMEOCCLUDER
15#define OSG_SHADOWVOLUMEOCCLUDER 1
17#include <osg/Polytope>
18#include <osg/ConvexPlanarOccluder>
25/** ShadowVolumeOccluder is a helper class for implementing shadow occlusion culling. */
26class OSG_EXPORT ShadowVolumeOccluder
32 typedef std::vector<Polytope> HoleList;
34 ShadowVolumeOccluder(const ShadowVolumeOccluder& svo):
36 _nodePath(svo._nodePath),
37 _projectionMatrix(svo._projectionMatrix),
38 _occluderVolume(svo._occluderVolume),
39 _holeList(svo._holeList) {}
41 ShadowVolumeOccluder():
45 bool operator < (const ShadowVolumeOccluder& svo) const { return getVolume()>svo.getVolume(); } // not greater volume first.
47 /** compute the shadow volume occluder. */
48 bool computeOccluder(const NodePath& nodePath,const ConvexPlanarOccluder& occluder,CullStack& cullStack,bool createDrawables=false);
51 inline void disableResultMasks();
53 inline void pushCurrentMask();
54 inline void popCurrentMask();
57 /** return true if the matrix passed in matches the projection matrix that this ShadowVolumeOccluder is
59 bool matchProjectionMatrix(const osg::Matrix& matrix) const
61 if (_projectionMatrix.valid()) return matrix==*_projectionMatrix;
66 /** Set the NodePath which describes which node in the scene graph
67 * that this occluder is attached to. */
68 inline void setNodePath(NodePath& nodePath) { _nodePath = nodePath; }
69 inline NodePath& getNodePath() { return _nodePath; }
70 inline const NodePath& getNodePath() const { return _nodePath; }
73 /** get the volume of the occluder minus its holes, in eye coords, the volume is normalized by dividing by
74 * the volume of the view frustum in eye coords.*/
75 float getVolume() const { return _volume; }
77 /** return the occluder polytope.*/
78 Polytope& getOccluder() { return _occluderVolume; }
80 /** return the const occluder polytope.*/
81 const Polytope& getOccluder() const { return _occluderVolume; }
83 /** return the list of holes.*/
84 HoleList& getHoleList() { return _holeList; }
86 /** return the const list of holes.*/
87 const HoleList& getHoleList() const { return _holeList; }
90 /** return true if the specified vertex list is contained entirely
91 * within this shadow occluder volume.*/
92 bool contains(const std::vector<Vec3>& vertices);
94 /** return true if the specified bounding sphere is contained entirely
95 * within this shadow occluder volume.*/
96 bool contains(const BoundingSphere& bound);
98 /** return true if the specified bounding box is contained entirely
99 * within this shadow occluder volume.*/
100 bool contains(const BoundingBox& bound);
102 inline void transformProvidingInverse(const osg::Matrix& matrix)
104 _occluderVolume.transformProvidingInverse(matrix);
105 for(HoleList::iterator itr=_holeList.begin();
106 itr!=_holeList.end();
109 itr->transformProvidingInverse(matrix);
118 ref_ptr<const RefMatrix> _projectionMatrix;
119 Polytope _occluderVolume;
124/** A list of ShadowVolumeOccluder, used by CollectOccluderVisitor and CullVistor's.*/
125typedef std::vector<ShadowVolumeOccluder> ShadowVolumeOccluderList;
128inline void ShadowVolumeOccluder::disableResultMasks()
130 //std::cout<<"ShadowVolumeOccluder::disableResultMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
131 _occluderVolume.setResultMask(0);
132 for(HoleList::iterator itr=_holeList.begin();
133 itr!=_holeList.end();
136 itr->setResultMask(0);
140inline void ShadowVolumeOccluder::pushCurrentMask()
142 //std::cout<<"ShadowVolumeOccluder::pushCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;
143 _occluderVolume.pushCurrentMask();
144 if (!_holeList.empty())
146 for(HoleList::iterator itr=_holeList.begin();
147 itr!=_holeList.end();
150 itr->pushCurrentMask();
155inline void ShadowVolumeOccluder::popCurrentMask()
157 _occluderVolume.popCurrentMask();
158 if (!_holeList.empty())
160 for(HoleList::iterator itr=_holeList.begin();
161 itr!=_holeList.end();
164 itr->popCurrentMask();
167 //std::cout<<"ShadowVolumeOccluder::popCurrentMasks() - _occluderVolume.getMaskStack().size()="<<_occluderVolume.getMaskStack().size()<<" "<<_occluderVolume.getCurrentMask()<<std::endl;