2001-10-22 05:27:40 +08:00
|
|
|
#include <osg/Group>
|
|
|
|
#include <osg/BoundingBox>
|
Added DataVariance enum and set/get fields to osg::Object to help identify
which objects have values that vary over the lifetime of the object (DYNAMIC)
and ones that do not vary (STATIC). Removed the equivalent code in
osg::Transform, StateSet and StateAttribute, as these are now encompassed
by the new DataVariance field.
Removed MatrixMode enum from Matrix, and associated fields/parameters from
osg::Transfrom and osg::NodeVisitor, since MatrixMode was not providing
any useful functionality, but made the interface more complex (MatrixMode
was an experimental API)
Added ReferenceFrame field to osg::Transform which allows users to specify
transforms that are relative to their parents (the default, and previous behavior)
or absolute reference frame, which can be used for HUD's, camera relative
light sources etc etc. Note, the view frustum culling for absolute Transform
are disabled, and all their parents up to the root are also automatically
have view frustum culling disabled. However, once passed an absolute Transform
node culling will return to its default state of on, so you can still cull
underneath an absolute transform, its only the culling above which is disabled.
2002-04-12 07:20:23 +08:00
|
|
|
#include <osg/Transform>
|
2002-06-10 21:50:25 +08:00
|
|
|
#include <osg/OccluderNode>
|
2002-12-08 05:18:12 +08:00
|
|
|
#include <osg/Notify>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <math.h>
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
using namespace osg;
|
|
|
|
|
|
|
|
Group::Group()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2002-01-29 22:04:06 +08:00
|
|
|
Group::Group(const Group& group,const CopyOp& copyop):
|
|
|
|
Node(group,copyop)
|
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
|
|
|
{
|
|
|
|
for(ChildList::const_iterator itr=group._children.begin();
|
|
|
|
itr!=group._children.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2002-01-29 22:04:06 +08:00
|
|
|
Node* child = copyop(itr->get());
|
2002-01-29 20:52:04 +08:00
|
|
|
if (child) addChild(child);
|
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
|
|
|
}
|
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
Group::~Group()
|
|
|
|
{
|
2002-02-09 06:55:21 +08:00
|
|
|
// remove reference to this from children's parent lists.
|
2001-01-11 00:32:10 +08:00
|
|
|
for(ChildList::iterator itr=_children.begin();
|
2001-09-20 05:08:56 +08:00
|
|
|
itr!=_children.end();
|
|
|
|
++itr)
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
2002-02-09 06:55:21 +08:00
|
|
|
(*itr)->removeParent(this);
|
2001-01-11 00:32:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Group::traverse(NodeVisitor& nv)
|
|
|
|
{
|
|
|
|
for(ChildList::iterator itr=_children.begin();
|
2001-09-20 05:08:56 +08:00
|
|
|
itr!=_children.end();
|
|
|
|
++itr)
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
(*itr)->accept(nv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Group::addChild( Node *child )
|
|
|
|
{
|
|
|
|
if (child && !containsNode(child))
|
|
|
|
{
|
|
|
|
// note ref_ptr<> automatically handles incrementing child's reference count.
|
|
|
|
_children.push_back(child);
|
|
|
|
|
|
|
|
// register as parent of child.
|
2002-02-09 06:55:21 +08:00
|
|
|
child->addParent(this);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
dirtyBound();
|
|
|
|
|
2001-09-22 10:42:08 +08:00
|
|
|
// could now require app traversal thanks to the new subgraph,
|
|
|
|
// so need to check and update if required.
|
2002-12-19 23:55:40 +08:00
|
|
|
if (child->getNumChildrenRequiringUpdateTraversal()>0 ||
|
|
|
|
child->getUpdateCallback())
|
2001-09-22 10:42:08 +08:00
|
|
|
{
|
2002-12-19 23:55:40 +08:00
|
|
|
setNumChildrenRequiringUpdateTraversal(
|
|
|
|
getNumChildrenRequiringUpdateTraversal()+1
|
2001-09-22 10:42:08 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2001-10-19 20:56:37 +08:00
|
|
|
// could now require disabling of culling thanks to the new subgraph,
|
|
|
|
// so need to check and update if required.
|
|
|
|
if (child->getNumChildrenWithCullingDisabled()>0 ||
|
|
|
|
!child->getCullingActive())
|
|
|
|
{
|
|
|
|
setNumChildrenWithCullingDisabled(
|
|
|
|
getNumChildrenWithCullingDisabled()+1
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2002-06-10 21:50:25 +08:00
|
|
|
if (child->getNumChildrenWithOccluderNodes()>0 ||
|
|
|
|
dynamic_cast<osg::OccluderNode*>(child))
|
|
|
|
{
|
|
|
|
setNumChildrenWithOccluderNodes(
|
|
|
|
getNumChildrenWithOccluderNodes()+1
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Group::removeChild( Node *child )
|
|
|
|
{
|
2002-12-08 05:18:12 +08:00
|
|
|
return removeChild(getChildIndex(child));
|
|
|
|
}
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2002-12-08 05:18:12 +08:00
|
|
|
bool Group::removeChild(unsigned int pos,unsigned int numChildrenToRemove)
|
|
|
|
{
|
|
|
|
if (pos<_children.size() && numChildrenToRemove>0)
|
|
|
|
{
|
|
|
|
unsigned int endOfRemoveRange = pos+numChildrenToRemove;
|
|
|
|
if (endOfRemoveRange>_children.size())
|
2001-09-22 10:42:08 +08:00
|
|
|
{
|
2002-12-08 05:18:12 +08:00
|
|
|
notify(DEBUG_INFO)<<"Warning: Group::removeChild(i,numChildrenToRemove) has been passed an excessive number"<<std::endl;
|
|
|
|
notify(DEBUG_INFO)<<" of chilren to remove, trimming just to end of child list."<<std::endl;
|
|
|
|
endOfRemoveRange=_children.size();
|
2001-09-22 10:42:08 +08:00
|
|
|
}
|
|
|
|
|
2002-12-08 05:18:12 +08:00
|
|
|
unsigned int appCallbackRemoved = 0;
|
|
|
|
unsigned int numChildrenWithCullingDisabledRemoved = 0;
|
|
|
|
unsigned int numChildrenWithOccludersRemoved = 0;
|
|
|
|
|
|
|
|
for(unsigned i=pos;i<endOfRemoveRange;++i)
|
2001-10-19 20:56:37 +08:00
|
|
|
{
|
2002-12-08 05:18:12 +08:00
|
|
|
osg::Node* child = _children[i].get();
|
|
|
|
// remove this Geode from the child parent list.
|
|
|
|
child->removeParent(this);
|
|
|
|
|
2002-12-19 23:55:40 +08:00
|
|
|
if (child->getNumChildrenRequiringUpdateTraversal()>0 || child->getUpdateCallback()) ++appCallbackRemoved;
|
2002-12-08 05:18:12 +08:00
|
|
|
|
|
|
|
if (child->getNumChildrenWithCullingDisabled()>0 || !child->getCullingActive()) ++numChildrenWithCullingDisabledRemoved;
|
|
|
|
|
|
|
|
if (child->getNumChildrenWithOccluderNodes()>0 || dynamic_cast<osg::OccluderNode*>(child)) ++numChildrenWithOccludersRemoved;
|
|
|
|
|
2001-10-19 20:56:37 +08:00
|
|
|
}
|
|
|
|
|
2002-12-08 05:18:12 +08:00
|
|
|
_children.erase(_children.begin()+pos,_children.begin()+endOfRemoveRange);
|
|
|
|
|
|
|
|
if (appCallbackRemoved)
|
2002-06-10 21:50:25 +08:00
|
|
|
{
|
2002-12-19 23:55:40 +08:00
|
|
|
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-appCallbackRemoved);
|
2002-06-10 21:50:25 +08:00
|
|
|
}
|
2002-12-08 05:18:12 +08:00
|
|
|
|
|
|
|
if (numChildrenWithCullingDisabledRemoved)
|
|
|
|
{
|
|
|
|
setNumChildrenWithCullingDisabled(getNumChildrenWithCullingDisabled()-numChildrenWithCullingDisabledRemoved);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (numChildrenWithOccludersRemoved)
|
|
|
|
{
|
|
|
|
setNumChildrenWithOccluderNodes(getNumChildrenWithOccluderNodes()-numChildrenWithOccludersRemoved);
|
|
|
|
}
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
dirtyBound();
|
2002-12-08 05:18:12 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
bool Group::replaceChild( Node *origNode, Node *newNode )
|
|
|
|
{
|
|
|
|
if (newNode==NULL || origNode==newNode) return false;
|
|
|
|
|
2002-11-21 17:07:11 +08:00
|
|
|
unsigned int pos = getChildIndex(origNode);
|
2002-11-19 18:56:59 +08:00
|
|
|
if (pos<_children.size())
|
|
|
|
{
|
|
|
|
return setChild(pos,newNode);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Group::setChild( unsigned int i, Node* newNode )
|
|
|
|
{
|
|
|
|
if (i<_children.size() && newNode)
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
2002-11-19 18:56:59 +08:00
|
|
|
|
2002-11-22 00:08:30 +08:00
|
|
|
ref_ptr<Node> origNode = _children[i];
|
2002-11-19 18:56:59 +08:00
|
|
|
|
2002-02-09 06:55:21 +08:00
|
|
|
// first remove for origNode's parent list.
|
|
|
|
origNode->removeParent(this);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
// note ref_ptr<> automatically handles decrementing origNode's reference count,
|
|
|
|
// and inccrementing newNode's reference count.
|
2002-11-19 18:56:59 +08:00
|
|
|
_children[i] = newNode;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
// register as parent of child.
|
2002-02-09 06:55:21 +08:00
|
|
|
newNode->addParent(this);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
dirtyBound();
|
2001-10-19 20:56:37 +08:00
|
|
|
|
|
|
|
|
|
|
|
// could now require app traversal thanks to the new subgraph,
|
|
|
|
// so need to check and update if required.
|
|
|
|
int delta_numChildrenRequiringAppTraversal = 0;
|
2002-12-19 23:55:40 +08:00
|
|
|
if (origNode->getNumChildrenRequiringUpdateTraversal()>0 ||
|
|
|
|
origNode->getUpdateCallback())
|
2001-10-19 20:56:37 +08:00
|
|
|
{
|
|
|
|
--delta_numChildrenRequiringAppTraversal;
|
|
|
|
}
|
2002-12-19 23:55:40 +08:00
|
|
|
if (newNode->getNumChildrenRequiringUpdateTraversal()>0 ||
|
|
|
|
newNode->getUpdateCallback())
|
2001-10-19 20:56:37 +08:00
|
|
|
{
|
|
|
|
++delta_numChildrenRequiringAppTraversal;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delta_numChildrenRequiringAppTraversal!=0)
|
|
|
|
{
|
2002-12-19 23:55:40 +08:00
|
|
|
setNumChildrenRequiringUpdateTraversal(
|
|
|
|
getNumChildrenRequiringUpdateTraversal()+delta_numChildrenRequiringAppTraversal
|
2001-10-19 20:56:37 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// could now require disabling of culling thanks to the new subgraph,
|
|
|
|
// so need to check and update if required.
|
|
|
|
int delta_numChildrenWithCullingDisabled = 0;
|
|
|
|
if (origNode->getNumChildrenWithCullingDisabled()>0 ||
|
|
|
|
!origNode->getCullingActive())
|
|
|
|
{
|
|
|
|
--delta_numChildrenWithCullingDisabled;
|
|
|
|
}
|
|
|
|
if (newNode->getNumChildrenWithCullingDisabled()>0 ||
|
|
|
|
!newNode->getCullingActive())
|
|
|
|
{
|
|
|
|
++delta_numChildrenWithCullingDisabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delta_numChildrenWithCullingDisabled!=0)
|
|
|
|
{
|
|
|
|
setNumChildrenWithCullingDisabled(
|
2002-11-22 00:08:30 +08:00
|
|
|
getNumChildrenWithCullingDisabled()+delta_numChildrenWithCullingDisabled
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// could now require disabling of culling thanks to the new subgraph,
|
|
|
|
// so need to check and update if required.
|
|
|
|
int delta_numChildrenWithOccluderNodes = 0;
|
|
|
|
if (origNode->getNumChildrenWithOccluderNodes()>0 ||
|
|
|
|
!origNode->getCullingActive())
|
|
|
|
{
|
|
|
|
--delta_numChildrenWithOccluderNodes;
|
|
|
|
}
|
|
|
|
if (newNode->getNumChildrenWithOccluderNodes()>0 ||
|
|
|
|
!newNode->getCullingActive())
|
|
|
|
{
|
|
|
|
++delta_numChildrenWithOccluderNodes;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (delta_numChildrenWithOccluderNodes!=0)
|
|
|
|
{
|
|
|
|
setNumChildrenWithOccluderNodes(
|
|
|
|
getNumChildrenWithOccluderNodes()+delta_numChildrenWithOccluderNodes
|
2001-10-19 20:56:37 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2002-09-02 20:31:35 +08:00
|
|
|
bool Group::computeBound() const
|
2001-01-11 00:32:10 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
_bsphere.init();
|
2002-12-17 23:41:05 +08:00
|
|
|
if (_children.empty())
|
|
|
|
{
|
|
|
|
_bsphere_computed = true;
|
|
|
|
return false;
|
|
|
|
}
|
2001-09-20 05:08:56 +08:00
|
|
|
|
Added DataVariance enum and set/get fields to osg::Object to help identify
which objects have values that vary over the lifetime of the object (DYNAMIC)
and ones that do not vary (STATIC). Removed the equivalent code in
osg::Transform, StateSet and StateAttribute, as these are now encompassed
by the new DataVariance field.
Removed MatrixMode enum from Matrix, and associated fields/parameters from
osg::Transfrom and osg::NodeVisitor, since MatrixMode was not providing
any useful functionality, but made the interface more complex (MatrixMode
was an experimental API)
Added ReferenceFrame field to osg::Transform which allows users to specify
transforms that are relative to their parents (the default, and previous behavior)
or absolute reference frame, which can be used for HUD's, camera relative
light sources etc etc. Note, the view frustum culling for absolute Transform
are disabled, and all their parents up to the root are also automatically
have view frustum culling disabled. However, once passed an absolute Transform
node culling will return to its default state of on, so you can still cull
underneath an absolute transform, its only the culling above which is disabled.
2002-04-12 07:20:23 +08:00
|
|
|
// note, special handling of the case when a child is an Transform,
|
|
|
|
// such that only Transforms which are relative to their parents coordinates frame (i.e this group)
|
|
|
|
// are handled, Transform relative to and absolute reference frame are ignored.
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
BoundingBox bb;
|
|
|
|
bb.init();
|
2001-09-20 05:08:56 +08:00
|
|
|
ChildList::const_iterator itr;
|
2001-01-11 00:32:10 +08:00
|
|
|
for(itr=_children.begin();
|
|
|
|
itr!=_children.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2002-09-12 23:34:31 +08:00
|
|
|
const osg::Transform* transform = (*itr)->asTransform();
|
Added DataVariance enum and set/get fields to osg::Object to help identify
which objects have values that vary over the lifetime of the object (DYNAMIC)
and ones that do not vary (STATIC). Removed the equivalent code in
osg::Transform, StateSet and StateAttribute, as these are now encompassed
by the new DataVariance field.
Removed MatrixMode enum from Matrix, and associated fields/parameters from
osg::Transfrom and osg::NodeVisitor, since MatrixMode was not providing
any useful functionality, but made the interface more complex (MatrixMode
was an experimental API)
Added ReferenceFrame field to osg::Transform which allows users to specify
transforms that are relative to their parents (the default, and previous behavior)
or absolute reference frame, which can be used for HUD's, camera relative
light sources etc etc. Note, the view frustum culling for absolute Transform
are disabled, and all their parents up to the root are also automatically
have view frustum culling disabled. However, once passed an absolute Transform
node culling will return to its default state of on, so you can still cull
underneath an absolute transform, its only the culling above which is disabled.
2002-04-12 07:20:23 +08:00
|
|
|
if (!transform || transform->getReferenceFrame()==osg::Transform::RELATIVE_TO_PARENTS)
|
|
|
|
{
|
|
|
|
bb.expandBy((*itr)->getBound());
|
|
|
|
}
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-12-17 23:41:05 +08:00
|
|
|
if (!bb.valid())
|
|
|
|
{
|
|
|
|
_bsphere_computed = true;
|
|
|
|
return false;
|
|
|
|
}
|
2001-09-20 05:08:56 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
_bsphere._center = bb.center();
|
|
|
|
_bsphere._radius = 0.0f;
|
|
|
|
for(itr=_children.begin();
|
|
|
|
itr!=_children.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2002-09-12 23:34:31 +08:00
|
|
|
const osg::Transform* transform = (*itr)->asTransform();
|
Added DataVariance enum and set/get fields to osg::Object to help identify
which objects have values that vary over the lifetime of the object (DYNAMIC)
and ones that do not vary (STATIC). Removed the equivalent code in
osg::Transform, StateSet and StateAttribute, as these are now encompassed
by the new DataVariance field.
Removed MatrixMode enum from Matrix, and associated fields/parameters from
osg::Transfrom and osg::NodeVisitor, since MatrixMode was not providing
any useful functionality, but made the interface more complex (MatrixMode
was an experimental API)
Added ReferenceFrame field to osg::Transform which allows users to specify
transforms that are relative to their parents (the default, and previous behavior)
or absolute reference frame, which can be used for HUD's, camera relative
light sources etc etc. Note, the view frustum culling for absolute Transform
are disabled, and all their parents up to the root are also automatically
have view frustum culling disabled. However, once passed an absolute Transform
node culling will return to its default state of on, so you can still cull
underneath an absolute transform, its only the culling above which is disabled.
2002-04-12 07:20:23 +08:00
|
|
|
if (!transform || transform->getReferenceFrame()==osg::Transform::RELATIVE_TO_PARENTS)
|
|
|
|
{
|
|
|
|
_bsphere.expandRadiusBy((*itr)->getBound());
|
|
|
|
}
|
2001-09-20 05:08:56 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-12-17 23:41:05 +08:00
|
|
|
_bsphere_computed = true;
|
2001-01-11 00:32:10 +08:00
|
|
|
return true;
|
|
|
|
}
|