Added osgSim::MultiSwitch and support for it in the OpenFlight and

.osg plugins
This commit is contained in:
Robert Osfield
2003-11-25 15:58:57 +00:00
parent 280eaf56fd
commit 72ba462251
8 changed files with 453 additions and 19 deletions

View File

@@ -224,6 +224,14 @@ SOURCE=..\..\..\src\osgPlugins\osgSim\IO_BlinkSequence.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\osgPlugins\osgSim\IO_MultiSwitch.cpp
# End Source File
# End Group
# Begin Group "Header Files"

View File

@@ -133,6 +133,10 @@ SOURCE=..\..\src\osgSim\SphereSegment.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgSim\MultiSwitch.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgSim\Version.cpp
# End Source File
# End Group
@@ -181,6 +185,10 @@ SOURCE=..\..\include\osgSim\SphereSegment
# End Source File
# Begin Source File
SOURCE=..\..\include\osgSim\MultiSwitch
# End Source File
# Begin Source File
SOURCE=..\..\include\osgSim\Export
# End Source File
# Begin Source File

View File

@@ -0,0 +1,91 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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.
*/
#ifndef OSG_MULTISWITCH
#define OSG_MULTISWITCH 1
#include <osg/Group>
namespace osgSim {
/** MultiSwitch is a Group node which allows switching between sets of selected children.
MultiSwtich is based on the OpenFlight switch behaviour.
*/
class SG_EXPORT MultiSwitch : public osg::Group
{
public :
MultiSwitch();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
MultiSwitch(const MultiSwitch&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
META_Node(osgSim, MultiSwitch);
virtual void traverse(osg::NodeVisitor& nv);
void setNewChildDefaultValue(bool value) { _newChildDefaultValue = value; }
bool getNewChildDefaultValue() const { return _newChildDefaultValue; }
virtual bool addChild( Node *child );
virtual bool insertChild( unsigned int index, Node *child );
virtual bool removeChild( Node *child );
void setValue(unsigned int switchSet, unsigned int pos,bool value);
bool getValue(unsigned int switchSet, unsigned int pos) const;
void setChildValue(const Node* child,unsigned int switchSet, bool value);
bool getChildValue(const Node* child,unsigned int switchSet) const;
/** Set all the children off (false), and set the new default child value to off (false).*/
bool setAllChildrenOff(unsigned int switchSet);
/** Set all the children on (true), and set the new default child value to on (true).*/
bool setAllChildrenOn(unsigned int switchSet);
/** Set a single child to be on, MultiSwitch off all other children.*/
bool setSingleChildOn(unsigned int switchSet, unsigned int pos);
/** Set which of the available switch set lists to use.*/
void setActiveSwitchSet(unsigned int switchSet) { _activeSwitchSet = switchSet; }
/** Get which of the available switch set lists to use.*/
unsigned int getActiveSwitchSet(unsigned int switchSet) { return _activeSwitchSet; }
typedef std::vector<bool> ValueList;
typedef std::vector<ValueList> SwitchSetList;
const SwitchSetList& getSwitchSetList() const { return _values; }
const ValueList& getValueList(unsigned int switchSet) const { return _values[switchSet]; }
protected :
virtual ~MultiSwitch() {}
void expandToEncompassSwitchSet(unsigned int switchSet);
// this is effectively a list of bit mask.
bool _newChildDefaultValue;
unsigned int _activeSwitchSet;
SwitchSetList _values;
};
}
#endif

View File

@@ -10,7 +10,6 @@
#include <osg/Group>
#include <osg/LOD>
#include <osg/MatrixTransform>
#include <osg/Switch>
#include <osg/Geode>
#include <osg/StateSet>
#include <osg/CullFace>
@@ -29,15 +28,16 @@
#include <osg/LightSource>
#include <osg/Image>
#include <osg/Notify>
#include <osg/Sequence>
#include <osgSim/MultiSwitch>
#include <osgSim/DOFTransform>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <osgSim/DOFTransform>
#include "opcodes.h"
#include "flt.h"
@@ -997,23 +997,22 @@ osg::Group* ConvertFromFLT::visitDOF(osg::Group& osgParent, DofRecord* rec)
osg::Group* ConvertFromFLT::visitSwitch(osg::Group& osgParent, SwitchRecord* rec)
{
SSwitch *pSSwitch = (SSwitch*)rec->getData();
osg::Switch* osgSwitch = new osg::Switch;
osgSim::MultiSwitch* osgSwitch = new osgSim::MultiSwitch;
osgSwitch->setName(pSSwitch->szIdent);
visitAncillary(osgParent, *osgSwitch, rec)->addChild( osgSwitch );
osg::ref_ptr<osg::Group> allChildrenGroup = new osg::Group;
visitPrimaryNode(*allChildrenGroup, (PrimNodeRecord*)rec);
visitPrimaryNode(*osgSwitch, (PrimNodeRecord*)rec);
unsigned int totalNumChildren = (unsigned int)rec->getNumChildren();
if (totalNumChildren!=allChildrenGroup->getNumChildren())
if (totalNumChildren!=osgSwitch->getNumChildren())
{
// only convert the children we agree on,
// however, there could be a chance that ordering of children might
// be different if there a children that hanvn't mapped across...
if (totalNumChildren>allChildrenGroup->getNumChildren()) totalNumChildren=allChildrenGroup->getNumChildren();
if (totalNumChildren>osgSwitch->getNumChildren()) totalNumChildren=osgSwitch->getNumChildren();
osg::notify(osg::INFO)<<"Warning::OpenFlight loader has come across an incorrectly handled switch."<<std::endl;
osg::notify(osg::INFO)<<" The number of OpenFlight children ("<<rec->getNumChildren()<<") "<<std::endl;
osg::notify(osg::INFO)<<" exceeds the number converted to OSG ("<<allChildrenGroup->getNumChildren()<<")"<<std::endl;
osg::notify(osg::INFO)<<" exceeds the number converted to OSG ("<<osgSwitch->getNumChildren()<<")"<<std::endl;
}
// for each mask in the FLT Switch node
@@ -1023,20 +1022,16 @@ osg::Group* ConvertFromFLT::visitSwitch(osg::Group& osgParent, SwitchRecord* rec
osg::ref_ptr<osg::Group> group = new osg::Group;
osgSwitch->addChild( group.get() );
// for each child in the FLT Switch node
for (unsigned itChild=0; itChild<totalNumChildren; ++itChild)
for (unsigned int itChild=0; itChild<totalNumChildren; ++itChild)
{
// test if this child is active in the current mask (itMask)
unsigned int nMaskBit = itChild % 32;
unsigned int nMaskWord = itMask * pSSwitch->nWordsInMask + itChild / 32;
if ( (pSSwitch->aMask[nMaskWord] & (uint32(1) << nMaskBit))!=0 )
{
// add this child in the group
group->addChild( allChildrenGroup->getChild(itChild) );
}
osgSwitch->setValue(itMask, itChild, (pSSwitch->aMask[nMaskWord] & (uint32(1) << nMaskBit))!=0 );
}
// now the group contain all the childrens that are active in the current mask (itMask)
}
osgSwitch->setSingleChildOn(pSSwitch->nCurrentMask);
osgSwitch->setActiveSwitchSet(pSSwitch->nCurrentMask);
return osgSwitch;
}

View File

@@ -6,6 +6,7 @@ CXXFILES =\
IO_LightPointNode.cpp\
IO_LightPoint.cpp\
IO_BlinkSequence.cpp\
IO_MultiSwitch.cpp\
IO_Sector.cpp
LIBS += -losgSim -losgText $(OSG_LIBS) $(OTHER_LIBS)

View File

@@ -0,0 +1,113 @@
#include "osgSim/MultiSwitch"
#include "osgDB/Registry"
#include "osgDB/Input"
#include "osgDB/Output"
using namespace osg;
using namespace osgSim;
using namespace osgDB;
// forward declare functions to use later.
bool MultiSwitch_readLocalData(Object& obj, Input& fr);
bool MultiSwitch_writeLocalData(const Object& obj, Output& fw);
// register the read and write functions with the osgDB::Registry.
RegisterDotOsgWrapperProxy g_SwitchProxy
(
new osgSim::MultiSwitch,
"MultiSwitch",
"Object Node MultiSwitch Group",
&MultiSwitch_readLocalData,
&MultiSwitch_writeLocalData
);
bool MultiSwitch_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
MultiSwitch& sw = static_cast<MultiSwitch&>(obj);
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!=0);
iteratorAdvanced = true;
fr += 2;
}
}
if (fr.matchSequence("ValueList %i {"))
{
int entry = fr[0].getNoNestedBrackets();
unsigned int switchSet;
fr[1].getUInt(switchSet);
// move inside the brakets.
fr += 3;
unsigned int pos=0;
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
int value;
if (fr[0].getInt(value))
{
sw.setValue(switchSet, pos,value!=0);
++pos;
}
++fr;
}
++fr;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool MultiSwitch_writeLocalData(const Object& obj, Output& fw)
{
const MultiSwitch& sw = static_cast<const MultiSwitch&>(obj);
fw.indent()<<"NewChildDefaultValue "<<sw.getNewChildDefaultValue()<<std::endl;
unsigned int pos = 0;
const osgSim::MultiSwitch::SwitchSetList& switchset = sw.getSwitchSetList();
for(osgSim::MultiSwitch::SwitchSetList::const_iterator sitr=switchset.begin();
sitr!=switchset.end();
++sitr,++pos)
{
fw.indent()<<"ValueList "<<pos<<" {"<< std::endl;
fw.moveIn();
const MultiSwitch::ValueList& values = *sitr;
for(MultiSwitch::ValueList::const_iterator itr=values.begin();
itr!=values.end();
++itr)
{
fw.indent()<<*itr<<std::endl;
}
fw.moveOut();
fw.indent()<<"}"<< std::endl;
}
return true;
}

View File

@@ -3,16 +3,17 @@ include $(TOPDIR)/Make/makedefs
CXXFILES = \
BlinkSequence.cpp\
ColorRange.cpp\
DOFTransform.cpp\
ScalarBar.cpp\
ScalarsToColors.cpp\
BlinkSequence.cpp\
LightPoint.cpp\
LightPointDrawable.cpp\
LightPointNode.cpp\
ScalarBar.cpp\
ScalarsToColors.cpp\
Sector.cpp\
SphereSegment.cpp\
MultiSwitch.cpp\
Version.cpp\
DEF += -DOSGSIM_LIBRARY

217
src/osgSim/MultiSwitch.cpp Normal file
View File

@@ -0,0 +1,217 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 <osgSim/MultiSwitch>
#include <algorithm>
using namespace osgSim;
MultiSwitch::MultiSwitch():
_newChildDefaultValue(true),
_activeSwitchSet(0)
{
}
MultiSwitch::MultiSwitch(const MultiSwitch& sw,const osg::CopyOp& copyop):
osg::Group(sw,copyop),
_newChildDefaultValue(sw._newChildDefaultValue),
_values(sw._values)
{
}
void MultiSwitch::traverse(osg::NodeVisitor& nv)
{
if (nv.getTraversalMode()==osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
{
if (_activeSwitchSet<_values.size())
{
for(unsigned int pos=0;pos<_children.size();++pos)
{
if (_values[_activeSwitchSet][pos]) _children[pos]->accept(nv);
}
}
}
else
{
Group::traverse(nv);
}
}
bool MultiSwitch::addChild( Node *child)
{
unsigned int childPosition = _children.size();
if (Group::addChild(child))
{
for(SwitchSetList::iterator itr=_values.begin();
itr!=_values.end();
++itr)
{
ValueList& values = *itr;
if (_children.size()>_values.size())
{
values.resize(_children.size(),_newChildDefaultValue);
values[childPosition]=_newChildDefaultValue;
}
}
return true;
}
return false;
}
bool MultiSwitch::insertChild( unsigned int index, Node *child)
{
if (Group::insertChild(index,child))
{
for(SwitchSetList::iterator itr=_values.begin();
itr!=_values.end();
++itr)
{
ValueList& values = *itr;
if (index>=_values.size())
{
values.push_back(_newChildDefaultValue);
}
else
{
values.insert(values.begin()+index, _newChildDefaultValue);
}
}
return true;
}
return false;
}
bool MultiSwitch::removeChild( Node *child )
{
// find the child's position.
unsigned int pos=getChildIndex(child);
if (pos==_children.size()) return false;
for(SwitchSetList::iterator itr=_values.begin();
itr!=_values.end();
++itr)
{
ValueList& values = *itr;
values.erase(values.begin()+pos);
}
return Group::removeChild(child);
}
void MultiSwitch::setValue(unsigned int switchSet, unsigned int pos,bool value)
{
expandToEncompassSwitchSet(switchSet);
ValueList& values = _values[switchSet];
if (pos>=values.size()) values.resize(pos+1,_newChildDefaultValue);
values[pos]=value;
}
void MultiSwitch::setChildValue(const Node* child,unsigned int switchSet, bool value)
{
expandToEncompassSwitchSet(switchSet);
// find the child's position.
unsigned int pos=getChildIndex(child);
if (pos==_children.size()) return;
ValueList& values = _values[switchSet];
values[pos]=value;
}
bool MultiSwitch::getValue(unsigned int switchSet, unsigned int pos) const
{
if (switchSet>=_values.size()) return false;
const ValueList& values = _values[switchSet];
if (pos>=values.size()) return false;
return values[pos];
}
bool MultiSwitch::getChildValue(const Node* child, unsigned int switchSet) const
{
if (switchSet>=_values.size()) return false;
// find the child's position.
unsigned int pos=getChildIndex(child);
if (pos==_children.size()) return false;
const ValueList& values = _values[switchSet];
return values[pos];
}
void MultiSwitch::expandToEncompassSwitchSet(unsigned int switchSet)
{
if (switchSet>=_values.size())
{
// need to expand arrays.
unsigned int originalSize = _values.size();
_values.resize(switchSet+1);
for(unsigned int i=originalSize;i<=switchSet;++i)
{
ValueList& values = _values[switchSet];
values.resize(_children.size(),_newChildDefaultValue);
}
}
}
bool MultiSwitch::setAllChildrenOff(unsigned int switchSet)
{
_newChildDefaultValue = false;
expandToEncompassSwitchSet(switchSet);
ValueList& values = _values[switchSet];
for(ValueList::iterator itr=values.begin();
itr!=values.end();
++itr)
{
*itr = false;
}
return true;
}
bool MultiSwitch::setAllChildrenOn(unsigned int switchSet)
{
_newChildDefaultValue = true;
expandToEncompassSwitchSet(switchSet);
ValueList& values = _values[switchSet];
for(ValueList::iterator itr=values.begin();
itr!=values.end();
++itr)
{
*itr = true;
}
return true;
}
bool MultiSwitch::setSingleChildOn(unsigned int switchSet, unsigned int pos)
{
expandToEncompassSwitchSet(switchSet);
ValueList& values = _values[switchSet];
for(ValueList::iterator itr=values.begin();
itr!=values.end();
++itr)
{
*itr = false;
}
setValue(switchSet, pos,true);
return true;
}