that removeChild(Node*), removeChild(uint) and equivilant Geode methods are now inline methods, not designed to be overriden, and seperated out the multiple remove method to be called removeChildren(uint, uint) which is now the only virtual method. There removeChildren is now the method to override in subclasses. This reorganisation requires some call code to be rename removeChild usage to removeChildren.
223 lines
6.0 KiB
C++
223 lines
6.0 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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.
|
|
*/
|
|
#include <osg/Geode>
|
|
#include <osg/Notify>
|
|
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#define square(x) ((x)*(x))
|
|
|
|
using namespace osg;
|
|
|
|
Geode::Geode()
|
|
{
|
|
}
|
|
|
|
Geode::Geode(const Geode& geode,const CopyOp& copyop):
|
|
Node(geode,copyop)
|
|
{
|
|
for(DrawableList::const_iterator itr=geode._drawables.begin();
|
|
itr!=geode._drawables.end();
|
|
++itr)
|
|
{
|
|
Drawable* drawable = copyop(itr->get());
|
|
if (drawable) addDrawable(drawable);
|
|
}
|
|
}
|
|
|
|
Geode::~Geode()
|
|
{
|
|
// remove reference to this from children's parent lists.
|
|
for(DrawableList::iterator itr=_drawables.begin();
|
|
itr!=_drawables.end();
|
|
++itr)
|
|
{
|
|
(*itr)->removeParent(this);
|
|
}
|
|
}
|
|
|
|
bool Geode::addDrawable( Drawable *drawable )
|
|
{
|
|
if (drawable && !containsDrawable(drawable))
|
|
{
|
|
// note ref_ptr<> automatically handles incrementing drawable's reference count.
|
|
_drawables.push_back(drawable);
|
|
|
|
// register as parent of drawable.
|
|
drawable->addParent(this);
|
|
|
|
if (drawable->requiresUpdateTraversal())
|
|
{
|
|
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
|
|
}
|
|
|
|
if (drawable->requiresEventTraversal())
|
|
{
|
|
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+1);
|
|
}
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
|
|
bool Geode::removeDrawable( Drawable *drawable )
|
|
{
|
|
return removeDrawables(getDrawableIndex(drawable),1);
|
|
}
|
|
|
|
bool Geode::removeDrawables(unsigned int pos,unsigned int numDrawablesToRemove)
|
|
{
|
|
if (pos<_drawables.size() && numDrawablesToRemove>0)
|
|
{
|
|
unsigned int endOfRemoveRange = pos+numDrawablesToRemove;
|
|
if (endOfRemoveRange>_drawables.size())
|
|
{
|
|
notify(DEBUG_INFO)<<"Warning: Geode::removeDrawable(i,numDrawablesToRemove) has been passed an excessive number"<<std::endl;
|
|
notify(DEBUG_INFO)<<" of drawables to remove, trimming just to end of drawable list."<<std::endl;
|
|
endOfRemoveRange=_drawables.size();
|
|
}
|
|
|
|
unsigned int updateCallbackRemoved = 0;
|
|
unsigned int eventCallbackRemoved = 0;
|
|
for(unsigned i=pos;i<endOfRemoveRange;++i)
|
|
{
|
|
// remove this Geode from the child parent list.
|
|
_drawables[i]->removeParent(this);
|
|
// update the number of app calbacks removed
|
|
if (_drawables[i]->requiresUpdateTraversal()) ++updateCallbackRemoved;
|
|
if (_drawables[i]->requiresEventTraversal()) ++eventCallbackRemoved;
|
|
}
|
|
|
|
_drawables.erase(_drawables.begin()+pos,_drawables.begin()+endOfRemoveRange);
|
|
|
|
if (updateCallbackRemoved)
|
|
{
|
|
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved);
|
|
}
|
|
|
|
if (eventCallbackRemoved)
|
|
{
|
|
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved);
|
|
}
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
}
|
|
else return false;
|
|
}
|
|
|
|
bool Geode::replaceDrawable( Drawable *origDrawable, Drawable *newDrawable )
|
|
{
|
|
if (newDrawable==NULL || origDrawable==newDrawable) return false;
|
|
|
|
unsigned int pos = getDrawableIndex(origDrawable);
|
|
if (pos<_drawables.size())
|
|
{
|
|
return setDrawable(pos,newDrawable);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Geode::setDrawable( unsigned int i, Drawable* newDrawable )
|
|
{
|
|
if (i<_drawables.size() && newDrawable)
|
|
{
|
|
|
|
Drawable* origDrawable = _drawables[i].get();
|
|
|
|
int deltaUpdate = 0;
|
|
if (origDrawable->requiresUpdateTraversal()) --deltaUpdate;
|
|
if (newDrawable->requiresUpdateTraversal()) ++deltaUpdate;
|
|
if (deltaUpdate!=0)
|
|
{
|
|
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+deltaUpdate);
|
|
}
|
|
|
|
int deltaEvent = 0;
|
|
if (origDrawable->requiresEventTraversal()) --deltaEvent;
|
|
if (newDrawable->requiresEventTraversal()) ++deltaEvent;
|
|
if (deltaEvent!=0)
|
|
{
|
|
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+deltaEvent);
|
|
}
|
|
|
|
|
|
// remove from origDrawable's parent list.
|
|
origDrawable->removeParent(this);
|
|
|
|
// note ref_ptr<> automatically handles decrementing origGset's reference count,
|
|
// and inccrementing newGset's reference count.
|
|
_drawables[i] = newDrawable;
|
|
|
|
// register as parent of child.
|
|
newDrawable->addParent(this);
|
|
|
|
|
|
dirtyBound();
|
|
|
|
return true;
|
|
}
|
|
else return false;
|
|
|
|
}
|
|
|
|
|
|
BoundingSphere Geode::computeBound() const
|
|
{
|
|
BoundingSphere bsphere;
|
|
|
|
_bbox.init();
|
|
|
|
DrawableList::const_iterator itr;
|
|
for(itr=_drawables.begin();
|
|
itr!=_drawables.end();
|
|
++itr)
|
|
{
|
|
_bbox.expandBy((*itr)->getBound());
|
|
}
|
|
|
|
if (_bbox.valid())
|
|
{
|
|
bsphere.expandBy(_bbox);
|
|
}
|
|
return bsphere;
|
|
}
|
|
|
|
void Geode::compileDrawables(State& state)
|
|
{
|
|
for(DrawableList::iterator itr = _drawables.begin();
|
|
itr!=_drawables.end();
|
|
++itr)
|
|
{
|
|
(*itr)->compileGLObjects(state);
|
|
}
|
|
}
|
|
|
|
void Geode::releaseGLObjects(osg::State* state) const
|
|
{
|
|
Node::releaseGLObjects(state);
|
|
|
|
for(DrawableList::const_iterator itr=_drawables.begin();
|
|
itr!=_drawables.end();
|
|
++itr)
|
|
{
|
|
(*itr)->releaseGLObjects(state);
|
|
}
|
|
}
|