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

@@ -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;
}