Updated the Switch, Sequence and Group classes so that they all used a
similar style removeChild() mechansim. Made the old style osg::Switch::setValue() method deprecated.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include <osg/Geode>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <osg/Geode>
|
||||
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
@@ -58,19 +60,36 @@ bool Geode::addDrawable( Drawable *drawable )
|
||||
|
||||
bool Geode::removeDrawable( Drawable *drawable )
|
||||
{
|
||||
DrawableList::iterator itr = findDrawable(drawable);
|
||||
if (itr!=_drawables.end())
|
||||
{
|
||||
// remove this Geode from the child parent list.
|
||||
drawable->removeParent(this);
|
||||
return removeDrawable(getDrawableIndex(drawable));
|
||||
}
|
||||
|
||||
if (drawable->getAppCallback())
|
||||
bool Geode::removeDrawable(unsigned int pos,unsigned int numDrawablesToRemove)
|
||||
{
|
||||
if (pos<_drawables.size() && numDrawablesToRemove>0)
|
||||
{
|
||||
unsigned int endOfRemoveRange = pos+numDrawablesToRemove;
|
||||
if (endOfRemoveRange>_drawables.size())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()-1);
|
||||
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();
|
||||
}
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing drawable's reference count.
|
||||
_drawables.erase(itr);
|
||||
unsigned int appCallbackRemoved = 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]->getAppCallback()) ++appCallbackRemoved;
|
||||
}
|
||||
|
||||
_drawables.erase(_drawables.begin()+pos,_drawables.begin()+endOfRemoveRange);
|
||||
|
||||
if (appCallbackRemoved)
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()-appCallbackRemoved);
|
||||
}
|
||||
|
||||
dirtyBound();
|
||||
|
||||
@@ -79,7 +98,6 @@ bool Geode::removeDrawable( Drawable *drawable )
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Geode::replaceDrawable( Drawable *origDrawable, Drawable *newDrawable )
|
||||
{
|
||||
if (newDrawable==NULL || origDrawable==newDrawable) return false;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <osg/Group>
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/Transform>
|
||||
#include <osg/OccluderNode>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -94,48 +96,60 @@ bool Group::addChild( Node *child )
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
bool Group::removeChild( Node *child )
|
||||
{
|
||||
ChildList::iterator itr = findNode(child);
|
||||
if (itr!=_children.end())
|
||||
return removeChild(getChildIndex(child));
|
||||
}
|
||||
|
||||
bool Group::removeChild(unsigned int pos,unsigned int numChildrenToRemove)
|
||||
{
|
||||
if (pos<_children.size() && numChildrenToRemove>0)
|
||||
{
|
||||
// remove this group from the child parent list.
|
||||
child->removeParent(this);
|
||||
|
||||
// could now require app traversal thanks to the new subgraph,
|
||||
// so need to check and update if required.
|
||||
// note, need to do this checking before the erase of the child
|
||||
// otherwise child will be invalid.
|
||||
if (child->getNumChildrenRequiringAppTraversal()>0 ||
|
||||
child->getAppCallback())
|
||||
unsigned int endOfRemoveRange = pos+numChildrenToRemove;
|
||||
if (endOfRemoveRange>_children.size())
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(
|
||||
getNumChildrenRequiringAppTraversal()-1
|
||||
);
|
||||
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();
|
||||
}
|
||||
|
||||
if (child->getNumChildrenWithCullingDisabled()>0 ||
|
||||
!child->getCullingActive())
|
||||
unsigned int appCallbackRemoved = 0;
|
||||
unsigned int numChildrenWithCullingDisabledRemoved = 0;
|
||||
unsigned int numChildrenWithOccludersRemoved = 0;
|
||||
|
||||
for(unsigned i=pos;i<endOfRemoveRange;++i)
|
||||
{
|
||||
setNumChildrenWithCullingDisabled(
|
||||
getNumChildrenWithCullingDisabled()-1
|
||||
);
|
||||
osg::Node* child = _children[i].get();
|
||||
// remove this Geode from the child parent list.
|
||||
child->removeParent(this);
|
||||
|
||||
if (child->getNumChildrenRequiringAppTraversal()>0 || child->getAppCallback()) ++appCallbackRemoved;
|
||||
|
||||
if (child->getNumChildrenWithCullingDisabled()>0 || !child->getCullingActive()) ++numChildrenWithCullingDisabledRemoved;
|
||||
|
||||
if (child->getNumChildrenWithOccluderNodes()>0 || dynamic_cast<osg::OccluderNode*>(child)) ++numChildrenWithOccludersRemoved;
|
||||
|
||||
}
|
||||
|
||||
if (child->getNumChildrenWithOccluderNodes()>0 ||
|
||||
dynamic_cast<osg::OccluderNode*>(child))
|
||||
{
|
||||
setNumChildrenWithOccluderNodes(
|
||||
getNumChildrenWithOccluderNodes()-1
|
||||
);
|
||||
}
|
||||
_children.erase(_children.begin()+pos,_children.begin()+endOfRemoveRange);
|
||||
|
||||
// note ref_ptr<> automatically handles decrementing child's reference count.
|
||||
_children.erase(itr);
|
||||
if (appCallbackRemoved)
|
||||
{
|
||||
setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()-appCallbackRemoved);
|
||||
}
|
||||
|
||||
if (numChildrenWithCullingDisabledRemoved)
|
||||
{
|
||||
setNumChildrenWithCullingDisabled(getNumChildrenWithCullingDisabled()-numChildrenWithCullingDisabledRemoved);
|
||||
}
|
||||
|
||||
if (numChildrenWithOccludersRemoved)
|
||||
{
|
||||
setNumChildrenWithOccluderNodes(getNumChildrenWithOccluderNodes()-numChildrenWithOccludersRemoved);
|
||||
}
|
||||
|
||||
dirtyBound();
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
|
||||
@@ -6,7 +6,8 @@ using namespace osg;
|
||||
* Sequence constructor.
|
||||
*/
|
||||
Sequence::Sequence() :
|
||||
Switch(),
|
||||
Group(),
|
||||
_value(-1),
|
||||
_last(-1.0f),
|
||||
_step(1),
|
||||
_loopMode(LOOP),
|
||||
@@ -21,7 +22,8 @@ Sequence::Sequence() :
|
||||
}
|
||||
|
||||
Sequence::Sequence(const Sequence& seq, const CopyOp& copyop) :
|
||||
Switch(seq, copyop),
|
||||
Group(seq, copyop),
|
||||
_value(seq._value),
|
||||
_last(seq._last),
|
||||
_step(seq._step),
|
||||
_loopMode(seq._loopMode),
|
||||
@@ -82,7 +84,7 @@ void Sequence::setMode(SequenceMode mode)
|
||||
switch (mode) {
|
||||
case START:
|
||||
// restarts sequence in 'traverse'
|
||||
setValue(ALL_CHILDREN_OFF);
|
||||
setValue(-1);
|
||||
_mode = mode;
|
||||
break;
|
||||
case STOP:
|
||||
@@ -101,75 +103,89 @@ void Sequence::setMode(SequenceMode mode)
|
||||
|
||||
void Sequence::traverse(NodeVisitor& nv)
|
||||
{
|
||||
// if app traversal update the frame count.
|
||||
if (nv.getVisitorType()==NodeVisitor::APP_VISITOR && _mode == START && _nrepsremain)
|
||||
{
|
||||
double t = nv.getFrameStamp()->getReferenceTime();
|
||||
if (_last == -1.0)
|
||||
_last = t;
|
||||
const FrameStamp* framestamp = nv.getFrameStamp();
|
||||
if (framestamp)
|
||||
{
|
||||
|
||||
double t = framestamp->getReferenceTime();
|
||||
if (_last == -1.0)
|
||||
_last = t;
|
||||
|
||||
// first and last frame of interval
|
||||
unsigned int nch = getNumChildren();
|
||||
int begin = (_begin < 0 ? nch + _begin : _begin);
|
||||
int end = (_end < 0 ? nch + _end : _end);
|
||||
// first and last frame of interval
|
||||
unsigned int nch = getNumChildren();
|
||||
int begin = (_begin < 0 ? nch + _begin : _begin);
|
||||
int end = (_end < 0 ? nch + _end : _end);
|
||||
|
||||
int sw = getValue();
|
||||
if (sw == ALL_CHILDREN_OFF ||
|
||||
sw == ALL_CHILDREN_ON ||
|
||||
sw == MULTIPLE_CHILDREN_ON ) {
|
||||
sw = begin;
|
||||
_step = (begin < end ? 1 : -1);
|
||||
}
|
||||
|
||||
// default timeout for unset values
|
||||
if (sw >= (int) _frameTime.size()) {
|
||||
setTime(sw, 1.0f);
|
||||
}
|
||||
|
||||
// frame time-out?
|
||||
float dur = _frameTime[sw] * _speed;
|
||||
if ((t - _last) > dur) {
|
||||
|
||||
sw += _step;
|
||||
|
||||
// check interval
|
||||
int ibegin = (begin < end ? begin : end);
|
||||
int iend = (end > begin ? end : begin);
|
||||
//cerr << this << " interval " << ibegin << "," << iend << endl;
|
||||
|
||||
if (sw < ibegin || sw > iend) {
|
||||
// stop at last frame
|
||||
if (sw < ibegin)
|
||||
sw = ibegin;
|
||||
else
|
||||
sw = iend;
|
||||
|
||||
// repeat counter
|
||||
if (_nrepsremain > 0)
|
||||
_nrepsremain--;
|
||||
|
||||
if (_nrepsremain == 0) {
|
||||
// stop
|
||||
setMode(STOP);
|
||||
}
|
||||
else {
|
||||
// wrap around
|
||||
switch (_loopMode) {
|
||||
case LOOP:
|
||||
//cerr << this << " loop" << endl;
|
||||
sw = begin;
|
||||
break;
|
||||
case SWING:
|
||||
//cerr << this << " swing" << endl;
|
||||
_step = -_step;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int sw = getValue();
|
||||
if (sw<0)
|
||||
{
|
||||
sw = begin;
|
||||
_step = (begin < end ? 1 : -1);
|
||||
}
|
||||
|
||||
_last = t;
|
||||
// default timeout for unset values
|
||||
if (sw >= (int) _frameTime.size())
|
||||
{
|
||||
setTime(sw, 1.0f);
|
||||
}
|
||||
|
||||
// frame time-out?
|
||||
float dur = _frameTime[sw] * _speed;
|
||||
if ((t - _last) > dur) {
|
||||
|
||||
sw += _step;
|
||||
|
||||
// check interval
|
||||
int ibegin = (begin < end ? begin : end);
|
||||
int iend = (end > begin ? end : begin);
|
||||
//cerr << this << " interval " << ibegin << "," << iend << endl;
|
||||
|
||||
if (sw < ibegin || sw > iend) {
|
||||
// stop at last frame
|
||||
if (sw < ibegin)
|
||||
sw = ibegin;
|
||||
else
|
||||
sw = iend;
|
||||
|
||||
// repeat counter
|
||||
if (_nrepsremain > 0)
|
||||
_nrepsremain--;
|
||||
|
||||
if (_nrepsremain == 0) {
|
||||
// stop
|
||||
setMode(STOP);
|
||||
}
|
||||
else {
|
||||
// wrap around
|
||||
switch (_loopMode) {
|
||||
case LOOP:
|
||||
//cerr << this << " loop" << endl;
|
||||
sw = begin;
|
||||
break;
|
||||
case SWING:
|
||||
//cerr << this << " swing" << endl;
|
||||
_step = -_step;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_last = t;
|
||||
}
|
||||
setValue(sw);
|
||||
}
|
||||
//cerr << this << " child=" << sw << endl;
|
||||
setValue(sw);
|
||||
}
|
||||
Switch::traverse(nv);
|
||||
|
||||
// now do the traversal
|
||||
if (nv.getTraversalMode()==NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
|
||||
{
|
||||
if (getValue()>=0) _children[getValue()]->accept(nv);
|
||||
}
|
||||
else
|
||||
{
|
||||
Group::traverse(nv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,23 +18,16 @@ Switch::Switch(const Switch& sw,const CopyOp& copyop):
|
||||
|
||||
void Switch::traverse(NodeVisitor& nv)
|
||||
{
|
||||
switch(nv.getTraversalMode())
|
||||
if (nv.getTraversalMode()==NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
|
||||
{
|
||||
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
for(unsigned int pos=0;pos<_children.size();++pos)
|
||||
{
|
||||
std::for_each(_children.begin(),_children.end(),NodeAcceptOp(nv));
|
||||
break;
|
||||
if (_values[pos]) _children[pos]->accept(nv);
|
||||
}
|
||||
case(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
{
|
||||
for(unsigned int pos=0;pos<_children.size();++pos)
|
||||
{
|
||||
if (_values[pos]) _children[pos]->accept(nv);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Group::traverse(nv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +68,7 @@ void Switch::setValue(unsigned int pos,bool value)
|
||||
_values[pos]=value;
|
||||
}
|
||||
|
||||
void Switch::setValue(const Node* child,bool value)
|
||||
void Switch::setChildValue(const Node* child,bool value)
|
||||
{
|
||||
// find the child's position.
|
||||
unsigned int pos=getChildIndex(child);
|
||||
@@ -90,7 +83,7 @@ bool Switch::getValue(unsigned int pos) const
|
||||
return _values[pos];
|
||||
}
|
||||
|
||||
bool Switch::getValue(const Node* child) const
|
||||
bool Switch::getChildValue(const Node* child) const
|
||||
{
|
||||
// find the child's position.
|
||||
unsigned int pos=getChildIndex(child);
|
||||
@@ -99,6 +92,43 @@ bool Switch::getValue(const Node* child) const
|
||||
return _values[pos];
|
||||
}
|
||||
|
||||
bool Switch::setAllChildrenOff()
|
||||
{
|
||||
_newChildDefaultValue = false;
|
||||
for(ValueList::iterator itr=_values.begin();
|
||||
itr!=_values.end();
|
||||
++itr)
|
||||
{
|
||||
*itr = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Switch::setAllChildrenOn()
|
||||
{
|
||||
_newChildDefaultValue = true;
|
||||
for(ValueList::iterator itr=_values.begin();
|
||||
itr!=_values.end();
|
||||
++itr)
|
||||
{
|
||||
*itr = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Switch::setSingleChildOn(unsigned int pos)
|
||||
{
|
||||
for(ValueList::iterator itr=_values.begin();
|
||||
itr!=_values.end();
|
||||
++itr)
|
||||
{
|
||||
*itr = false;
|
||||
}
|
||||
setValue(pos,true);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef USE_DEPRECTATED_API
|
||||
void Switch::setValue(int value)
|
||||
{
|
||||
switch(value)
|
||||
@@ -165,3 +195,4 @@ int Switch::getValue() const
|
||||
return firstChildSelected;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1172,14 +1172,22 @@ class ReaderWriterGEO : public ReaderWriter
|
||||
osg::Group *makeSwitch(const georecord *gr) {
|
||||
osg::Switch *sw=new Switch;
|
||||
const geoField *gfd=gr->getField(GEO_DB_SWITCH_CURRENT_MASK);
|
||||
sw->setValue(osg::Switch::ALL_CHILDREN_OFF);
|
||||
sw->setAllChildrenOff();
|
||||
if (gfd) {
|
||||
int imask;
|
||||
int imask; // bit surprised this isn't a uint.. Robert Dec 2002.
|
||||
imask=gfd->getInt();
|
||||
sw->setValue(imask);
|
||||
|
||||
// will set all 32 bits of the mask into the switch right now,
|
||||
// should cap to only set the number of children in the switch.
|
||||
int selector_mask = 0x1;
|
||||
for(unsigned int i=0;i<32;++i)
|
||||
{
|
||||
sw->setValue(i,(imask&selector_mask));
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
osg::notify(osg::WARN) << gr << " imask " << imask << std::endl;
|
||||
} else {
|
||||
sw->setValue(0);
|
||||
sw->setSingleChildOn(0);
|
||||
osg::notify(osg::WARN) << gr << " No mask " << std::endl;
|
||||
}
|
||||
gfd=gr->getField(GEO_DB_SWITCH_NAME);
|
||||
|
||||
@@ -31,26 +31,50 @@ bool Switch_readLocalData(Object& obj, Input& fr)
|
||||
{
|
||||
if (fr[1].matchWord("ALL_CHILDREN_ON"))
|
||||
{
|
||||
sw.setValue(Switch::ALL_CHILDREN_ON);
|
||||
sw.setAllChildrenOn();
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
else if (fr[1].matchWord("ALL_CHILDREN_OFF"))
|
||||
{
|
||||
sw.setValue(Switch::ALL_CHILDREN_OFF);
|
||||
sw.setAllChildrenOff();
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
else if (fr[1].isInt())
|
||||
{
|
||||
int value;
|
||||
fr[1].getInt(value);
|
||||
sw.setValue(value);
|
||||
unsigned int value;
|
||||
fr[1].getUInt(value);
|
||||
sw.setSingleChildOn(value);
|
||||
iteratorAdvanced = true;
|
||||
fr+=2;
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("NewChildDefaultValue"))
|
||||
{
|
||||
if (fr[1].matchWord("TRUE"))
|
||||
{
|
||||
sw.setNewChildDefaultValue(true);
|
||||
iteratorAdvanced = true;
|
||||
fr += 2;
|
||||
}
|
||||
else if (fr[1].matchWord("FALSE"))
|
||||
{
|
||||
sw.setNewChildDefaultValue(false);
|
||||
iteratorAdvanced = true;
|
||||
fr += 2;
|
||||
}
|
||||
else if (fr[1].isInt())
|
||||
{
|
||||
int value;
|
||||
fr[1].getInt(value);
|
||||
sw.setNewChildDefaultValue(value);
|
||||
iteratorAdvanced = true;
|
||||
fr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (fr.matchSequence("ValueList {"))
|
||||
{
|
||||
int entry = fr[0].getNoNestedBrackets();
|
||||
@@ -64,7 +88,7 @@ bool Switch_readLocalData(Object& obj, Input& fr)
|
||||
int value;
|
||||
if (fr[0].getInt(value))
|
||||
{
|
||||
sw.setValue(value);
|
||||
sw.setValue(pos,value);
|
||||
++pos;
|
||||
}
|
||||
++fr;
|
||||
@@ -84,28 +108,20 @@ bool Switch_writeLocalData(const Object& obj, Output& fw)
|
||||
{
|
||||
const Switch& sw = static_cast<const Switch&>(obj);
|
||||
|
||||
int value=sw.getValue();
|
||||
switch(value)
|
||||
|
||||
fw.indent()<<"NewChildDefaultValue "<<sw.getNewChildDefaultValue()<<std::endl;
|
||||
|
||||
fw.indent()<<"ValueList {"<< std::endl;
|
||||
fw.moveIn();
|
||||
const Switch::ValueList& values = sw.getValueList();
|
||||
for(Switch::ValueList::const_iterator itr=values.begin();
|
||||
itr!=values.end();
|
||||
++itr)
|
||||
{
|
||||
case(Switch::MULTIPLE_CHILDREN_ON):
|
||||
{
|
||||
fw.indent()<<"ValueList {"<< std::endl;
|
||||
fw.moveIn();
|
||||
const Switch::ValueList& values = sw.getValueList();
|
||||
for(Switch::ValueList::const_iterator itr=values.begin();
|
||||
itr!=values.end();
|
||||
++itr)
|
||||
{
|
||||
fw.indent()<<*itr<<std::endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent()<<"}"<< std::endl;
|
||||
break;
|
||||
}
|
||||
case(Switch::ALL_CHILDREN_ON): fw.indent()<<"value ALL_CHILDREN_ON"<< std::endl;break;
|
||||
case(Switch::ALL_CHILDREN_OFF): fw.indent()<<"value ALL_CHILDREN_OFF"<< std::endl;break;
|
||||
default: fw.indent()<<"value "<<value<< std::endl;break;
|
||||
fw.indent()<<*itr<<std::endl;
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent()<<"}"<< std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user