Refined the CollectOccluderVisitor so that it checks the subgraph below
a node contains occluders before traversing.
This commit is contained in:
parent
c71bf35152
commit
73ec80843f
@ -50,6 +50,25 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
|
||||
bool _createDrawables;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ void CollectOccludersVisitor::apply(osg::Node& node)
|
||||
// push the culling mode.
|
||||
pushCurrentMask();
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
// pop the culling mode.
|
||||
popCurrentMask();
|
||||
@ -49,7 +49,7 @@ void CollectOccludersVisitor::apply(osg::Transform& node)
|
||||
node.getLocalToWorldMatrix(*matrix,this);
|
||||
pushModelViewMatrix(matrix.get());
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
popModelViewMatrix();
|
||||
|
||||
@ -67,7 +67,7 @@ void CollectOccludersVisitor::apply(osg::Projection& node)
|
||||
ref_ptr<osg::Matrix> matrix = createOrReuseMatrix(node.getMatrix());
|
||||
pushProjectionMatrix(matrix.get());
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
popProjectionMatrix();
|
||||
|
||||
@ -91,7 +91,7 @@ void CollectOccludersVisitor::apply(osg::LOD& node)
|
||||
pushCurrentMask();
|
||||
|
||||
//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.
|
||||
popCurrentMask();
|
||||
@ -130,7 +130,7 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node)
|
||||
}
|
||||
}
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
// pop the culling mode.
|
||||
popCurrentMask();
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
@ -274,6 +273,62 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
|
||||
geode->addDrawable(createOccluderDrawable(points,farPoints));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user