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;
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user