diff --git a/include/osg/Node b/include/osg/Node index 08c6cd254..77c06e08a 100644 --- a/include/osg/Node +++ b/include/osg/Node @@ -95,6 +95,14 @@ class OSG_EXPORT Node : public Object /** return the name of the node's class type.*/ virtual const char* className() const { return "Node"; } + /** Convert 'this' into a Node pointer if Object is a Node, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual Node* asNode() { return this; } + + /** convert 'const this' into a const Node pointer if Object is a Node, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const Node* asNode() const { return this; } + /** convert 'this' into a Drawable pointer if Node is a Drawable, otherwise return 0. * Equivalent to dynamic_cast(this).*/ virtual Drawable* asDrawable() { return 0; } diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 373ff4c1e..2b0bb6177 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -96,6 +96,15 @@ class OSG_EXPORT NodeVisitor : public virtual Object META_Object(osg, NodeVisitor) + /** Convert 'this' into a NodeVisitor pointer if Object is a NodeVisitor, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual NodeVisitor* asNodeVisitor() { return this; } + + /** convert 'const this' into a const NodeVisitor pointer if Object is a NodeVisitor, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const NodeVisitor* asNodeVisitor() const { return this; } + + /** Method to call to reset visitor. Useful if your visitor accumulates state during a traversal, and you plan to reuse the visitor. To flush that state for the next traversal: call reset() prior diff --git a/include/osg/Object b/include/osg/Object index be5f144d0..4a9c1e1a8 100644 --- a/include/osg/Object +++ b/include/osg/Object @@ -27,6 +27,10 @@ namespace osg { // forward declare class State; class UserDataContainer; +class Node; +class NodeVisitor; +class StateAttribute; +class Uniform; #define _ADDQUOTES(def) #def #define ADDQUOTES(def) _ADDQUOTES(def) @@ -88,6 +92,39 @@ class OSG_EXPORT Object : public Referenced /** return the compound class name that combines the library name and class name.*/ std::string getCompoundClassName() const { return std::string(libraryName()) + std::string("::") + std::string(className()); } + + + /** Convert 'this' into a Node pointer if Object is a Node, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual Node* asNode() { return 0; } + + /** convert 'const this' into a const Node pointer if Object is a Node, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const Node* asNode() const { return 0; } + + /** Convert 'this' into a NodeVisitor pointer if Object is a NodeVisitor, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual NodeVisitor* asNodeVisitor() { return 0; } + + /** convert 'const this' into a const NodeVisitor pointer if Object is a NodeVisitor, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const NodeVisitor* asNodeVisitor() const { return 0; } + + /** Convert 'this' into a StateAttribute pointer if Object is a StateAttribute, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual StateAttribute* asStateAttribute() { return 0; } + + /** convert 'const this' into a const StateAttribute pointer if Object is a StateAttribute, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const StateAttribute* asStateAttribute() const { return 0; } + + /** Convert 'this' into a Uniform pointer if Object is a Uniform, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual Uniform* asUniform() { return 0; } + + /** convert 'const this' into a const Uniform pointer if Object is a Uniform, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const Uniform* asUniform() const { return 0; } /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ diff --git a/include/osg/StateAttribute b/include/osg/StateAttribute index dee906af7..da01efa15 100644 --- a/include/osg/StateAttribute +++ b/include/osg/StateAttribute @@ -235,6 +235,14 @@ class OSG_EXPORT StateAttribute : public Object virtual const char* className() const { return "StateAttribute"; } + /** Convert 'this' into a StateAttribute pointer if Object is a StateAttribute, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual StateAttribute* asStateAttribute() { return this; } + + /** convert 'const this' into a const StateAttribute pointer if Object is a StateAttribute, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const StateAttribute* asStateAttribute() const { return this; } + /** Fast alternative to dynamic_cast<> for determining if state attribute is a Texture.*/ virtual Texture* asTexture() { return 0; } diff --git a/include/osg/Uniform b/include/osg/Uniform index 23c67e1d9..134897a6e 100644 --- a/include/osg/Uniform +++ b/include/osg/Uniform @@ -551,7 +551,15 @@ class OSG_EXPORT Uniform : public Object META_Object(osg, Uniform); + /** Convert 'this' into a Uniform pointer if Object is a Uniform, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual Uniform* asUniform() { return this; } + /** convert 'const this' into a const Uniform pointer if Object is a Uniform, otherwise return 0. + * Equivalent to dynamic_cast(this).*/ + virtual const Uniform* asUniform() const { return this; } + + /** Set the type of glUniform, ensuring it is only set once.*/ bool setType( Type t ); diff --git a/src/osg/Callback.cpp b/src/osg/Callback.cpp index 13e8aa7f2..c908c088b 100644 --- a/src/osg/Callback.cpp +++ b/src/osg/Callback.cpp @@ -25,13 +25,8 @@ bool Callback::traverse(Object* object, Object* data) if (_nestedCallback.valid()) return _nestedCallback->run(object, data); else { -#if 1 - osg::Node* node = dynamic_cast(object); - osg::NodeVisitor* nv = dynamic_cast(data); -#else - osg::Node* node = object ? data->asNode() : 0; + osg::Node* node = object ? object->asNode() : 0; osg::NodeVisitor* nv = data ? data->asNodeVisitor() : 0; -#endif if (node && nv) { nv->traverse(*node); @@ -69,8 +64,9 @@ bool CallbackObject::run(osg::Object* object, osg::Parameters& inputParameters, // bool NodeCallback::run(osg::Object* object, osg::Object* data) { - osg::Node* node = dynamic_cast(object); - osg::NodeVisitor* nv = dynamic_cast(data); + osg::Node* node = object ? object->asNode() : 0; + osg::NodeVisitor* nv = data ? data->asNodeVisitor() : 0; + if (node && nv) { operator()(node, nv); @@ -95,8 +91,8 @@ void NodeCallback::operator()(Node* node, NodeVisitor* nv) // bool StateAttributeCallback::run(osg::Object* object, osg::Object* data) { - osg::StateAttribute* sa = dynamic_cast(object); - osg::NodeVisitor* nv = dynamic_cast(data); + osg::StateAttribute* sa = object ? object->asStateAttribute() : 0; + osg::NodeVisitor* nv = data ? data->asNodeVisitor() : 0; if (sa && nv) { operator()(sa, nv); @@ -114,8 +110,8 @@ bool StateAttributeCallback::run(osg::Object* object, osg::Object* data) // bool UniformCallback::run(osg::Object* object, osg::Object* data) { - osg::Uniform* uniform = dynamic_cast(object); - osg::NodeVisitor* nv = dynamic_cast(data); + osg::Uniform* uniform = object ? object->asUniform() : 0; + osg::NodeVisitor* nv = data ? data->asNodeVisitor() : 0; if (uniform && nv) { operator()(uniform, nv);