OpenSceneGraph/include/osg/Node

540 lines
24 KiB
Plaintext
Raw Normal View History

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
2001-01-11 00:32:10 +08:00
#ifndef OSG_NODE
#define OSG_NODE 1
#include <osg/Object>
#include <osg/StateSet>
2001-01-11 00:32:10 +08:00
#include <osg/BoundingSphere>
2014-05-14 18:19:43 +08:00
#include <osg/BoundingBox>
#include <osg/Callback>
2001-01-11 00:32:10 +08:00
#include <string>
#include <vector>
// forward declare osgTerrrain::Terrain to enable declaration of asTerrain() method.
namespace osgTerrain {
class Terrain;
}
2001-01-11 00:32:10 +08:00
namespace osg {
// forcing declare classes to enable declaration of as*() methods.
2001-01-11 00:32:10 +08:00
class NodeVisitor;
class Drawable;
class Geometry;
2001-01-11 00:32:10 +08:00
class Group;
class Transform;
class Node;
class Switch;
class Geode;
2011-09-14 18:22:04 +08:00
class Camera;
class OccluderNode;
/** A vector of Nodes pointers which is used to describe the path from a root node to a descendant.*/
typedef std::vector< Node* > NodePath;
/** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
typedef std::vector< NodePath > NodePathList;
/** A vector of NodePath, typically used to describe all the paths from a node to the potential root nodes it has.*/
typedef std::vector< Matrix > MatrixList;
2001-01-11 00:32:10 +08:00
2014-05-14 18:19:43 +08:00
2001-09-22 10:42:08 +08:00
/** META_Node macro define the standard clone, isSameKindAs, className
* and accept methods. Use when subclassing from Node to make it
* more convenient to define the required pure virtual methods.*/
#define META_Node(library,name) \
virtual osg::Object* cloneType() const { return new name (); } \
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const name *>(obj)!=NULL; } \
2001-09-22 10:42:08 +08:00
virtual const char* className() const { return #name; } \
virtual const char* libraryName() const { return #library; } \
virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } } \
2001-09-22 10:42:08 +08:00
2001-01-11 00:32:10 +08:00
/** Base class for all internal nodes in the scene graph.
Provides interface for most common node operations (Composite Pattern).
*/
class OSG_EXPORT Node : public Object
2001-01-11 00:32:10 +08:00
{
public:
/** Construct a node.
Initialize the parent list to empty, node name to "" and
2001-01-11 00:32:10 +08:00
bounding sphere dirty flag to true.*/
Node();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
Node(const Node&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
/** clone an object of the same type as the node.*/
virtual Object* cloneType() const { return new Node(); }
/** return a clone of a node, with Object* return type.*/
virtual Object* clone(const CopyOp& copyop) const { return new Node(*this,copyop); }
2001-01-11 00:32:10 +08:00
/** return true if this and obj are of the same kind of object.*/
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Node*>(obj)!=NULL; }
2001-01-11 00:32:10 +08:00
/** return the name of the node's library.*/
virtual const char* libraryName() const { return "osg"; }
2001-01-11 00:32:10 +08:00
/** 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<Node*>(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<const Node*>(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<Group*>(this).*/
virtual Drawable* asDrawable() { return 0; }
/** convert 'const this' into a const Drawable pointer if Node is a Drawable, otherwise return 0.
* Equivalent to dynamic_cast<const Group*>(this).*/
virtual const Drawable* asDrawable() const { return 0; }
/** convert 'this' into a Geometry pointer if Node is a Geometry, otherwise return 0.
* Equivalent to dynamic_cast<Group*>(this).*/
virtual Geometry* asGeometry() { return 0; }
/** convert 'const this' into a const Geometry pointer if Node is a Geometry, otherwise return 0.
* Equivalent to dynamic_cast<const Group*>(this).*/
virtual const Geometry* asGeometry() const { return 0; }
/** convert 'this' into a Group pointer if Node is a Group, otherwise return 0.
* Equivalent to dynamic_cast<Group*>(this).*/
virtual Group* asGroup() { return 0; }
/** convert 'const this' into a const Group pointer if Node is a Group, otherwise return 0.
* Equivalent to dynamic_cast<const Group*>(this).*/
virtual const Group* asGroup() const { return 0; }
/** Convert 'this' into a Transform pointer if Node is a Transform, otherwise return 0.
* Equivalent to dynamic_cast<Transform*>(this).*/
virtual Transform* asTransform() { return 0; }
/** convert 'const this' into a const Transform pointer if Node is a Transform, otherwise return 0.
* Equivalent to dynamic_cast<const Transform*>(this).*/
virtual const Transform* asTransform() const { return 0; }
/** Convert 'this' into an OccluderNode pointer if Node is an OccluderNode, otherwise return 0.
* Equivalent to dynamic_cast<OccluderNode*>(this).*/
virtual OccluderNode* asOccluderNode() { return 0; }
/** Convert 'const this' into a const OccluderNode pointer if Node is an OccluderNode, otherwise return 0.
* Equivalent to dynamic_cast<const OccluderNode*>(this).*/
virtual const OccluderNode* asOccluderNode() const { return 0; }
/** Convert 'this' into a Switch pointer if Node is a Switch, otherwise return 0.
* Equivalent to dynamic_cast<Switch*>(this).*/
virtual Switch* asSwitch() { return 0; }
/** convert 'const this' into a const Switch pointer if Node is a Switch, otherwise return 0.
* Equivalent to dynamic_cast<const Switch*>(this).*/
virtual const Switch* asSwitch() const { return 0; }
/** Convert 'this' into a Geode pointer if Node is a Geode, otherwise return 0.
* Equivalent to dynamic_cast<Geode*>(this).*/
virtual Geode* asGeode() { return 0; }
/** convert 'const this' into a const Geode pointer if Node is a Geode, otherwise return 0.
* Equivalent to dynamic_cast<const Geode*>(this).*/
virtual const Geode* asGeode() const { return 0; }
/** Convert 'this' into a Transform pointer if Node is a Terrain, otherwise return 0.
* Equivalent to dynamic_cast<Terrrain*>(this).*/
virtual osgTerrain::Terrain* asTerrain() { return 0; }
/** convert 'const this' into a const Terrain pointer if Node is a Terrain, otherwise return 0.
* Equivalent to dynamic_cast<const Terrain*>(this).*/
virtual const osgTerrain::Terrain* asTerrain() const { return 0; }
2001-01-11 00:32:10 +08:00
/** Visitor Pattern : calls the apply method of a NodeVisitor with this node's type.*/
virtual void accept(NodeVisitor& nv);
/** Traverse upwards : calls parents' accept method with NodeVisitor.*/
virtual void ascend(NodeVisitor& nv);
/** Traverse downwards : calls children's accept method with NodeVisitor.*/
virtual void traverse(NodeVisitor& /*nv*/) {}
2001-01-11 00:32:10 +08:00
/** A vector of osg::Group pointers which is used to store the parent(s) of node.*/
typedef std::vector<Group*> ParentList;
2001-01-11 00:32:10 +08:00
/** Get the parent list of node. */
inline const ParentList& getParents() const { return _parents; }
/** Get the a copy of parent list of node. A copy is returned to
2001-09-22 10:42:08 +08:00
* prevent modification of the parent list.*/
inline ParentList getParents() { return _parents; }
inline Group* getParent(unsigned int i) { return _parents[i]; }
2001-01-11 00:32:10 +08:00
/**
* Get a single const parent of node.
2001-01-11 00:32:10 +08:00
* @param i index of the parent to get.
* @return the parent i.
*/
inline const Group* getParent(unsigned int i) const { return _parents[i]; }
2001-01-11 00:32:10 +08:00
/**
* Get the number of parents of node.
* @return the number of parents of this node.
*/
2009-01-30 18:55:28 +08:00
inline unsigned int getNumParents() const { return static_cast<unsigned int>(_parents.size()); }
2001-01-11 00:32:10 +08:00
/** Get the list of node paths parent paths.
2018-04-21 00:18:22 +08:00
* The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specified node. */
NodePathList getParentalNodePaths(osg::Node* haltTraversalAtNode=0) const;
/** Get the list of matrices that transform this node from local coordinates to world coordinates.
2018-04-21 00:18:22 +08:00
* The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specified node. */
MatrixList getWorldMatrices(const osg::Node* haltTraversalAtNode=0) const;
2001-01-11 00:32:10 +08:00
/** Set update node callback, called during update traversal. */
void setUpdateCallback(Callback* nc);
2001-09-22 10:42:08 +08:00
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void setUpdateCallback(const ref_ptr<T>& nc) { setUpdateCallback(nc.get()); }
/** Get update node callback, called during update traversal. */
inline Callback* getUpdateCallback() { return _updateCallback.get(); }
2001-09-22 10:42:08 +08:00
/** Get const update node callback, called during update traversal. */
inline const Callback* getUpdateCallback() const { return _updateCallback.get(); }
/** Convenience method that sets the update callback of the node if it doesn't exist, or nest it into the existing one. */
inline void addUpdateCallback(Callback* nc) {
if (nc != NULL) {
if (_updateCallback.valid()) _updateCallback->addNestedCallback(nc);
else setUpdateCallback(nc);
}
}
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void addUpdateCallback(const ref_ptr<T>& nc) { addUpdateCallback(nc.get()); }
/** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
inline void removeUpdateCallback(Callback* nc) {
if (nc != NULL && _updateCallback.valid()) {
if (_updateCallback == nc)
{
ref_ptr<osg::Callback> new_nested_callback = nc->getNestedCallback();
nc->setNestedCallback(0);
setUpdateCallback(new_nested_callback.get());
}
else _updateCallback->removeNestedCallback(nc);
}
}
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void removeUpdateCallback(const ref_ptr<T>& nc) { removeUpdateCallback(nc.get()); }
/** Get the number of Children of this node which require Update traversal,
* since they have an Update Callback attached to them or their children.*/
inline unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; }
2001-09-22 10:42:08 +08:00
/** Set event node callback, called during event traversal. */
void setEventCallback(Callback* nc);
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void setEventCallback(const ref_ptr<T>& nc) { setEventCallback(nc.get()); }
/** Get event node callback, called during event traversal. */
inline Callback* getEventCallback() { return _eventCallback.get(); }
/** Get const event node callback, called during event traversal. */
inline const Callback* getEventCallback() const { return _eventCallback.get(); }
/** Convenience method that sets the event callback of the node if it doesn't exist, or nest it into the existing one. */
inline void addEventCallback(Callback* nc) {
if (nc != NULL) {
if (_eventCallback.valid()) _eventCallback->addNestedCallback(nc);
else setEventCallback(nc);
}
}
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void addEventCallback(const ref_ptr<T>& nc) { addEventCallback(nc.get()); }
/** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
inline void removeEventCallback(Callback* nc) {
if (nc != NULL && _eventCallback.valid()) {
if (_eventCallback == nc)
{
ref_ptr<osg::Callback> new_nested_callback = nc->getNestedCallback();
nc->setNestedCallback(0);
setEventCallback(new_nested_callback.get()); // replace the callback by the nested one
}
else _eventCallback->removeNestedCallback(nc);
}
}
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void removeEventCallback(const ref_ptr<T>& nc) { removeEventCallback(nc.get()); }
/** Get the number of Children of this node which require Event traversal,
* since they have an Event Callback attached to them or their children.*/
inline unsigned int getNumChildrenRequiringEventTraversal() const { return _numChildrenRequiringEventTraversal; }
/** Set cull node callback, called during cull traversal. */
void setCullCallback(Callback* nc) { _cullCallback = nc; }
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void setCullCallback(const ref_ptr<T>& nc) { setCullCallback(nc.get()); }
2002-11-11 16:04:40 +08:00
/** Get cull node callback, called during cull traversal. */
inline Callback* getCullCallback() { return _cullCallback.get(); }
2002-11-11 16:04:40 +08:00
/** Get const cull node callback, called during cull traversal. */
inline const Callback* getCullCallback() const { return _cullCallback.get(); }
/** Convenience method that sets the cull callback of the node if it doesn't exist, or nest it into the existing one. */
inline void addCullCallback(Callback* nc) {
if (nc != NULL) {
if (_cullCallback.valid()) _cullCallback->addNestedCallback(nc);
else setCullCallback(nc);
}
}
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void addCullCallback(const ref_ptr<T>& nc) { addCullCallback(nc.get()); }
/** Convenience method that removes a given callback from a node, even if that callback is nested. There is no error return in case the given callback is not found. */
inline void removeCullCallback(Callback* nc) {
if (nc != NULL && _cullCallback.valid()) {
if (_cullCallback == nc)
{
ref_ptr<osg::Callback> new_nested_callback = nc->getNestedCallback();
nc->setNestedCallback(0);
setCullCallback(new_nested_callback.get()); // replace the callback by the nested one
}
else _cullCallback->removeNestedCallback(nc);
}
}
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void removeCullCallback(const ref_ptr<T>& nc) { removeCullCallback(nc.get()); }
/** Set the view frustum/small feature culling of this node to be active or inactive.
* The default value is true for _cullingActive. Used as a guide
* to the cull traversal.*/
void setCullingActive(bool active);
/** Get the view frustum/small feature _cullingActive flag for this node. Used as a guide
* to the cull traversal.*/
inline bool getCullingActive() const { return _cullingActive; }
/** Get the number of Children of this node which have culling disabled.*/
inline unsigned int getNumChildrenWithCullingDisabled() const { return _numChildrenWithCullingDisabled; }
/** Return true if this node can be culled by view frustum, occlusion or small feature culling during the cull traversal.
* Note, returns true only if no children have culling disabled, and the local _cullingActive flag is true.*/
inline bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && getBound().valid(); }
/** Get the number of Children of this node which are or have OccluderNode's.*/
inline unsigned int getNumChildrenWithOccluderNodes() const { return _numChildrenWithOccluderNodes; }
/** return true if this node is an OccluderNode or the subgraph below this node are OccluderNodes.*/
bool containsOccluderNodes() const;
2001-01-11 00:32:10 +08:00
/**
* This is a set of bits (flags) that represent the Node.
* The default value is 0xffffffff (all bits set).
*
* The most common use of these is during traversal of the scene graph.
2009-07-28 14:00:23 +08:00
* For instance, when traversing the scene graph the osg::NodeVisitor does a bitwise
2011-12-24 00:14:51 +08:00
* AND of its TraversalMask with the Node's NodeMask to
* determine if the Node should be processed/traversed.
*
2009-07-28 14:00:23 +08:00
* For example, if a Node has a NodeMask value of 0x02 (only 2nd bit set)
* and the osg::Camera has a CullMask of 0x4 (2nd bit not set) then during cull traversal,
* which takes it's TraversalMask from the Camera's CullMask, the node and any children
* would be ignored and thereby treated as "culled" and thus not rendered.
* Conversely, if the osg::Camera CullMask were 0x3 (2nd bit set) then the node
* would be processed and child Nodes would be examined.
*/
2001-01-11 00:32:10 +08:00
typedef unsigned int NodeMask;
/** Set the node mask.*/
inline void setNodeMask(NodeMask nm) { _nodeMask = nm; }
/** Get the node Mask.*/
inline NodeMask getNodeMask() const { return _nodeMask; }
2001-01-11 00:32:10 +08:00
/** Set the node's StateSet.*/
void setStateSet(osg::StateSet* stateset);
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void setStateSet(const osg::ref_ptr<T>& stateset) { setStateSet(stateset.get()); }
2002-05-04 06:47:57 +08:00
/** return the node's StateSet, if one does not already exist create it
* set the node and return the newly created StateSet. This ensures
* that a valid StateSet is always returned and can be used directly.*/
osg::StateSet* getOrCreateStateSet();
2002-05-04 06:47:57 +08:00
/** Return the node's StateSet. returns NULL if a stateset is not attached.*/
inline osg::StateSet* getStateSet() { return _stateset.get(); }
/** Return the node's const StateSet. Returns NULL if a stateset is not attached.*/
inline const osg::StateSet* getStateSet() const { return _stateset.get(); }
/** A vector of std::string's which are used to describe the object.*/
typedef std::vector<std::string> DescriptionList;
/** Set the list of string descriptions.*/
void setDescriptions(const DescriptionList& descriptions);
/** Get the description list of the node.*/
DescriptionList& getDescriptions();
/** Get the const description list of the const node.*/
const DescriptionList& getDescriptions() const;
/** Get a single const description of the const node.*/
const std::string& getDescription(unsigned int i) const;
/** Get a single description of the node.*/
std::string& getDescription(unsigned int i);
/** Get the number of descriptions of the node.*/
unsigned int getNumDescriptions() const;
/** Add a description string to the node.*/
void addDescription(const std::string& desc);
/** Set the initial bounding volume to use when computing the overall bounding volume.*/
void setInitialBound(const osg::BoundingSphere& bsphere) { _initialBound = bsphere; dirtyBound(); }
/** Set the initial bounding volume to use when computing the overall bounding volume.*/
const BoundingSphere& getInitialBound() const { return _initialBound; }
/** Mark this node's bounding sphere dirty.
Forcing it to be computed on the next call to getBound().*/
void dirtyBound();
inline const BoundingSphere& getBound() const
2014-05-14 18:19:43 +08:00
{
if(!_boundingSphereComputed)
{
_boundingSphere = _initialBound;
if (_computeBoundCallback.valid())
_boundingSphere.expandBy(_computeBoundCallback->computeBound(*this));
else
_boundingSphere.expandBy(computeBound());
2014-05-14 18:19:43 +08:00
_boundingSphereComputed = true;
}
return _boundingSphere;
}
2001-01-11 00:32:10 +08:00
/** Compute the bounding sphere around Node's geometry or children.
This method is automatically called by getBound() when the bounding
sphere has been marked dirty via dirtyBound().*/
virtual BoundingSphere computeBound() const;
/** Callback to allow users to override the default computation of bounding volume.*/
struct ComputeBoundingSphereCallback : public osg::Object
{
ComputeBoundingSphereCallback() {}
ComputeBoundingSphereCallback(const ComputeBoundingSphereCallback& org,const CopyOp& copyop):
Object(org, copyop) {}
META_Object(osg,ComputeBoundingSphereCallback);
virtual BoundingSphere computeBound(const osg::Node&) const { return BoundingSphere(); }
};
/** Set the compute bound callback to override the default computeBound.*/
void setComputeBoundingSphereCallback(ComputeBoundingSphereCallback* callback) { _computeBoundCallback = callback; }
Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods, forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 21:42:19 +08:00
template<class T> void setComputeBoundingSphereCallback(const ref_ptr<T>& callback) { setComputeBoundingSphereCallback(callback.get()); }
/** Get the compute bound callback.*/
ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() { return _computeBoundCallback.get(); }
/** Get the const compute bound callback.*/
const ComputeBoundingSphereCallback* getComputeBoundingSphereCallback() const { return _computeBoundCallback.get(); }
2001-01-11 00:32:10 +08:00
/** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
virtual void setThreadSafeRefUnref(bool threadSafe);
/** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int /*maxSize*/);
2001-01-11 00:32:10 +08:00
/** If State is non-zero, this function releases any associated OpenGL objects for
* the specified graphics context. Otherwise, releases OpenGL objects
* for all graphics contexts. */
virtual void releaseGLObjects(osg::State* = 0) const;
2001-01-11 00:32:10 +08:00
protected:
/** Node destructor. Note, is protected so that Nodes cannot
be deleted other than by being dereferenced and the reference
count being zero (see osg::Referenced), preventing the deletion
of nodes which are still in use. This also means that
Nodes cannot be created on stack i.e Node node will not compile,
2001-01-11 00:32:10 +08:00
forcing all nodes to be created on the heap i.e Node* node
= new Node().*/
virtual ~Node();
BoundingSphere _initialBound;
ref_ptr<ComputeBoundingSphereCallback> _computeBoundCallback;
mutable BoundingSphere _boundingSphere;
mutable bool _boundingSphereComputed;
2001-01-11 00:32:10 +08:00
void addParent(osg::Group* parent);
void removeParent(osg::Group* parent);
2001-01-11 00:32:10 +08:00
ParentList _parents;
friend class osg::Group;
2002-07-10 23:35:47 +08:00
friend class osg::Drawable;
friend class osg::StateSet;
2001-01-11 00:32:10 +08:00
ref_ptr<Callback> _updateCallback;
unsigned int _numChildrenRequiringUpdateTraversal;
void setNumChildrenRequiringUpdateTraversal(unsigned int num);
2001-09-22 10:42:08 +08:00
ref_ptr<Callback> _eventCallback;
unsigned int _numChildrenRequiringEventTraversal;
void setNumChildrenRequiringEventTraversal(unsigned int num);
ref_ptr<Callback> _cullCallback;
bool _cullingActive;
unsigned int _numChildrenWithCullingDisabled;
void setNumChildrenWithCullingDisabled(unsigned int num);
unsigned int _numChildrenWithOccluderNodes;
void setNumChildrenWithOccluderNodes(unsigned int num);
2001-01-11 00:32:10 +08:00
NodeMask _nodeMask;
ref_ptr<StateSet> _stateset;
2001-01-11 00:32:10 +08:00
};
}
2001-01-11 00:32:10 +08:00
#endif