Added app callback to Drawable.

This commit is contained in:
Robert Osfield 2002-07-10 15:35:47 +00:00
parent b3ac26f3dc
commit 27338f57b1
5 changed files with 89 additions and 18 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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));
}
}
};

View File

@ -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);
}
}
}

View File

@ -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,6 +87,13 @@ 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;