Refined the CollectOccluderVisitor so that it checks the subgraph below

a node contains occluders before traversing.
This commit is contained in:
Robert Osfield 2002-06-14 13:49:59 +00:00
parent c71bf35152
commit 73ec80843f
3 changed files with 80 additions and 6 deletions

View File

@ -50,6 +50,25 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
bool _createDrawables; bool _createDrawables;
ShadowVolumeOccluderList _collectedOccluderList; ShadowVolumeOccluderList _collectedOccluderList;
inline void handle_callbacks_and_traverse(osg::Node& node)
{
osg::NodeCallback* callback = node.getAppCallback();
if (callback) (*callback)(&node,this);
else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node);
}
inline void handle_cull_callbacks_and_traverse(osg::Node& node)
{
/*osg::NodeCallback* callback = node.getCullCallback();
if (callback) (*callback)(&node,this);
else*/ if (node.getNumChildrenWithOccluderNodes()>0) traverse(node);
}
inline void handle_cull_callbacks_and_accept(osg::Node& node,osg::Node* acceptNode)
{
/*osg::NodeCallback* callback = node.getCullCallback();
if (callback) (*callback)(&node,this);
else*/ if (node.getNumChildrenWithOccluderNodes()>0) acceptNode->accept(*this);
}
}; };
} }

View File

@ -32,7 +32,7 @@ void CollectOccludersVisitor::apply(osg::Node& node)
// push the culling mode. // push the culling mode.
pushCurrentMask(); pushCurrentMask();
traverse(node); handle_cull_callbacks_and_traverse(node);
// pop the culling mode. // pop the culling mode.
popCurrentMask(); popCurrentMask();
@ -49,7 +49,7 @@ void CollectOccludersVisitor::apply(osg::Transform& node)
node.getLocalToWorldMatrix(*matrix,this); node.getLocalToWorldMatrix(*matrix,this);
pushModelViewMatrix(matrix.get()); pushModelViewMatrix(matrix.get());
traverse(node); handle_cull_callbacks_and_traverse(node);
popModelViewMatrix(); popModelViewMatrix();
@ -67,7 +67,7 @@ void CollectOccludersVisitor::apply(osg::Projection& node)
ref_ptr<osg::Matrix> matrix = createOrReuseMatrix(node.getMatrix()); ref_ptr<osg::Matrix> matrix = createOrReuseMatrix(node.getMatrix());
pushProjectionMatrix(matrix.get()); pushProjectionMatrix(matrix.get());
traverse(node); handle_cull_callbacks_and_traverse(node);
popProjectionMatrix(); popProjectionMatrix();
@ -91,7 +91,7 @@ void CollectOccludersVisitor::apply(osg::LOD& node)
pushCurrentMask(); pushCurrentMask();
//notify(INFO) << "selecting child "<<eval<< std::endl; //notify(INFO) << "selecting child "<<eval<< std::endl;
node.getChild(eval)->accept(*this); handle_cull_callbacks_and_accept(node,node.getChild(eval));
// pop the culling mode. // pop the culling mode.
popCurrentMask(); popCurrentMask();
@ -130,7 +130,7 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node)
} }
} }
traverse(node); handle_cull_callbacks_and_traverse(node);
// pop the culling mode. // pop the culling mode.
popCurrentMask(); popCurrentMask();

View File

@ -189,7 +189,6 @@ Drawable* createOccluderDrawable(const PointList& front, const PointList& back)
} }
bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack,bool createDrawables) bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,CullStack& cullStack,bool createDrawables)
{ {
@ -276,6 +275,62 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
} }
for(ConvexPlanerOccluder::HoleList::const_iterator hitr=occluder.getHoleList().begin();
hitr!=occluder.getHoleList().end();
++hitr)
{
PointList points;
if (clip(cullingset.getFrustum().getPlaneList(),hitr->getVertexList(),points)>=3)
{
_holeList.push_back();
Polytope& polytope = _holeList.back();
// compute the points on the far plane.
PointList farPoints;
farPoints.reserve(points.size());
transform(points,farPoints,MVP);
pushToFarPlane(farPoints);
transform(farPoints,invP);
// move the occlude points into projection space.
transform(points,MV);
// create the front face of the occluder
Plane occludePlane = computeFrontPlane(points);
// create the sides of the occluder
computePlanes(points,farPoints,polytope.getPlaneList());
polytope.setupMask();
// if the front face is pointing away from the eye point flip the whole polytope.
if (occludePlane[3]>0.0f)
{
polytope.flip();
}
if (createDrawables && !nodePath.empty())
{
osg::Group* group = dynamic_cast<osg::Group*>(nodePath.back());
if (group)
{
osg::Matrix invMV;
invMV.invert(MV);
transform(points,invMV);
transform(farPoints,invMV);
osg::Geode* geode = osgNew osg::Geode;
group->addChild(geode);
geode->addDrawable(createOccluderDrawable(points,farPoints));
}
}
}
}
return true; return true;
} }
else else