Hi Robert,
The files attached should be separately put into the directories
src/osgPlugins/osg and src/osgWrappers/serializers/osgSim. They fix a
serious infinite loop problem that may be caused by the stream buffer
mechanism under Windows and some osgSim wrapper bugs pointed by
Andreas. I've asked the community to help test them and hope now we
can solve these recent .osgt file reading issues.
Cheers,
Wang Rui
#ifndef OSGDB_ASCIISTREAMOPERATOR
#define OSGDB_ASCIISTREAMOPERATOR
#include <ostream>
#include <osgDB/StreamOperator>
class AsciiOutputIterator : public osgDB::OutputIterator
{
public:
AsciiOutputIterator( std::ostream* ostream )
: _readyForIndent(false), _indent(0) { _out = ostream; }
virtual ~AsciiOutputIterator() {}
virtual bool isBinary() const { return false; }
virtual void writeBool( bool b )
{
indentIfRequired();
if ( b ) *_out << "TRUE ";
else *_out << "FALSE ";
}
virtual void writeChar( char c )
{ indentIfRequired(); *_out << (short)c << ' '; }
virtual void writeUChar( unsigned char c )
{ indentIfRequired(); *_out << (unsigned short)c << ' '; }
virtual void writeShort( short s )
{ indentIfRequired(); *_out << s << ' '; }
virtual void writeUShort( unsigned short s )
{ indentIfRequired(); *_out << s << ' '; }
virtual void writeInt( int i )
{ indentIfRequired(); *_out << i << ' '; }
virtual void writeUInt( unsigned int i )
{ indentIfRequired(); *_out << i << ' '; }
virtual void writeLong( long l )
{ indentIfRequired(); *_out << l << ' '; }
virtual void writeULong( unsigned long l )
{ indentIfRequired(); *_out << l << ' '; }
virtual void writeFloat( float f )
{ indentIfRequired(); *_out << f << ' '; }
virtual void writeDouble( double d )
{ indentIfRequired(); *_out << d << ' '; }
virtual void writeString( const std::string& s )
{ indentIfRequired(); *_out << s << ' '; }
virtual void writeStream( std::ostream& (*fn)(std::ostream&) )
{
indentIfRequired(); *_out << fn;
if ( isEndl( fn ) )
{
_readyForIndent = true;
}
}
virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) )
{
indentIfRequired(); *_out << fn;
}
virtual void writeGLenum( const osgDB::ObjectGLenum& value )
{
GLenum e = value.get();
const std::string& enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString("GL", e);
indentIfRequired(); *_out << enumString << ' ';
}
virtual void writeProperty( const osgDB::ObjectProperty& prop )
{
std::string enumString = prop._name;
if ( prop._mapProperty )
{
enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString(prop._name, prop._value);
}
indentIfRequired(); *_out << enumString << ' ';
}
virtual void writeMark( const osgDB::ObjectMark& mark )
{
_indent += mark._indentDelta;
indentIfRequired(); *_out << mark._name;
}
virtual void writeCharArray( const char* s, unsigned int size ) {}
virtual void writeWrappedString( const std::string& str )
{
std::string wrappedStr;
unsigned int size = str.size();
for ( unsigned int i=0; i<size; ++i )
{
char ch = str[i];
if ( ch=='\"' ) wrappedStr += '\\';
else if ( ch=='\\' ) wrappedStr += '\\';
wrappedStr += ch;
}
wrappedStr.insert( std::string::size_type(0), 1, '\"' );
wrappedStr += '\"';
indentIfRequired();
writeString( wrappedStr );
}
protected:
inline void indentIfRequired()
{
if ( _readyForIndent )
{
for (int i=0; i<_indent; ++i)
*_out << ' ';
_readyForIndent = false;
}
}
bool _readyForIndent;
int _indent;
};
class AsciiInputIterator : public osgDB::InputIterator
{
public:
AsciiInputIterator( std::istream* istream ) { _in = istream; }
virtual ~AsciiInputIterator() {}
virtual bool isBinary() const { return false; }
virtual void readBool( bool& b )
{
std::string boolString;
readString( boolString );
if ( boolString=="TRUE" ) b = true;
else b = false;
}
virtual void readChar( char& c )
{
short s = 0;
readShort( s );
c = (char)s;
}
virtual void readSChar( signed char& c )
{
short s = 0;
readShort( s );
c = (signed char)s;
}
virtual void readUChar( unsigned char& c )
{
short s = 0;
readShort( s );
c = (unsigned char)s;
}
virtual void readShort( short& s )
{ std::string str; readString(str); s = static_cast<short>(strtol(str.c_str(), NULL, 0)); }
virtual void readUShort( unsigned short& s )
{ std::string str; readString(str); s = static_cast<unsigned short>(strtoul(str.c_str(), NULL, 0)); }
virtual void readInt( int& i )
{ std::string str; readString(str); i = static_cast<int>(strtol(str.c_str(), NULL, 0)); }
virtual void readUInt( unsigned int& i )
{ std::string str; readString(str); i = static_cast<unsigned int>(strtoul(str.c_str(), NULL, 0)); }
virtual void readLong( long& l )
{ std::string str; readString(str); l = strtol(str.c_str(), NULL, 0); }
virtual void readULong( unsigned long& l )
{ std::string str; readString(str); l = strtoul(str.c_str(), NULL, 0); }
virtual void readFloat( float& f )
{ std::string str; readString(str); f = osg::asciiToFloat(str.c_str()); }
virtual void readDouble( double& d )
{ std::string str; readString(str); d = osg::asciiToDouble(str.c_str()); }
virtual void readString( std::string& s )
{
if ( _preReadString.empty() )
*_in >> s;
else
{
s = _preReadString;
_preReadString.clear();
}
}
virtual void readStream( std::istream& (*fn)(std::istream&) )
{ *_in >> fn; }
virtual void readBase( std::ios_base& (*fn)(std::ios_base&) )
{ *_in >> fn; }
virtual void readGLenum( osgDB::ObjectGLenum& value )
{
GLenum e = 0;
std::string enumString;
readString( enumString );
e = osgDB::Registry::instance()->getObjectWrapperManager()->getValue("GL", enumString);
value.set( e );
}
virtual void readProperty( osgDB::ObjectProperty& prop )
{
int value = 0;
std::string enumString;
readString( enumString );
if ( prop._mapProperty )
{
value = osgDB::Registry::instance()->getObjectWrapperManager()->getValue(prop._name, enumString);
}
else
{
if ( prop._name!=enumString )
{
OSG_WARN << "AsciiInputIterator::readProperty(): Unmatched property "
<< enumString << ", expecting " << prop._name << std::endl;
}
prop._name = enumString;
}
prop.set( value );
}
virtual void readMark( osgDB::ObjectMark& mark )
{
std::string markString;
readString( markString );
}
virtual void readCharArray( char* s, unsigned int size ) {}
virtual void readWrappedString( std::string& str )
{
if ( !_preReadString.empty() )
{
str = _preReadString;
return;
}
char ch;
_in->get( ch ); checkStream();
// skip white space
while ( ch==' ' || (ch=='\n') || (ch=='\r'))
{
_in->get( ch ); checkStream();
}
if (ch=='"')
{
// we have an "wrapped string"
_in->get( ch ); checkStream();
while ( ch!='"' )
{
if (ch=='\\')
{
_in->get( ch ); checkStream();
str += ch;
}
else str += ch;
_in->get( ch ); checkStream();
}
}
else
{
// we have an unwrapped string, read to first space or end of line
while ( (ch!=' ') && (ch!=0) && (ch!='\n') )
{
str += ch;
_in->get( ch ); checkStream();
}
}
}
virtual bool matchString( const std::string& str )
{
if ( _preReadString.empty() )
*_in >> _preReadString;
if ( _preReadString==str )
{
_preReadString.clear();
return true;
}
return false;
}
virtual void advanceToCurrentEndBracket()
{
std::string passString;
unsigned int blocks = 0;
while ( !_in->eof() )
{
passString.clear();
readString( passString );
if ( passString=="}" )
{
if ( blocks<=0 ) return;
else blocks--;
}
else if ( passString=="{" )
blocks++;
}
}
protected:
std::string _preReadString;
};
#endif
#include <osgSim/LightPointNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkLightPointList( const osgSim::LightPointNode& node )
{
return node.getNumLightPoints()>0;
}
static bool readLightPointList( osgDB::InputStream& is, osgSim::LightPointNode& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osgSim::LightPoint pt;
is >> osgDB::PROPERTY("LightPoint") >> osgDB::BEGIN_BRACKET;
is >> osgDB::PROPERTY("Position") >> pt._position;
is >> osgDB::PROPERTY("Color") >> pt._color;
int blendingMode = 0;
is >> osgDB::PROPERTY("Attributes") >> pt._on >> blendingMode >> pt._intensity >> pt._radius;
pt._blendingMode = (osgSim::LightPoint::BlendingMode)blendingMode;
bool hasObject = false; is >> osgDB::PROPERTY("Sector") >> hasObject;
if ( hasObject )
{
is >> osgDB::BEGIN_BRACKET;
pt._sector = dynamic_cast<osgSim::Sector*>( is.readObject() );
is >> osgDB::END_BRACKET;
}
hasObject = false; is >> osgDB::PROPERTY("BlinkSequence") >> hasObject;
if ( hasObject )
{
is >> osgDB::BEGIN_BRACKET;
pt._blinkSequence = dynamic_cast<osgSim::BlinkSequence*>( is.readObject() );
is >> osgDB::END_BRACKET;
}
is >> osgDB::END_BRACKET;
node.addLightPoint( pt );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeLightPointList( osgDB::OutputStream& os, const osgSim::LightPointNode& node )
{
unsigned int size = node.getNumLightPoints();
os << size << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<size; ++i )
{
const osgSim::LightPoint& pt = node.getLightPoint(i);
os << osgDB::PROPERTY("LightPoint") << osgDB::BEGIN_BRACKET << std::endl;
os << osgDB::PROPERTY("Position") << pt._position << std::endl;
os << osgDB::PROPERTY("Color") << pt._color << std::endl;
os << osgDB::PROPERTY("Attributes") << pt._on << (int)pt._blendingMode
<< pt._intensity << pt._radius << std::endl;
os << osgDB::PROPERTY("Sector") << (pt._sector!=NULL);
if ( pt._sector!=NULL )
{
os << osgDB::BEGIN_BRACKET << std::endl;
os.writeObject( pt._sector.get() );
os << osgDB::END_BRACKET << std::endl;
}
os << osgDB::PROPERTY("BlinkSequence") << (pt._blinkSequence!=NULL);
if ( pt._blinkSequence!=NULL )
{
os << osgDB::BEGIN_BRACKET << std::endl;
os.writeObject( pt._blinkSequence.get() );
os << osgDB::END_BRACKET << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( osgSim_LightPointNode,
new osgSim::LightPointNode,
osgSim::LightPointNode,
"osg::Object osg::Node osgSim::LightPointNode" )
{
ADD_USER_SERIALIZER( LightPointList ); // _lightPointList
ADD_FLOAT_SERIALIZER( MinPixelSize, 0.0f ); // _minPixelSize
ADD_FLOAT_SERIALIZER( MaxPixelSize, 30.0f ); // _maxPixelSize
ADD_FLOAT_SERIALIZER( MaxVisibleDistance2, FLT_MAX ); // _maxVisibleDistance2
ADD_OBJECT_SERIALIZER( LightPointSystem, osgSim::LightPointSystem, NULL ); // _lightSystem
ADD_BOOL_SERIALIZER( PointSprite, false ); // _pointSprites
}
#include <osgSim/MultiSwitch>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkValues( const osgSim::MultiSwitch& node )
{
return node.getSwitchSetList().size()>0;
}
static bool readValues( osgDB::InputStream& is, osgSim::MultiSwitch& node )
{
unsigned int size = is.readSize(); is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
is >> osgDB::PROPERTY("SwitchSet");
unsigned int valueSize = is.readSize(); is >> osgDB::BEGIN_BRACKET;
osgSim::MultiSwitch::ValueList values;
for ( unsigned int j=0; j<valueSize; ++j )
{
bool value; is >> value;
values.push_back( value );
}
node.setValueList( i, values );
is >> osgDB::END_BRACKET;
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeValues( osgDB::OutputStream& os, const osgSim::MultiSwitch& node )
{
const osgSim::MultiSwitch::SwitchSetList& switches = node.getSwitchSetList();
os.writeSize( switches.size() ); os << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<switches.size(); ++i )
{
const osgSim::MultiSwitch::ValueList& values = node.getValueList(i);
os << osgDB::PROPERTY("SwitchSet"); os.writeSize( values.size() );
os << osgDB::BEGIN_BRACKET << std::endl;
for ( osgSim::MultiSwitch::ValueList::const_iterator itr=values.begin();
itr!=values.end(); ++itr )
{
os << *itr << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( osgSim_MultiSwitch,
new osgSim::MultiSwitch,
osgSim::MultiSwitch,
"osg::Object osg::Node osg::Group osgSim::MultiSwitch" )
{
ADD_BOOL_SERIALIZER( NewChildDefaultValue, true ); // _newChildDefaultValue
ADD_UINT_SERIALIZER( ActiveSwitchSet, 0 ); // _activeSwitchSet
ADD_USER_SERIALIZER( Values ); // _values
}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org