2005-04-15 05:41:28 +08:00
|
|
|
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
|
2003-01-22 00:45:36 +08:00
|
|
|
*
|
|
|
|
* 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-10-04 23:12:57 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
#ifndef OSG_GROUP
|
|
|
|
#define OSG_GROUP 1
|
|
|
|
|
|
|
|
#include <osg/Node>
|
|
|
|
#include <osg/NodeVisitor>
|
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
2003-07-09 22:55:39 +08:00
|
|
|
typedef std::vector< ref_ptr<Node> > NodeList;
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** General group node which maintains a list of children.
|
2004-09-13 23:14:11 +08:00
|
|
|
* Children are reference counted. This allows children to be shared
|
|
|
|
* with memory management handled automatically via osg::Referenced.
|
2001-01-11 00:32:10 +08:00
|
|
|
*/
|
2005-04-12 01:14:17 +08:00
|
|
|
class OSG_EXPORT Group : public Node
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
public :
|
|
|
|
|
|
|
|
|
|
|
|
Group();
|
|
|
|
|
2004-09-13 23:14:11 +08:00
|
|
|
/** Copy constructor using CopyOp to manage deep vs shallow copy. */
|
2002-01-29 22:04:06 +08:00
|
|
|
Group(const Group&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
Added support for shallow and deep copy of nodes, drawables and state, via a
copy constructor which takes an optional Cloner object, and the old
osg::Object::clone() has changed so that it now requires a Cloner as paramter.
This is passed on to the copy constructor to help control the shallow vs
deep copying. The old functionality of clone() which was clone of type has
been renamed to cloneType().
Updated all of the OSG to work with these new conventions, implemention all
the required copy constructors etc. A couple of areas will do shallow
copies by design, a couple of other still need to be updated to do either
shallow or deep.
Neither of the shallow or deep copy operations have been tested yet, only
the old functionality of the OSG has been checked so far, such running the
viewer on various demo datasets.
Also fixed a problem in osg::Optimize::RemoveRendundentNodesVisitor which
was not checking that Group didn't have have any attached StateSet's, Callbacks
or UserData. These checks have now been added, which fixes a bug which was
revealled by the new osgscribe demo, this related to removal of group acting
as state decorator.
method
2002-01-29 05:17:01 +08:00
|
|
|
|
2002-06-06 21:25:36 +08:00
|
|
|
META_Node(osg, Group);
|
2001-09-22 10:42:08 +08:00
|
|
|
|
2002-09-12 23:34:31 +08:00
|
|
|
virtual Group* asGroup() { return this; }
|
|
|
|
virtual const Group* asGroup() const { return this; }
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
virtual void traverse(NodeVisitor& nv);
|
|
|
|
|
|
|
|
/** Add Node to Group.
|
2004-09-13 23:14:11 +08:00
|
|
|
* If node is not NULL and is not contained in Group then increment its
|
|
|
|
* reference count, add it to the child list and dirty the bounding
|
|
|
|
* sphere to force it to recompute on next getBound() and return true for success.
|
|
|
|
* Otherwise return false. Scene nodes can't be added as child nodes.
|
|
|
|
*/
|
2001-01-11 00:32:10 +08:00
|
|
|
virtual bool addChild( Node *child );
|
|
|
|
|
2003-07-10 21:11:25 +08:00
|
|
|
/** Insert Node to Group at specific location.
|
2004-09-13 23:14:11 +08:00
|
|
|
* The new child node is inserted into the child list
|
|
|
|
* before the node at the specified index. No nodes
|
|
|
|
* are removed from the group with this operation.
|
|
|
|
*/
|
2003-07-10 21:11:25 +08:00
|
|
|
virtual bool insertChild( unsigned int index, Node *child );
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Remove Node from Group.
|
2004-09-13 23:14:11 +08:00
|
|
|
* If Node is contained in Group then remove it from the child
|
|
|
|
* list, decrement its reference count, and dirty the
|
|
|
|
* bounding sphere to force it to recompute on next getBound() and
|
|
|
|
* return true for success. If Node is not found then return false
|
|
|
|
* and do not change the reference count of the Node.
|
2006-05-02 17:45:31 +08:00
|
|
|
* Note, do not override, only override removeChildren(,) is required.
|
2004-09-13 23:14:11 +08:00
|
|
|
*/
|
2006-05-02 17:45:31 +08:00
|
|
|
inline bool removeChild( Node *child )
|
|
|
|
{
|
|
|
|
unsigned int pos = getChildIndex(child);
|
|
|
|
if (pos<_children.size()) return removeChildren(pos,1);
|
|
|
|
else return false;
|
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2006-05-02 17:45:31 +08:00
|
|
|
/** Remove Node from Group.
|
|
|
|
* If Node is contained in Group then remove it from the child
|
|
|
|
* list, decrement its reference count, and dirty the
|
|
|
|
* bounding sphere to force it to recompute on next getBound() and
|
|
|
|
* return true for success. If Node is not found then return false
|
|
|
|
* and do not change the reference count of the Node.
|
|
|
|
* Note, do not override, only override removeChildren(,) is required.
|
|
|
|
*/
|
2006-05-05 03:36:30 +08:00
|
|
|
inline bool removeChild( unsigned int pos, unsigned int numChildrenToRemove=1 )
|
2006-05-02 17:45:31 +08:00
|
|
|
{
|
2006-05-05 03:36:30 +08:00
|
|
|
if (pos<_children.size()) return removeChildren(pos,numChildrenToRemove);
|
2006-05-02 17:45:31 +08:00
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Remove children from Group.
|
|
|
|
* Note, must be override by subclasses of Group which add per child attributes.*/
|
|
|
|
virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove);
|
2002-12-08 05:18:12 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
/** Replace specified Node with another Node.
|
2004-09-13 23:14:11 +08:00
|
|
|
* Equivalent to setChild(getChildIndex(orignChild),node)
|
|
|
|
* See docs for setChild for futher details on implementation.
|
2004-09-22 01:26:08 +08:00
|
|
|
*/
|
2002-11-19 18:56:59 +08:00
|
|
|
virtual bool replaceChild( Node *origChild, Node* newChild );
|
|
|
|
|
2004-09-13 23:14:11 +08:00
|
|
|
/** Return the number of chilren nodes. */
|
2002-11-19 18:56:59 +08:00
|
|
|
inline unsigned int getNumChildren() const { return _children.size(); }
|
|
|
|
|
2004-09-13 23:14:11 +08:00
|
|
|
/** Set child node at position i.
|
|
|
|
* Return true if set correctly, false on failure (if node==NULL || i is out of range).
|
|
|
|
* When Set can be successful applied, the algorithm is : decrement the reference count origNode and increment the
|
|
|
|
* reference count of newNode, and dirty the bounding sphere
|
|
|
|
* to force it to recompute on next getBound() and return true.
|
|
|
|
* If origNode is not found then return false and do not
|
|
|
|
* add newNode. If newNode is NULL then return false and do
|
|
|
|
* not remove origNode. Also returns false if newChild is a Scene node.
|
|
|
|
*/
|
2002-11-19 18:56:59 +08:00
|
|
|
virtual bool setChild( unsigned int i, Node* node );
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2004-09-13 23:14:11 +08:00
|
|
|
/** Return child node at position i. */
|
2002-11-19 18:56:59 +08:00
|
|
|
inline Node* getChild( unsigned int i ) { return _children[i].get(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2004-09-13 23:14:11 +08:00
|
|
|
/** Return child node at position i. */
|
2002-11-19 18:56:59 +08:00
|
|
|
inline const Node* getChild( unsigned int i ) const { return _children[i].get(); }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2004-09-13 23:14:11 +08:00
|
|
|
/** Return true if node is contained within Group. */
|
2001-09-20 05:08:56 +08:00
|
|
|
inline bool containsNode( const Node* node ) const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
|
2003-07-09 22:55:39 +08:00
|
|
|
for (NodeList::const_iterator itr=_children.begin();
|
2001-01-11 00:32:10 +08:00
|
|
|
itr!=_children.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
if (itr->get()==node) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
/** Get the index number of child, return a value between
|
2002-10-07 04:33:13 +08:00
|
|
|
* 0 and _children.size()-1 if found, if not found then
|
2004-09-13 23:14:11 +08:00
|
|
|
* return _children.size().
|
2005-11-18 01:44:48 +08:00
|
|
|
*/
|
2002-11-21 17:07:11 +08:00
|
|
|
inline unsigned int getChildIndex( const Node* node ) const
|
2002-10-07 04:33:13 +08:00
|
|
|
{
|
2002-11-19 18:56:59 +08:00
|
|
|
for (unsigned int childNum=0;childNum<_children.size();++childNum)
|
2002-10-07 04:33:13 +08:00
|
|
|
{
|
2002-11-19 18:56:59 +08:00
|
|
|
if (_children[childNum]==node) return childNum;
|
2002-10-07 04:33:13 +08:00
|
|
|
}
|
|
|
|
return _children.size(); // node not found.
|
|
|
|
}
|
|
|
|
|
2005-05-08 04:47:09 +08:00
|
|
|
/** If State is non-zero, this function releases any associated OpenGL objects for
|
|
|
|
* the specified graphics context. Otherwise, releases OpenGL objexts
|
|
|
|
* for all graphics contexts. */
|
|
|
|
virtual void releaseGLObjects(osg::State* = 0) const;
|
|
|
|
|
2005-05-16 04:31:22 +08:00
|
|
|
virtual BoundingSphere computeBound() const;
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
protected:
|
|
|
|
|
|
|
|
virtual ~Group();
|
|
|
|
|
2004-01-06 04:45:28 +08:00
|
|
|
virtual void childRemoved(unsigned int /*pos*/, unsigned int /*numChildrenToRemove*/) {}
|
|
|
|
virtual void childInserted(unsigned int /*pos*/) {}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2003-07-09 22:55:39 +08:00
|
|
|
NodeList _children;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2002-02-03 20:33:41 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
#endif
|