Added app callback to Drawable.
This commit is contained in:
parent
b3ac26f3dc
commit
27338f57b1
@ -161,6 +161,38 @@ class SG_EXPORT Drawable : public Object
|
||||
void compile(State& state);
|
||||
|
||||
|
||||
struct AppCallback : public osg::Referenced
|
||||
{
|
||||
/** do customized app code.*/
|
||||
virtual void app(osg::NodeVisitor *visitor, osg::Drawable* drawable) const = 0;
|
||||
};
|
||||
|
||||
/** Set the AppCallback which allows users to attach customize the undating of an object during the app traversal.*/
|
||||
void setAppCallback(AppCallback* ac);
|
||||
|
||||
/** Get the non const AppCallback.*/
|
||||
AppCallback* getAppCallback() { return _appCallback.get(); }
|
||||
|
||||
/** Get the const AppCallback.*/
|
||||
const AppCallback* getAppCallback() const { return _appCallback.get(); }
|
||||
|
||||
|
||||
struct CullCallback : public osg::Referenced
|
||||
{
|
||||
/** do customized cull code.*/
|
||||
virtual bool cull(osg::NodeVisitor *visitor, osg::Drawable* drawable, osg::State *state=NULL) const = 0;
|
||||
};
|
||||
|
||||
/** Set the CullCallback which allows users to attach customize the culling of Drawable during the cull traversal.*/
|
||||
void setCullCallback(CullCallback* cc) { _cullCallback=cc; }
|
||||
|
||||
/** Get the non const CullCallback.*/
|
||||
CullCallback* getCullCallback() { return _cullCallback.get(); }
|
||||
|
||||
/** Get the const CullCallback.*/
|
||||
const CullCallback* getCullCallback() const { return _cullCallback.get(); }
|
||||
|
||||
|
||||
/** Callback attached to an Drawable which allows the users to customize the drawing of an exist Drawable object.
|
||||
* The draw callback is implement as a replacement to the Drawable's own drawImmediateMode() method, if the
|
||||
* the user intends to decorate the exist draw code then simple call the drawable->drawImmediateMode() from
|
||||
@ -181,21 +213,6 @@ class SG_EXPORT Drawable : public Object
|
||||
/** Get the const DrawCallback.*/
|
||||
const DrawCallback* getDrawCallback() const { return _drawCallback.get(); }
|
||||
|
||||
struct CullCallback : public osg::Referenced
|
||||
{
|
||||
/** do customized cull code.*/
|
||||
virtual bool cull(osg::NodeVisitor *visitor, osg::Drawable* drawable, osg::State *state=NULL) const = 0;
|
||||
};
|
||||
|
||||
/** Set the CullCallback which allows users to attach customize the drawing of existing Drawable object.*/
|
||||
void setCullCallback(CullCallback* cc) { _cullCallback=cc; }
|
||||
|
||||
/** Get the non const CullCallback.*/
|
||||
CullCallback* getCullCallback() { return _cullCallback.get(); }
|
||||
|
||||
/** Get the const CullCallback.*/
|
||||
const CullCallback* getCullCallback() const { return _cullCallback.get(); }
|
||||
|
||||
|
||||
/** draw directly ignoring an OpenGL display list which could be attached.
|
||||
* This is the internal draw method which does the drawing itself,
|
||||
@ -310,6 +327,7 @@ class SG_EXPORT Drawable : public Object
|
||||
mutable BoundingBox _bbox;
|
||||
mutable bool _bbox_computed;
|
||||
|
||||
ref_ptr<AppCallback> _appCallback;
|
||||
ref_ptr<DrawCallback> _drawCallback;
|
||||
ref_ptr<CullCallback> _cullCallback;
|
||||
|
||||
|
@ -243,6 +243,7 @@ class SG_EXPORT Node : public Object
|
||||
|
||||
ParentList _parents;
|
||||
friend class osg::Group;
|
||||
friend class osg::Drawable;
|
||||
|
||||
ref_ptr<NodeCallback> _appCallback;
|
||||
int _numChildrenRequiringAppTraversal;
|
||||
|
@ -37,8 +37,9 @@ class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor
|
||||
|
||||
virtual void apply(osg::Node& node) { handle_callbacks_and_traverse(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::Geode& node) { handle_geode_callbacks(node); }
|
||||
virtual void apply(osg::Billboard& node) { handle_geode_callbacks(node); }
|
||||
|
||||
virtual void apply(osg::LightSource& node) { handle_callbacks_and_traverse(node); }
|
||||
|
||||
virtual void apply(osg::Group& node) { handle_callbacks_and_traverse(node); }
|
||||
@ -65,6 +66,20 @@ class OSGUTIL_EXPORT AppVisitor : public osg::NodeVisitor
|
||||
else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node);
|
||||
}
|
||||
|
||||
inline void handle_geode_callbacks(osg::Geode& node)
|
||||
{
|
||||
osg::NodeCallback* callback = node.getAppCallback();
|
||||
if (callback) (*callback)(&node,this);
|
||||
else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node);
|
||||
|
||||
// call the app callbacks on the drawables.
|
||||
for(int i=0;i<node.getNumDrawables();++i)
|
||||
{
|
||||
osg::Drawable::AppCallback* callback = node.getDrawable(i)->getAppCallback();
|
||||
if (callback) callback->app(this,node.getDrawable(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
@ -206,3 +206,22 @@ void Drawable::flushDeletedDisplayLists(uint contextID)
|
||||
s_deletedDisplayListCache.erase(citr);
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::setAppCallback(AppCallback* ac)
|
||||
{
|
||||
if (_appCallback==ac) return;
|
||||
|
||||
int delta = 0;
|
||||
if (_appCallback.valid()) --delta;
|
||||
if (ac) ++delta;
|
||||
|
||||
if (delta!=0)
|
||||
{
|
||||
for(ParentList::iterator itr=_parents.begin();
|
||||
itr!=_parents.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->setNumChildrenRequiringAppTraversal((*itr)->getNumChildrenRequiringAppTraversal()+delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,11 @@ const bool Geode::addDrawable( Drawable *drawable )
|
||||
// register as parent of drawable.
|
||||
drawable->addParent(this);
|
||||
|
||||
if (drawable->getAppCallback())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()+1);
|
||||
}
|
||||
|
||||
dirtyBound();
|
||||
|
||||
return true;
|
||||
@ -59,6 +64,11 @@ const bool Geode::removeDrawable( Drawable *drawable )
|
||||
// remove this Geode from the child parent list.
|
||||
drawable->removeParent(this);
|
||||
|
||||
if (drawable->getAppCallback())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()-1);
|
||||
}
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing drawable's reference count.
|
||||
_drawables.erase(itr);
|
||||
|
||||
@ -77,7 +87,14 @@ const bool Geode::replaceDrawable( Drawable *origDrawable, Drawable *newDrawable
|
||||
DrawableList::iterator itr = findDrawable(origDrawable);
|
||||
if (itr!=_drawables.end())
|
||||
{
|
||||
|
||||
int delta = 0;
|
||||
if (origDrawable->getAppCallback()) --delta;
|
||||
if (newDrawable->getAppCallback()) ++delta;
|
||||
if (delta!=0)
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()+delta);
|
||||
}
|
||||
|
||||
// remove from origDrawable's parent list.
|
||||
origDrawable->removeParent(this);
|
||||
|
||||
@ -88,6 +105,7 @@ const bool Geode::replaceDrawable( Drawable *origDrawable, Drawable *newDrawable
|
||||
// register as parent of child.
|
||||
newDrawable->addParent(this);
|
||||
|
||||
|
||||
dirtyBound();
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user