OpenSceneGraph/src/osg/Geode.cpp

247 lines
6.6 KiB
C++
Raw Normal View History

2006-07-18 23:21:48 +08:00
/* -*-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.
*/
#include <osg/Geode>
#include <osg/Notify>
2001-01-11 00:32:10 +08:00
#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);
}
}
2001-01-11 00:32:10 +08:00
Geode::~Geode()
{
// remove reference to this from children's parent lists.
for(DrawableList::iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
(*itr)->removeParent(this);
}
2001-01-11 00:32:10 +08:00
}
bool Geode::addDrawable( Drawable *drawable )
2001-01-11 00:32:10 +08:00
{
if (drawable /* && !containsDrawable(drawable)*/)
2001-01-11 00:32:10 +08:00
{
// 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())
2002-07-10 23:35:47 +08:00
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
2002-07-10 23:35:47 +08:00
}
if (drawable->requiresEventTraversal())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+1);
}
dirtyBound();
2001-01-11 00:32:10 +08:00
return true;
}
else return false;
}
bool Geode::removeDrawable( Drawable *drawable )
2001-01-11 00:32:10 +08:00
{
return removeDrawables(getDrawableIndex(drawable),1);
}
bool Geode::removeDrawables(unsigned int pos,unsigned int numDrawablesToRemove)
{
if (pos<_drawables.size() && numDrawablesToRemove>0)
2001-01-11 00:32:10 +08:00
{
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)
2002-07-10 23:35:47 +08:00
{
// remove this Geode from the child parent list.
_drawables[i]->removeParent(this);
// update the number of app callbacks removed
if (_drawables[i]->requiresUpdateTraversal()) ++updateCallbackRemoved;
if (_drawables[i]->requiresEventTraversal()) ++eventCallbackRemoved;
2002-07-10 23:35:47 +08:00
}
_drawables.erase(_drawables.begin()+pos,_drawables.begin()+endOfRemoveRange);
if (updateCallbackRemoved)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved);
}
if (eventCallbackRemoved)
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved);
}
2001-01-11 00:32:10 +08:00
dirtyBound();
2001-01-11 00:32:10 +08:00
return true;
}
else return false;
}
bool Geode::replaceDrawable( Drawable *origDrawable, Drawable *newDrawable )
2001-01-11 00:32:10 +08:00
{
if (newDrawable==NULL || origDrawable==newDrawable) return false;
2001-01-11 00:32:10 +08:00
unsigned int pos = getDrawableIndex(origDrawable);
if (pos<_drawables.size())
2001-01-11 00:32:10 +08:00
{
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)
2002-07-10 23:35:47 +08:00
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+deltaUpdate);
2002-07-10 23:35:47 +08:00
}
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);
2001-01-11 00:32:10 +08:00
// note ref_ptr<> automatically handles decrementing origGset's reference count,
// and incrementing newGset's reference count.
_drawables[i] = newDrawable;
// register as parent of child.
newDrawable->addParent(this);
2002-07-10 23:35:47 +08:00
2001-01-11 00:32:10 +08:00
dirtyBound();
2001-01-11 00:32:10 +08:00
return true;
}
else return false;
2001-01-11 00:32:10 +08:00
}
BoundingSphere Geode::computeBound() const
{
BoundingSphere bsphere;
_bbox.init();
DrawableList::const_iterator itr;
for(itr=_drawables.begin();
itr!=_drawables.end();
2001-01-11 00:32:10 +08:00
++itr)
{
_bbox.expandBy((*itr)->getBound());
2001-01-11 00:32:10 +08:00
}
if (_bbox.valid())
2001-01-11 00:32:10 +08:00
{
bsphere.expandBy(_bbox);
}
return bsphere;
2001-01-11 00:32:10 +08:00
}
2006-11-14 20:51:31 +08:00
void Geode::compileDrawables(RenderInfo& renderInfo)
2001-01-11 00:32:10 +08:00
{
for(DrawableList::iterator itr = _drawables.begin();
itr!=_drawables.end();
2001-01-11 00:32:10 +08:00
++itr)
{
2006-11-14 20:51:31 +08:00
(*itr)->compileGLObjects(renderInfo);
2001-01-11 00:32:10 +08:00
}
}
void Geode::setThreadSafeRefUnref(bool threadSafe)
{
Node::setThreadSafeRefUnref(threadSafe);
for(DrawableList::const_iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
(*itr)->setThreadSafeRefUnref(threadSafe);
}
}
void Geode::resizeGLObjectBuffers(unsigned int maxSize)
{
Node::resizeGLObjectBuffers(maxSize);
for(DrawableList::const_iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
(*itr)->resizeGLObjectBuffers(maxSize);
}
}
void Geode::releaseGLObjects(osg::State* state) const
{
Node::releaseGLObjects(state);
for(DrawableList::const_iterator itr=_drawables.begin();
itr!=_drawables.end();
++itr)
{
(*itr)->releaseGLObjects(state);
}
}