Added CullCallbacks to osg::Node, and osgUtil::CullVisitor.
This commit is contained in:
@@ -112,6 +112,15 @@ class SG_EXPORT Node : public Object
|
||||
inline const int getNumChildrenRequiringAppTraversal() const { return _numChildrenRequiringAppTraversal; }
|
||||
|
||||
|
||||
/** Set cull node callback, called during cull traversal. */
|
||||
void setCullCallback(NodeCallback* nc) { _cullCallback = nc; }
|
||||
|
||||
/** Get app node callback, called during app traversal. */
|
||||
inline NodeCallback* getCullCallback() { return _cullCallback.get(); }
|
||||
|
||||
/** Get const app node callback, called during app traversal. */
|
||||
inline const NodeCallback* getCullCallback() const { return _cullCallback.get(); }
|
||||
|
||||
/** Set the view frustum/small feature culling of this node to be active or inactive.
|
||||
* The default value to true for _cullingActive. Used a guide
|
||||
* to the cull traversal.*/
|
||||
@@ -220,6 +229,8 @@ class SG_EXPORT Node : public Object
|
||||
int _numChildrenRequiringAppTraversal;
|
||||
void setNumChildrenRequiringAppTraversal(const int num);
|
||||
|
||||
ref_ptr<NodeCallback> _cullCallback;
|
||||
|
||||
bool _cullingActive;
|
||||
int _numChildrenWithCullingDisabled;
|
||||
void setNumChildrenWithCullingDisabled(const int num);
|
||||
|
||||
@@ -22,7 +22,13 @@ class SG_EXPORT NodeCallback : public Referenced {
|
||||
|
||||
|
||||
/** Callback method call by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(Node*, NodeVisitor*) {}
|
||||
virtual void operator()(Node* node, NodeVisitor* nv)
|
||||
{
|
||||
// note, callback is repsonsible for scenegraph traversal so
|
||||
// should always include call the traverse(node,nv) to ensure
|
||||
// that the rest of cullbacks and the scene graph are traversed.
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
/** Call any nested callbacks and then traverse the scene graph. */
|
||||
void traverse(Node* node,NodeVisitor* nv);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <osg/Switch>
|
||||
#include <osg/LightSource>
|
||||
#include <osg/Transform>
|
||||
#include <osg/Projection>
|
||||
#include <osg/Impostor>
|
||||
|
||||
#include <osgUtil/Export>
|
||||
@@ -33,17 +34,18 @@ class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void apply(osg::Node& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::Node& node) { handle_callbacks_and_traverse(node); }
|
||||
|
||||
virtual void apply(osg::Geode& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::Billboard& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::LightSource& node){ handle_callbacks(node); }
|
||||
virtual void apply(osg::Geode& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::Billboard& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::LightSource& node){ handle_callbacks_and_traverse(node); }
|
||||
|
||||
virtual void apply(osg::Group& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::Transform& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::Switch& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::LOD& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::Impostor& node) { handle_callbacks(node); }
|
||||
virtual void apply(osg::Group& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::Transform& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::Projection& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::Switch& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::LOD& node) { handle_callbacks_and_traverse(node); }
|
||||
virtual void apply(osg::Impostor& node) { handle_callbacks_and_traverse(node); }
|
||||
|
||||
|
||||
protected:
|
||||
@@ -54,7 +56,7 @@ class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor
|
||||
/** prevent unwanted copy operator.*/
|
||||
AppVisitor& operator = (const AppVisitor&) { return *this; }
|
||||
|
||||
inline void handle_callbacks(osg::Node& node)
|
||||
inline void handle_callbacks_and_traverse(osg::Node& node)
|
||||
{
|
||||
osg::NodeCallback* callback = node.getAppCallback();
|
||||
if (callback) (*callback)(&node,this);
|
||||
|
||||
@@ -183,6 +183,20 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
|
||||
/** prevent unwanted copy operator.*/
|
||||
CullVisitor& operator = (const CullVisitor&) { return *this; }
|
||||
|
||||
inline void handle_cull_callbacks_and_traverse(osg::Node& node)
|
||||
{
|
||||
osg::NodeCallback* callback = node.getCullCallback();
|
||||
if (callback) (*callback)(&node,this);
|
||||
else 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 acceptNode->accept(*this);
|
||||
}
|
||||
|
||||
inline osg::Matrix* getCurrentMatrix()
|
||||
{
|
||||
return _modelviewStack.back().get();
|
||||
|
||||
@@ -261,7 +261,19 @@ void set2dScene(osg::Group* rootNode)
|
||||
|
||||
}
|
||||
|
||||
struct MyCallback : public osg::NodeCallback
|
||||
{
|
||||
|
||||
MyCallback(const std::string& str):_message(str) {}
|
||||
|
||||
virtual void operator() (osg::Node* node,osg::NodeVisitor* nv)
|
||||
{
|
||||
std::cout<<"In my callback '"<<_message<<"'"<<std::endl;
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
std::string _message;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -328,6 +340,8 @@ int main( int argc, char **argv )
|
||||
set2dScene(modelview_abs);
|
||||
|
||||
projection->addChild(modelview_abs);
|
||||
projection->setAppCallback(osgNew MyCallback("App callback"));
|
||||
projection->setCullCallback(osgNew MyCallback("Cull callback"));
|
||||
|
||||
group->addChild(projection);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ Node::Node(const Node& node,const CopyOp& copyop):
|
||||
_parents(), // leave empty as parentList is managed by Group.
|
||||
_appCallback(node._appCallback),
|
||||
_numChildrenRequiringAppTraversal(0), // assume no children yet.
|
||||
_cullCallback(node._cullCallback),
|
||||
_cullingActive(node._cullingActive),
|
||||
_numChildrenWithCullingDisabled(0), // assume no children yet.
|
||||
_userData(copyop(node._userData.get())),
|
||||
|
||||
@@ -350,7 +350,7 @@ void CullVisitor::apply(Node& node)
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
// pop the node's state off the geostate stack.
|
||||
if (node_state) popStateSet();
|
||||
@@ -551,7 +551,7 @@ void CullVisitor::apply(Group& node)
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
@@ -581,7 +581,7 @@ void CullVisitor::apply(Transform& node)
|
||||
node.getLocalToWorldMatrix(*matrix,this);
|
||||
pushModelViewMatrix(matrix.get());
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
popModelViewMatrix();
|
||||
|
||||
@@ -612,7 +612,7 @@ void CullVisitor::apply(Projection& node)
|
||||
*matrix = node.getMatrix();
|
||||
pushProjectionMatrix(matrix.get());
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
popProjectionMatrix();
|
||||
|
||||
@@ -649,7 +649,7 @@ void CullVisitor::apply(LOD& node)
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
//notify(INFO) << "selecting child "<<eval<< std::endl;
|
||||
node.getChild(eval)->accept(*this);
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
@@ -667,7 +667,7 @@ void CullVisitor::apply(osg::EarthSky& node)
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
traverse(node);
|
||||
handle_cull_callbacks_and_traverse(node);
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
@@ -708,13 +708,13 @@ void CullVisitor::apply(Impostor& node)
|
||||
{
|
||||
// outwith the impostor distance threshold therefore simple
|
||||
// traverse the appropriate child of the LOD.
|
||||
node.getChild(eval)->accept(*this);
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
}
|
||||
else if (_viewportStack.empty())
|
||||
{
|
||||
// need to use impostor but no valid viewport is defined to simply
|
||||
// default to using the LOD child as above.
|
||||
node.getChild(eval)->accept(*this);
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -799,7 +799,7 @@ void CullVisitor::apply(Impostor& node)
|
||||
{
|
||||
// no impostor has been selected or created so default to
|
||||
// traversing the usual LOD selected child.
|
||||
node.getChild(eval)->accept(*this);
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -973,7 +973,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
{
|
||||
|
||||
// traversing the usual LOD selected child.
|
||||
node.getChild(eval)->accept(*this);
|
||||
handle_cull_callbacks_and_accept(node,node.getChild(eval));
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user