Added osgSim::MultiSwitch and support for it in the OpenFlight and
.osg plugins
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
91
include/osgSim/MultiSwitch
Normal file
91
include/osgSim/MultiSwitch
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
113
src/osgPlugins/osgSim/IO_MultiSwitch.cpp
Normal file
113
src/osgPlugins/osgSim/IO_MultiSwitch.cpp
Normal 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;
|
||||
}
|
||||
@@ -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
217
src/osgSim/MultiSwitch.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user