From Wang Rui, new native binary/ascii format infrastructure and wrappers.

From Robert Osfield, refactor of Wang Rui's original osg2 into 3 parts - parts placed into osgDB, the ReaderWriter placed into src/osg/Plugin/osg and wrappers into src/osgWrappers/serializers/osg
This commit is contained in:
Robert Osfield
2010-01-20 20:13:33 +00:00
parent 9806aebaf3
commit 219696f1ee
122 changed files with 8286 additions and 58 deletions

127
include/osgDB/DataTypes Normal file
View File

@@ -0,0 +1,127 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#ifndef H_DATATYPES
#define H_DATATYPES
#include <string>
namespace osgDB
{
// OSG Header (MD5, 16Bit)
#define OSG_HEADER_LOW 0x6C910EA1
#define OSG_HEADER_HIGH 0x1AFB4545
// Reader/writer plugin version
#define PLUGIN_VERSION 2
#define BOOL_SIZE 1
#define CHAR_SIZE 1
#define SHORT_SIZE 2
#define INT_SIZE 4
#define LONG_SIZE 4
#define FLOAT_SIZE 4
#define DOUBLE_SIZE 8
#define GLENUM_SIZE 4
#define ID_BYTE_ARRAY 0
#define ID_UBYTE_ARRAY 1
#define ID_SHORT_ARRAY 2
#define ID_USHORT_ARRAY 3
#define ID_INT_ARRAY 4
#define ID_UINT_ARRAY 5
#define ID_FLOAT_ARRAY 6
#define ID_DOUBLE_ARRAY 7
#define ID_VEC2B_ARRAY 8
#define ID_VEC3B_ARRAY 9
#define ID_VEC4B_ARRAY 10
#define ID_VEC4UB_ARRAY 11
#define ID_VEC2S_ARRAY 12
#define ID_VEC3S_ARRAY 13
#define ID_VEC4S_ARRAY 14
#define ID_VEC2_ARRAY 15
#define ID_VEC3_ARRAY 16
#define ID_VEC4_ARRAY 17
#define ID_VEC2D_ARRAY 18
#define ID_VEC3D_ARRAY 19
#define ID_VEC4D_ARRAY 20
#define ID_DRAWARRAYS 50
#define ID_DRAWARRAY_LENGTH 51
#define ID_DRAWELEMENTS_UBYTE 52
#define ID_DRAWELEMENTS_USHORT 53
#define ID_DRAWELEMENTS_UINT 54
// Used by BEGIN_BRACKET and END_BRACKET
#define INDENT_VALUE 2
// Used by the writeImage/readImage parameter
#define IMAGE_INLINE_DATA 0
#define IMAGE_INLINE_FILE 1
#define IMAGE_EXTERNAL 2
#define IMAGE_WRITE_OUT 3
struct ObjectGLenum
{
ObjectGLenum( GLenum value=0 ) : _value(value) {}
ObjectGLenum( const ObjectGLenum& copy ) : _value(copy._value) {}
void set( GLenum e ) { _value = e; }
GLenum get() const { return _value; }
GLenum _value;
};
#define GLENUM(value) osgDB::ObjectGLenum(value)
#define DEF_GLENUM(var) osgDB::ObjectGLenum var;
struct ObjectProperty
{
ObjectProperty( const char* name, int value=0, bool useMap=false )
: _name(name), _value(value), _mapProperty(useMap) {}
ObjectProperty( const ObjectProperty& copy )
: _name(copy._name), _value(copy._value), _mapProperty(copy._mapProperty) {}
ObjectProperty& proto( const char* name )
{ _name = name; return *this; }
void set( int v ) { _value = v; }
int get() const { return _value; }
std::string _name;
int _value;
bool _mapProperty;
};
static ObjectProperty defaultProp("");
#define PROPERTY(name) defaultProp.proto(name)
#define MAPPEE(pairName, value) osgDB::ObjectProperty(#pairName, value, true)
#define DEF_PROPERTY(name, var) osgDB::ObjectProperty var(name);
#define DEF_MAPPEE(pairName, var) osgDB::ObjectProperty var(#pairName, 0, true);
struct ObjectMark
{
ObjectMark( const char* name, int delta=0 )
: _name(name), _indentDelta(delta) {}
ObjectMark( const ObjectMark& copy )
: _name(copy._name), _indentDelta(copy._indentDelta) {}
std::string _name;
int _indentDelta;
};
static ObjectMark BEGIN_BRACKET("{", +INDENT_VALUE);
static ObjectMark END_BRACKET ("}", -INDENT_VALUE);
}
#endif

View File

@@ -79,6 +79,44 @@ class OSGDB_EXPORT DotOsgWrapper : public osg::Referenced
ReadWriteMode _readWriteMode;
};
/** Proxy class for automatic registration of DotOsgWrappers with the Registry.*/
class RegisterDotOsgWrapperProxy
{
public:
RegisterDotOsgWrapperProxy(osg::Object* proto,
const std::string& name,
const std::string& associates,
DotOsgWrapper::ReadFunc readFunc,
DotOsgWrapper::WriteFunc writeFunc,
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE);
~RegisterDotOsgWrapperProxy();
protected:
osg::ref_ptr<DotOsgWrapper> _wrapper;
};
template<class T>
class TemplateRegisterDotOsgWrapperProxy : public RegisterDotOsgWrapperProxy, public T
{
public:
TemplateRegisterDotOsgWrapperProxy(osg::Object* proto,
const std::string& name,
const std::string& associates,
DotOsgWrapper::ReadFunc readFunc,
DotOsgWrapper::WriteFunc writeFunc,
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE):
RegisterDotOsgWrapperProxy(proto, name, associates, readFunc, writeFunc, readWriteMode) {}
};
#define REGISTER_DOTOSGWRAPPER(classname) \
extern "C" void dotosgwrapper_##classname(void) {} \
static osgDB::RegisterDotOsgWrapperProxy dotosgwrapper_proxy_##classname
}
#endif

438
include/osgDB/InputStream Normal file
View File

@@ -0,0 +1,438 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#ifndef H_INPUTSTREAM
#define H_INPUTSTREAM
#include <osg/Endian>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Quat>
#include <osg/Matrix>
#include <osg/Array>
#include <osg/PrimitiveSet>
#include <osgDB/ReaderWriter>
#include <osgDB/DataTypes>
#include <iostream>
#include <sstream>
namespace osgDB
{
class InputException
{
public:
InputException( const std::string& field, const std::string& err )
: _field(field), _error(err) {}
const std::string& getField() const { return _field; }
const std::string& getError() const { return _error; }
protected:
std::string _field;
std::string _error;
};
class InputStream
{
public:
typedef std::map< unsigned int, osg::ref_ptr<osg::Array> > ArrayMap;
typedef std::map< unsigned int, osg::ref_ptr<osg::Object> > IdentifierMap;
enum ReadMode
{
READ_BINARY = 0,
READ_ASCII
};
enum ReadType
{
READ_UNKNOWN = 0,
READ_SCENE,
READ_IMAGE
};
InputStream( std::istream* istream, const osgDB::Options* options );
virtual ~InputStream();
bool isBinary() const { return _readMode==READ_BINARY; }
bool getUseFloatMatrix() const { return _useFloatMatrix; }
// Serialization related functions
inline InputStream& operator>>( bool& b );
inline InputStream& operator>>( char& c );
inline InputStream& operator>>( signed char& c );
inline InputStream& operator>>( unsigned char& c );
inline InputStream& operator>>( short& s );
inline InputStream& operator>>( unsigned short& s );
inline InputStream& operator>>( int& i );
inline InputStream& operator>>( unsigned int& i );
inline InputStream& operator>>( long& l );
inline InputStream& operator>>( unsigned long& l );
inline InputStream& operator>>( float& f );
inline InputStream& operator>>( double& d );
inline InputStream& operator>>( std::string& s );
inline InputStream& operator>>( std::istream& (*fn)(std::istream&) );
inline InputStream& operator>>( std::ios_base& (*fn)(std::ios_base&) );
InputStream& operator>>( osg::Vec2b& v );
InputStream& operator>>( osg::Vec3b& v );
InputStream& operator>>( osg::Vec4b& v );
InputStream& operator>>( osg::Vec4ub& v );
InputStream& operator>>( osg::Vec2s& v );
InputStream& operator>>( osg::Vec3s& v );
InputStream& operator>>( osg::Vec4s& v );
InputStream& operator>>( osg::Vec2f& v );
InputStream& operator>>( osg::Vec3f& v );
InputStream& operator>>( osg::Vec4f& v );
InputStream& operator>>( osg::Vec2d& v );
InputStream& operator>>( osg::Vec3d& v );
InputStream& operator>>( osg::Vec4d& v );
InputStream& operator>>( osg::Quat& q );
InputStream& operator>>( osg::Plane& p );
InputStream& operator>>( osg::Matrixf& mat );
InputStream& operator>>( osg::Matrixd& mat );
InputStream& operator>>( osg::Array*& a ) { a = readArray(); return *this; }
InputStream& operator>>( osg::Image*& img ) { img = readImage(); return *this; }
InputStream& operator>>( osg::PrimitiveSet*& p ) { p = readPrimitiveSet(); return *this; }
InputStream& operator>>( osg::Object*& obj ) { obj = readObject(); return *this; }
InputStream& operator>>( osg::ref_ptr<osg::Array>& ptr ) { ptr = readArray(); return *this; }
InputStream& operator>>( osg::ref_ptr<osg::Image>& ptr ) { ptr = readImage(); return *this; }
InputStream& operator>>( osg::ref_ptr<osg::PrimitiveSet>& ptr ) { ptr = readPrimitiveSet(); return *this; }
template<typename T> InputStream& operator>>( osg::ref_ptr<T>& ptr )
{ ptr = static_cast<T*>(readObject()); return *this; }
InputStream& operator>>( ObjectGLenum& value );
InputStream& operator>>( ObjectProperty& prop );
InputStream& operator>>( ObjectMark& mark );
// Convenient methods for reading
inline bool matchString( const std::string& str );
inline void advanceToCurrentEndBracket();
inline void readWrappedString( std::string& str );
inline void readCharArray( char* s, unsigned int size );
// Global reading functions
osg::Array* readArray();
osg::PrimitiveSet* readPrimitiveSet();
osg::Image* readImage();
osg::Object* readObject( osg::Object* existingObj=0 );
ReadType start();
void decompress();
// Schema handlers
void readSchema( std::istream& fin );
void resetSchema();
protected:
inline void checkStream() const;
void setWrapperSchema( const std::string& name, const std::string& properties );
template<typename T>
void readArrayImplementation( T* a, int readSize, bool useByteSwap=false );
ArrayMap _arrayMap;
IdentifierMap _identifierMap;
ReadMode _readMode;
int _byteSwap;
bool _useFloatMatrix;
std::string _currentField;
std::istream* _in;
};
// INLINE METHODS
InputStream& InputStream::operator>>( bool& b )
{
if ( isBinary() )
{
char c = 0;
_in->read( &c, CHAR_SIZE ); checkStream();
b = (c!=0);
}
else
{
std::string boolString;
*_in >> boolString; checkStream();
if ( boolString=="TRUE" ) b = true;
else b = false;
}
return *this;
}
InputStream& InputStream::operator>>( char& c )
{
if ( isBinary() )
{
_in->read( &c, CHAR_SIZE ); checkStream();
}
else
{
short s = 0;
*_in >> s; checkStream();
c = (char)s;
}
return *this;
}
InputStream& InputStream::operator>>( signed char& c )
{
if ( isBinary() )
{
_in->read( (char*)&c, CHAR_SIZE ); checkStream();
}
else
{
short s = 0;
*_in >> s; checkStream();
c = (signed char)s;
}
return *this;
}
InputStream& InputStream::operator>>( unsigned char& c )
{
if ( isBinary() )
{
_in->read( (char*)&c, CHAR_SIZE ); checkStream();
}
else
{
unsigned short s = 0;
*_in >> s; checkStream();
c = (unsigned char)s;
}
return *this;
}
InputStream& InputStream::operator>>( short& s )
{
if ( isBinary() )
{
_in->read( (char*)&s, SHORT_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE );
}
else
{
*_in >> s; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( unsigned short& s )
{
if ( isBinary() )
{
_in->read( (char*)&s, SHORT_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE );
}
else
{
*_in >> s; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( int& i )
{
if ( isBinary() )
{
_in->read( (char*)&i, INT_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE );
}
else
{
*_in >> i; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( unsigned int& i )
{
if ( isBinary() )
{
_in->read( (char*)&i, INT_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE );
}
else
{
*_in >> i; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( long& l )
{
if ( isBinary() )
{
_in->read( (char*)&l, LONG_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE );
}
else
{
*_in >> l; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( unsigned long& l )
{
if ( isBinary() )
{
_in->read( (char*)&l, LONG_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE );
}
else
{
*_in >> l; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( float& f )
{
if ( isBinary() )
{
_in->read( (char*)&f, FLOAT_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&f, FLOAT_SIZE );
}
else
{
*_in >> f; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( double& d )
{
if ( isBinary() )
{
_in->read( (char*)&d, DOUBLE_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&d, DOUBLE_SIZE );
}
else
{
*_in >> d; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( std::string& s )
{
if ( isBinary() )
{
int size = 0; *this >> size;
if ( size )
{
s.resize( size );
_in->read( (char*)s.c_str(), size ); checkStream();
}
}
else
{
*_in >> s; checkStream();
}
return *this;
}
InputStream& InputStream::operator>>( std::istream& (*fn)(std::istream&) )
{
if ( !isBinary() ) *_in >> fn;
return *this;
}
InputStream& InputStream::operator>>( std::ios_base& (*fn)(std::ios_base&) )
{
if ( !isBinary() ) *_in >> fn;
return *this;
}
bool InputStream::matchString( const std::string& str )
{
if ( !isBinary() )
{
std::string s;
*_in >> s; checkStream();
if ( s==str ) return true;
else _in->seekg( -(int)(s.length()), std::ios::cur );
}
return false;
}
void InputStream::advanceToCurrentEndBracket()
{
if ( isBinary() )
return;
std::string passString;
unsigned int blocks = 0;
while ( !_in->eof() )
{
passString.clear();
*_in >> passString;
if ( passString=="}" )
{
if ( blocks<=0 ) return;
else blocks--;
}
else if ( passString=="{" )
blocks++;
}
}
void InputStream::readWrappedString( std::string& str )
{
*this >> str;
if ( !isBinary() )
{
if ( str[0]=='\"' )
{
if ( str.size()==1 || (*str.rbegin())!='\"' )
{
char ch;
do
{
_in->get( ch ); checkStream();
str.append( 1, ch );
} while ( ch!='\"' );
}
str = str.substr(1, str.size()-2);
}
}
}
void InputStream::readCharArray( char* s, unsigned int size )
{
if ( size>0 )
{
_in->read( s, size ); checkStream();
}
}
void InputStream::checkStream() const
{
if ( _in->rdstate()&_in->failbit )
throw InputException(_currentField, "InputStream: Failed to read from stream.");
}
}
#endif

177
include/osgDB/ObjectWrapper Normal file
View File

@@ -0,0 +1,177 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#ifndef H_OBJECTWRAPPER
#define H_OBJECTWRAPPER
#include <osgDB/Serializer>
namespace osgDB
{
typedef std::vector<std::string> StringList;
extern void split( const std::string& src, StringList& list, char separator=' ' );
class BaseCompressor : public osg::Referenced
{
public:
BaseCompressor() {}
void setName( const std::string& name ) { _name = name; }
const std::string& getName() const { return _name; }
virtual bool compress( std::ostream&, const std::string& ) = 0;
virtual bool decompress( std::istream&, std::string& ) = 0;
protected:
std::string _name;
};
class ObjectWrapper : public osg::Referenced
{
public:
typedef std::vector< osg::ref_ptr<BaseSerializer> > SerializerList;
ObjectWrapper( osg::Object* proto, const std::string& name,
const std::string& associates );
const osg::Object* getProto() const { return _proto.get(); }
const std::string& getName() const { return _name; }
const StringList& getAssociates() const { return _associates; }
void addSerializer( BaseSerializer* s ) { _serializers.push_back(s); }
bool read( InputStream&, osg::Object& );
bool write( OutputStream&, const osg::Object& );
bool readSchema( const StringList& properties );
void writeSchema( StringList& properties );
void resetSchema()
{ if ( _backupSerializers.size()>0 ) _serializers = _backupSerializers; }
protected:
ObjectWrapper() {}
virtual ~ObjectWrapper() {}
osg::ref_ptr<osg::Object> _proto;
std::string _name;
StringList _associates;
SerializerList _serializers;
SerializerList _backupSerializers;
};
class ObjectRegistry : public osg::Referenced
{
public:
static ObjectRegistry* instance();
// Wrapper handlers
void addWrapper( ObjectWrapper* wrapper );
void removeWrapper( ObjectWrapper* wrapper );
ObjectWrapper* findWrapper( const std::string& name );
typedef std::map< std::string, osg::ref_ptr<ObjectWrapper> > WrapperMap;
WrapperMap& getWrapperMap() { return _wrappers; }
const WrapperMap& getWrapperMap() const { return _wrappers; }
// Compressor handlers
void addCompressor( BaseCompressor* compressor );
void removeCompressor( BaseCompressor* compressor );
BaseCompressor* findCompressor( const std::string& name );
typedef std::map< std::string, osg::ref_ptr<BaseCompressor> > CompressorMap;
CompressorMap& getCompressorMap() { return _compressors; }
const CompressorMap& getCompressorMap() const { return _compressors; }
protected:
ObjectRegistry() {}
virtual ~ObjectRegistry() {}
WrapperMap _wrappers;
CompressorMap _compressors;
};
class RegisterWrapperProxy
{
public:
typedef void (*AddPropFunc)( ObjectWrapper* );
RegisterWrapperProxy( osg::Object* proto, const std::string& name,
const std::string& associates, AddPropFunc func );
virtual ~RegisterWrapperProxy();
protected:
osg::ref_ptr<ObjectWrapper> _wrapper;
};
#define REGISTER_OBJECT_WRAPPER(NAME, PROTO, CLASS, ASSOCIATES) \
extern void wrapper_propfunc_##NAME(osgDB::ObjectWrapper*); \
static osgDB::RegisterWrapperProxy wrapper_proxy_##NAME( \
PROTO, #CLASS, ASSOCIATES, &wrapper_propfunc_##NAME); \
typedef CLASS MyClass; \
void wrapper_propfunc_##NAME(osgDB::ObjectWrapper* wrapper)
template<typename T>
class RegisterCompressorProxy
{
public:
RegisterCompressorProxy( const std::string& name )
{
_compressor = new T;
_compressor->setName( name );
ObjectRegistry::instance()->addCompressor( _compressor.get() );
}
virtual ~RegisterCompressorProxy()
{
ObjectRegistry::instance()->removeCompressor( _compressor.get() );
}
protected:
osg::ref_ptr<BaseCompressor> _compressor;
};
#define REGISTER_COMPRESSOR(NAME, CLASS) \
static osgDB::RegisterCompressorProxy<CLASS> compressor_proxy_##CLASS(NAME);
class GlobalLookupTable : public osg::Referenced
{
public:
typedef std::map<std::string, IntLookup> IntLookupMap;
static GlobalLookupTable* instance();
IntLookup::Value getValue( const std::string& group, const std::string& str )
{ return findLookup(group).getValue(str.c_str()); }
const std::string& getString( const std::string& group, IntLookup::Value value )
{ return findLookup(group).getString(value); }
protected:
GlobalLookupTable();
virtual ~GlobalLookupTable() {}
IntLookup& findLookup( const std::string& group )
{
IntLookupMap::iterator itr = _globalMap.find(group);
if ( itr!=_globalMap.end() ) return itr->second;
else return _globalMap["GL"];
}
IntLookupMap _globalMap;
};
}
#endif

381
include/osgDB/OutputStream Normal file
View File

@@ -0,0 +1,381 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#ifndef H_OUTPUTSTREAM
#define H_OUTPUTSTREAM
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Quat>
#include <osg/Matrix>
#include <osg/Array>
#include <osg/PrimitiveSet>
#include <osgDB/ReaderWriter>
#include <osgDB/DataTypes>
#include <iostream>
#include <sstream>
namespace osgDB
{
class OutputException
{
public:
OutputException( const std::string& field, const std::string& err )
: _field(field), _error(err) {}
const std::string& getField() const { return _field; }
const std::string& getError() const { return _error; }
protected:
std::string _field;
std::string _error;
};
class OutputStream
{
public:
typedef std::map<const osg::Array*, unsigned int> ArrayMap;
typedef std::map<const osg::Object*, unsigned int> ObjectMap;
enum WriteMode
{
WRITE_BINARY = 0,
WRITE_ASCII
};
enum WriteType
{
WRITE_UNKNOWN = 0,
WRITE_SCENE,
WRITE_IMAGE
};
enum WriteImageHint
{
WRITE_USE_IMAGE_HINT = 0, /*!< Use image hint, write inline data or use external */
WRITE_USE_EXTERNAL, /*!< Use external file on disk and write only the filename */
WRITE_INLINE_DATA, /*!< Write Image::data() to stream */
WRITE_INLINE_FILE, /*!< Write the image file itself to stream */
WRITE_EXTERNAL_FILE /*!< Write Image::data() to disk and use it as external file */
};
OutputStream( std::ostream* ostream, const osgDB::Options* options );
virtual ~OutputStream();
bool isBinary() const { return _writeMode==WRITE_BINARY; }
void setWriteImageHint( WriteImageHint hint ) { _writeImageHint = hint; }
WriteImageHint getWriteImageHint() const { return _writeImageHint; }
// Serialization related functions
inline OutputStream& operator<<( bool b );
inline OutputStream& operator<<( char c );
inline OutputStream& operator<<( unsigned char c );
inline OutputStream& operator<<( short s );
inline OutputStream& operator<<( unsigned short s );
inline OutputStream& operator<<( int i );
inline OutputStream& operator<<( unsigned int i );
inline OutputStream& operator<<( long l );
inline OutputStream& operator<<( unsigned long l );
inline OutputStream& operator<<( float f );
inline OutputStream& operator<<( double d );
inline OutputStream& operator<<( const std::string& s );
inline OutputStream& operator<<( std::ostream& (*fn)(std::ostream&) );
inline OutputStream& operator<<( std::ios_base& (*fn)(std::ios_base&) );
OutputStream& operator<<( const osg::Vec2b& v );
OutputStream& operator<<( const osg::Vec3b& v );
OutputStream& operator<<( const osg::Vec4b& v );
OutputStream& operator<<( const osg::Vec4ub& v );
OutputStream& operator<<( const osg::Vec2s& v );
OutputStream& operator<<( const osg::Vec3s& v );
OutputStream& operator<<( const osg::Vec4s& v );
OutputStream& operator<<( const osg::Vec2f& v );
OutputStream& operator<<( const osg::Vec3f& v );
OutputStream& operator<<( const osg::Vec4f& v );
OutputStream& operator<<( const osg::Vec2d& v );
OutputStream& operator<<( const osg::Vec3d& v );
OutputStream& operator<<( const osg::Vec4d& v );
OutputStream& operator<<( const osg::Quat& q );
OutputStream& operator<<( const osg::Plane& p );
OutputStream& operator<<( const osg::Matrixf& mat );
OutputStream& operator<<( const osg::Matrixd& mat );
OutputStream& operator<<( const osg::Array* a ) { writeArray(a); return *this; }
OutputStream& operator<<( const osg::Image* img ) { writeImage(img); return *this; }
OutputStream& operator<<( const osg::PrimitiveSet* p ) { writePrimitiveSet(p); return *this; }
OutputStream& operator<<( const osg::Object* obj ) { writeObject(obj); return *this; }
OutputStream& operator<<( const osg::ref_ptr<osg::Array>& ptr ) { writeArray(ptr.get()); return *this; }
OutputStream& operator<<( const osg::ref_ptr<osg::Image>& ptr ) { writeImage(ptr.get()); return *this; }
OutputStream& operator<<( const osg::ref_ptr<osg::PrimitiveSet>& ptr ) { writePrimitiveSet(ptr.get()); return *this; }
template<typename T> OutputStream& operator<<( const osg::ref_ptr<T>& ptr )
{ writeObject(ptr.get()); return *this; }
OutputStream& operator<<( const ObjectGLenum& value );
OutputStream& operator<<( const ObjectProperty& prop );
OutputStream& operator<<( const ObjectMark& mark );
// Convenient methods for writing
inline void writeWrappedString( const std::string& str );
inline void writeCharArray( const char* s, unsigned int size );
// Global writing functions
void writeArray( const osg::Array* a );
void writePrimitiveSet( const osg::PrimitiveSet* p );
void writeImage( const osg::Image* img );
void writeObject( const osg::Object* obj );
void start( WriteType type );
void compress( std::ostream* ostream );
// Schema handlers
void writeSchema( std::ostream& fout );
protected:
template<typename T>
void writeArrayImplementation( const T*, int writeSize, unsigned int numInRow=1 );
unsigned int findOrCreateArrayID( const osg::Array* array );
unsigned int findOrCreateObjectID( const osg::Object* obj );
ArrayMap _arrayMap;
ObjectMap _objectMap;
WriteMode _writeMode;
WriteImageHint _writeImageHint;
bool _readyForEndBracket;
int _indent;
std::string _currentField;
std::string _compressorName;
std::stringstream _compressSource;
std::ostream* _out;
};
// INLINE METHODS
OutputStream& OutputStream::operator<<( bool b )
{
if ( isBinary() )
{
char c = b?1:0;
_out->write( &c, CHAR_SIZE );
}
else
{
if ( b ) *_out << "TRUE ";
else *_out << "FALSE ";
}
return *this;
}
OutputStream& OutputStream::operator<<( char c )
{
if ( isBinary() )
{
_out->write( &c, CHAR_SIZE );
}
else
{
*_out << (short)c << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( unsigned char c )
{
if ( isBinary() )
{
_out->write( (char*)&c, CHAR_SIZE );
}
else
{
*_out << (unsigned short)c << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( short s )
{
if ( isBinary() )
{
_out->write( (char*)&s, SHORT_SIZE );
}
else
{
*_out << s << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( unsigned short s )
{
if ( isBinary() )
{
_out->write( (char*)&s, SHORT_SIZE );
}
else
{
*_out << s << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( int i )
{
if ( isBinary() )
{
_out->write( (char*)&i, INT_SIZE );
}
else
{
*_out << i << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( unsigned int i )
{
if ( isBinary() )
{
_out->write( (char*)&i, INT_SIZE );
}
else
{
*_out << i << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( long l )
{
if ( isBinary() )
{
_out->write( (char*)&l, LONG_SIZE );
}
else
{
*_out << l << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( unsigned long l )
{
if ( isBinary() )
{
_out->write( (char*)&l, LONG_SIZE );
}
else
{
*_out << l << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( float f )
{
if ( isBinary() )
{
_out->write( (char*)&f, FLOAT_SIZE );
}
else
{
*_out << f << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( double d )
{
if ( isBinary() )
{
_out->write((char*)&d, DOUBLE_SIZE);
}
else
{
*_out << d << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( const std::string& s )
{
if ( isBinary() )
{
int size = s.size();
_out->write( (char*)&size, INT_SIZE );
_out->write( s.c_str(), s.size() );
}
else
{
*_out << s << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( std::ostream& (*fn)(std::ostream&) )
{
if ( !isBinary() )
{
*_out << fn;
if ( fn==static_cast<std::ostream& (*)(std::ostream&)>(std::endl) )
{
_readyForEndBracket = true;
for (int i=0; i<_indent; ++i)
*_out << ' ';
}
}
return *this;
}
OutputStream& OutputStream::operator<<( std::ios_base& (*fn)(std::ios_base&) )
{
if ( !isBinary() ) *_out << fn;
return *this;
}
void OutputStream::writeWrappedString( const std::string& str )
{
if ( !isBinary() )
{
std::string wrappedStr = std::string("\"") + str + std::string("\"");
*this << wrappedStr;
}
else
*this << str;
}
void OutputStream::writeCharArray( const char* s, unsigned int size )
{
if ( size>0 )
{
if ( isBinary() )
{
_out->write( s, size );
}
else
{
*_out << s << ' ';
}
}
}
}
#endif

View File

@@ -621,52 +621,6 @@ inline void readCommandLine(osg::ArgumentParser& parser)
Registry::instance()->readCommandLine(parser);
}
/** Proxy class for automatic registration of DotOsgWrappers with the Registry.*/
class RegisterDotOsgWrapperProxy
{
public:
RegisterDotOsgWrapperProxy(osg::Object* proto,
const std::string& name,
const std::string& associates,
DotOsgWrapper::ReadFunc readFunc,
DotOsgWrapper::WriteFunc writeFunc,
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE)
{
if (Registry::instance())
{
_wrapper = new DotOsgWrapper(proto,name,associates,readFunc,writeFunc,readWriteMode);
Registry::instance()->addDotOsgWrapper(_wrapper.get());
}
}
~RegisterDotOsgWrapperProxy()
{
if (Registry::instance())
{
Registry::instance()->removeDotOsgWrapper(_wrapper.get());
}
}
protected:
osg::ref_ptr<DotOsgWrapper> _wrapper;
};
template<class T>
class TemplateRegisterDotOsgWrapperProxy : public RegisterDotOsgWrapperProxy, public T
{
public:
TemplateRegisterDotOsgWrapperProxy(osg::Object* proto,
const std::string& name,
const std::string& associates,
DotOsgWrapper::ReadFunc readFunc,
DotOsgWrapper::WriteFunc writeFunc,
DotOsgWrapper::ReadWriteMode readWriteMode=DotOsgWrapper::READ_AND_WRITE):
RegisterDotOsgWrapperProxy(proto, name, associates, readFunc, writeFunc, readWriteMode) {}
};
/** Proxy class for automatic registration of reader/writers with the Registry.*/
template<class T>
class RegisterReaderWriterProxy
@@ -705,19 +659,15 @@ struct PluginFunctionProxy
extern "C" void osgdb_##ext(void); \
static osgDB::PluginFunctionProxy proxy_##ext(osgdb_##ext);
#define USE_DOTOSGWRAPPER(classname) \
extern "C" void dotosgwrapper_##classname(void); \
static osgDB::PluginFunctionProxy proxy_dotosgwrapper_##classname(dotosgwrapper_##classname);
#define REGISTER_OSGPLUGIN(ext, classname) \
extern "C" void osgdb_##ext(void) {} \
static osgDB::RegisterReaderWriterProxy<classname> g_proxy_##classname;
#define USE_DOTOSGWRAPPER(classname) \
extern "C" void dotosgwrapper_##classname(void); \
static osgDB::PluginFunctionProxy proxy_dotosgwrapper_##classname(dotosgwrapper_##classname);
#define REGISTER_DOTOSGWRAPPER(classname) \
extern "C" void dotosgwrapper_##classname(void) {} \
static osgDB::RegisterDotOsgWrapperProxy dotosgwrapper_proxy_##classname
}
#endif

853
include/osgDB/Serializer Normal file
View File

@@ -0,0 +1,853 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#ifndef H_SERIALIZER
#define H_SERIALIZER
#include <osg/ref_ptr>
#include <osg/Notify>
#include <osg/Object>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
#include <string>
#include <sstream>
namespace osgDB
{
#ifndef OBJECT_CAST
#define OBJECT_CAST static_cast
#endif
class IntLookup
{
public:
typedef int Value;
typedef std::map<std::string, Value> StringToValue;
typedef std::map<Value, std::string> ValueToString;
IntLookup() {}
unsigned int size() const { return _stringToValue.size(); }
void add( const char* str, Value value )
{
if ( _valueToString.find(value)!=_valueToString.end() )
{
osg::notify(osg::WARN) << "Duplicate enum value " << value
<< " with old string: " << _valueToString[value]
<< " and new string: " << str << std::endl;
}
_valueToString[value] = str;
_stringToValue[str] = value;
}
Value getValue( const char* str )
{
StringToValue::iterator itr = _stringToValue.find(str);
if ( itr==_stringToValue.end() )
{
Value value;
std::stringstream stream;
stream << str; stream >> value;
_stringToValue[str] = value;
return value;
}
return itr->second;
}
const std::string& getString( Value value )
{
ValueToString::iterator itr = _valueToString.find(value);
if ( itr==_valueToString.end() )
{
std::string str;
std::stringstream stream;
stream << value; stream >> str;
_valueToString[value] = str;
return _valueToString[value];
}
return itr->second;
}
protected:
StringToValue _stringToValue;
ValueToString _valueToString;
};
class UserLookupTableProxy
{
public:
typedef void (*AddValueFunc)( IntLookup* lookup );
UserLookupTableProxy( AddValueFunc func ) { if ( func ) (*func)(&_lookup); }
IntLookup _lookup;
};
#define BEGIN_USER_TABLE(NAME, CLASS) \
static void add_user_value_func_##NAME(osgDB::IntLookup*); \
static osgDB::UserLookupTableProxy s_user_lookup_table_##NAME(&add_user_value_func_##NAME); \
static void add_user_value_func_##NAME(osgDB::IntLookup* lookup) { typedef CLASS MyClass
#define ADD_USER_VALUE(VALUE) lookup->add(#VALUE, MyClass::VALUE)
#define END_USER_TABLE() }
#define USER_READ_FUNC(NAME, FUNCNAME) \
static int FUNCNAME(osgDB::InputStream& is) { \
int value; if (is.isBinary()) is >> value; \
else { std::string str; is >> str; \
value = (s_user_lookup_table_##NAME)._lookup.getValue(str.c_str()); } \
return value; }
#define USER_WRITE_FUNC(NAME, FUNCNAME) \
static void FUNCNAME(osgDB::OutputStream& os, int value) { \
if (os.isBinary()) os << value; \
else os << (s_user_lookup_table_##NAME)._lookup.getString(value); } \
class BaseSerializer : public osg::Referenced
{
public:
BaseSerializer() {}
virtual bool read( InputStream&, osg::Object& ) = 0;
virtual bool write( OutputStream&, const osg::Object& ) = 0;
virtual const std::string& getName() const = 0;
};
template<typename C>
class UserSerializer : public BaseSerializer
{
public:
typedef bool (*Checker)( const C& );
typedef bool (*Reader)( InputStream&, C& );
typedef bool (*Writer)( OutputStream&, const C& );
UserSerializer( const char* name, Checker cf, Reader rf, Writer wf )
: _name(name), _checker(cf), _reader(rf), _writer(wf) {}
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
if ( !is.isBinary() && !is.matchString(_name) )
return true;
return (*_reader)(is, object);
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( !os.isBinary() )
{
if ( !(*_checker)(object) ) return true;
os << _name;
}
return (*_writer)(os, object);
}
virtual const std::string& getName() const { return _name; }
protected:
std::string _name;
Checker _checker;
Reader _reader;
Writer _writer;
};
template<typename P>
class TemplateSerializer : public BaseSerializer
{
public:
TemplateSerializer( const char* name )
: _name(name) {}
virtual bool read( InputStream& is, osg::Object& obj ) = 0;
virtual bool write( OutputStream& os, const osg::Object& obj ) = 0;
virtual const std::string& getName() const { return _name; }
protected:
std::string _name;
P _defaultValue;
};
template<typename C, typename P>
class PropByValSerializer : public TemplateSerializer<P>
{
public:
typedef TemplateSerializer<P> ParentType;
typedef P (C::*Getter)() const;
typedef void (C::*Setter)( P );
PropByValSerializer( const char* name, P def, Getter gf, Setter sf, bool useHex=false )
: ParentType(name), _getter(gf), _setter(sf), _useHex(useHex)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
P value;
if ( is.isBinary() )
{
is >> value;
if ( ParentType::_defaultValue!=value )
(object.*_setter)( value );
}
else if ( is.matchString(ParentType::_name) )
{
if ( _useHex ) is >> std::hex;
is >> value;
if ( _useHex ) is >> std::dec;
(object.*_setter)( value );
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( os.isBinary() )
{
os << (object.*_getter)();
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name;
if ( _useHex ) os << std::hex;
os << (object.*_getter)();
if ( _useHex ) os << std::dec;
os << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
bool _useHex;
};
template<typename C, typename P>
class PropByRefSerializer : public TemplateSerializer<P>
{
public:
typedef TemplateSerializer<P> ParentType;
typedef const P& CP;
typedef CP (C::*Getter)() const;
typedef void (C::*Setter)( CP );
PropByRefSerializer( const char* name, CP def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
P value;
if ( is.isBinary() )
{
is >> value;
if ( ParentType::_defaultValue!=value )
(object.*_setter)( value );
}
else if ( is.matchString(ParentType::_name) )
{
is >> value;
(object.*_setter)( value );
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( os.isBinary() )
{
os << (object.*_getter)();
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name << (object.*_getter)() << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
};
template<typename C>
class MatrixSerializer : public TemplateSerializer<osg::Matrix>
{
public:
typedef TemplateSerializer<osg::Matrix> ParentType;
typedef const osg::Matrix& (C::*Getter)() const;
typedef void (C::*Setter)( const osg::Matrix& );
MatrixSerializer( const char* name, const osg::Matrix& def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
osg::Matrix value;
if ( is.isBinary() )
{
readMatrixImplementation( is, value );
if ( ParentType::_defaultValue!=value )
(object.*_setter)( value );
}
else if ( is.matchString(ParentType::_name) )
{
readMatrixImplementation( is, value );
(object.*_setter)( value );
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( os.isBinary() )
{
os << (object.*_getter)();
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name << (object.*_getter)() << std::endl;
}
return true;
}
protected:
void readMatrixImplementation( InputStream& is, osg::Matrix& matrix )
{
if ( is.getUseFloatMatrix() )
{
osg::Matrixf realValue; is >> realValue;
matrix = realValue;
}
else
{
osg::Matrixd realValue; is >> realValue;
matrix = realValue;
}
}
Getter _getter;
Setter _setter;
};
template<typename C, typename P>
class GLenumSerializer : public TemplateSerializer<P>
{
public:
typedef TemplateSerializer<P> ParentType;
typedef P (C::*Getter)() const;
typedef void (C::*Setter)( P );
GLenumSerializer( const char* name, P def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
if ( is.isBinary() )
{
GLenum value; is >> value;
if ( ParentType::_defaultValue!=static_cast<P>(value) )
(object.*_setter)( static_cast<P>(value) );
}
else if ( is.matchString(ParentType::_name) )
{
DEF_GLENUM(value); is >> value;
(object.*_setter)( static_cast<P>(value.get()) );
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( os.isBinary() )
{
os << static_cast<GLenum>((object.*_getter)());
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name << GLENUM((object.*_getter)()) << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
};
template<typename C>
class StringSerializer : public TemplateSerializer<std::string>
{
public:
typedef TemplateSerializer<std::string> ParentType;
typedef const std::string& (C::*Getter)() const;
typedef void (C::*Setter)( const std::string& );
StringSerializer( const char* name, const std::string& def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
std::string value;
if ( is.isBinary() )
{
is >> value;
if ( ParentType::_defaultValue!=value )
(object.*_setter)( value );
}
else if ( is.matchString(ParentType::_name) )
{
is.readWrappedString( value );
if ( !value.empty() )
(object.*_setter)( value );
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( os.isBinary() )
{
os << (object.*_getter)();
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name;
os.writeWrappedString( (object.*_getter)() );
os << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
};
template<typename C, typename P>
class ObjectSerializer : public TemplateSerializer<P*>
{
public:
typedef TemplateSerializer<P*> ParentType;
typedef const P* (C::*Getter)() const;
typedef void (C::*Setter)( P* );
ObjectSerializer( const char* name, P* def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
bool hasObject = false;
if ( is.isBinary() )
{
is >> hasObject;
if ( hasObject )
{
P* value = dynamic_cast<P*>( is.readObject() );
if ( ParentType::_defaultValue!=value )
(object.*_setter)( value );
}
}
else if ( is.matchString(ParentType::_name) )
{
is >> hasObject;
if ( hasObject )
{
is >> BEGIN_BRACKET;
P* value = dynamic_cast<P*>( is.readObject() );
(object.*_setter)( value );
is >> END_BRACKET;
}
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
bool hasObject = ((object.*_getter)()!=NULL);
if ( os.isBinary() )
{
os << hasObject;
os.writeObject( (object.*_getter)() );
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name << hasObject;
if ( hasObject )
{
os << BEGIN_BRACKET << std::endl;
os.writeObject( (object.*_getter)() );
os << END_BRACKET;
}
os << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
};
template<typename C, typename P>
class ImageSerializer : public TemplateSerializer<P*>
{
public:
typedef TemplateSerializer<P*> ParentType;
typedef const P* (C::*Getter)() const;
typedef void (C::*Setter)( P* );
ImageSerializer( const char* name, P* def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
bool hasObject = false;
if ( is.isBinary() )
{
is >> hasObject;
if ( hasObject )
{
P* value = dynamic_cast<P*>( is.readImage() );
if ( ParentType::_defaultValue!=value )
(object.*_setter)( value );
}
}
else if ( is.matchString(ParentType::_name) )
{
is >> hasObject;
if ( hasObject )
{
is >> BEGIN_BRACKET;
P* value = dynamic_cast<P*>( is.readImage() );
(object.*_setter)( value );
is >> END_BRACKET;
}
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
bool hasObject = ((object.*_getter)()!=NULL);
if ( os.isBinary() )
{
os << hasObject;
os.writeImage( (object.*_getter)() );
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name << hasObject;
if ( hasObject )
{
os << BEGIN_BRACKET << std::endl;
os.writeImage( (object.*_getter)() );
os << END_BRACKET;
}
os << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
};
template<typename C, typename P, typename B>
class EnumSerializer : public TemplateSerializer<P>
{
public:
typedef TemplateSerializer<P> ParentType;
typedef P (C::*Getter)() const;
typedef B (C::*Setter)( P );
EnumSerializer( const char* name, P def, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf)
{ ParentType::_defaultValue = def; }
void add( const char* str, P value )
{ _lookup.add(str, static_cast<osgDB::IntLookup::Value>(value)); }
P getValue( const char* str )
{ return static_cast<P>(_lookup.getValue(str)); }
const std::string& getString( P value )
{ return _lookup.getString(static_cast<osgDB::IntLookup::Value>(value)); }
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
IntLookup::Value value;
if ( is.isBinary() )
{
is >> value;
if ( ParentType::_defaultValue!=static_cast<P>(value) )
(object.*_setter)( static_cast<P>(value) );
}
else if ( is.matchString(ParentType::_name) )
{
std::string str; is >> str;
(object.*_setter)( getValue(str.c_str()) );
}
return true;
}
virtual bool write( osgDB::OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
if ( os.isBinary() )
{
os << (osgDB::IntLookup::Value)(object.*_getter)();
}
else if ( ParentType::_defaultValue!=(object.*_getter)() )
{
os << ParentType::_name << getString((object.*_getter)()) << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
IntLookup _lookup;
};
template<typename C, typename P>
class ListSerializer : public TemplateSerializer<P>
{
public:
typedef TemplateSerializer<P> ParentType;
typedef typename P::value_type ValueType;
typedef typename P::const_iterator ConstIterator;
typedef const P& (C::*Getter)() const;
typedef void (C::*Setter)( const P& );
ListSerializer( const char* name, Getter gf, Setter sf )
: ParentType(name), _getter(gf), _setter(sf) {}
virtual bool read( InputStream& is, osg::Object& obj )
{
C& object = OBJECT_CAST<C&>(obj);
unsigned int size = 0;
P list;
if ( is.isBinary() )
{
is >> size;
for ( unsigned int i=0; i<size; ++i )
{
ValueType value;
is >> value;
list.push_back( value );
}
if ( size>0 ) (object.*_setter)( list );
}
else if ( is.matchString(ParentType::_name) )
{
is >> size;
if ( size>0 ) is >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
ValueType value;
is >> value;
list.push_back( value );
}
if ( size>0 )
{
is >> END_BRACKET;
(object.*_setter)( list );
}
}
return true;
}
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
const P& list = (object.*_getter)();
unsigned int size = (unsigned int)list.size();
if ( os.isBinary() )
{
os << size;
for ( ConstIterator itr=list.begin();
itr!=list.end(); ++itr )
{
os << (*itr);
}
}
else if ( size>0 )
{
os << ParentType::_name << size << BEGIN_BRACKET << std::endl;
for ( ConstIterator itr=list.begin();
itr!=list.end(); ++itr )
{
os << (*itr);
}
os << END_BRACKET << std::endl;
}
return true;
}
protected:
Getter _getter;
Setter _setter;
};
// ADDING MANIPULATORS
#define ADD_SERIALIZER(S) \
wrapper->addSerializer(S)
#define ADD_USER_SERIALIZER(PROP) \
wrapper->addSerializer( new osgDB::UserSerializer<MyClass>( \
#PROP, &check##PROP, &read##PROP, &write##PROP) )
#define ADD_BOOL_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, bool>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_SHORT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, short>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_USHORT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned short>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_HEXSHORT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned short>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true) )
#define ADD_INT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, int>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_UINT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned int>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_HEXINT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, unsigned int>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP, true) )
#define ADD_FLOAT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, float>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_DOUBLE_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer<MyClass, double>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_VEC3F_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec3f>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_VEC3D_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec3d>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_VEC3_SERIALIZER(PROP, DEF) ADD_VEC3F_SERIALIZER(PROP, DEF)
#define ADD_VEC4F_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec4f>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_VEC4D_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Vec4d>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_VEC4_SERIALIZER(PROP, DEF) ADD_VEC4F_SERIALIZER(PROP, DEF)
#define ADD_QUAT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Quat>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_PLANE_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Plane>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_MATRIXF_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Matrixf>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_MATRIXD_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByRefSerializer<MyClass, osg::Matrixd>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_MATRIX_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::MatrixSerializer<MyClass>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_GLENUM_SERIALIZER(PROP, TYPE, DEF) \
wrapper->addSerializer( new osgDB::GLenumSerializer<MyClass, TYPE>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_STRING_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::StringSerializer<MyClass>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_OBJECT_SERIALIZER(PROP, TYPE, DEF) \
wrapper->addSerializer( new osgDB::ObjectSerializer<MyClass, TYPE>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_IMAGE_SERIALIZER(PROP, TYPE, DEF) \
wrapper->addSerializer( new osgDB::ImageSerializer<MyClass, TYPE>( \
#PROP, DEF, &MyClass::get##PROP, &MyClass::set##PROP) )
#define ADD_LIST_SERIALIZER(PROP, TYPE) \
wrapper->addSerializer( new osgDB::ListSerializer<MyClass, TYPE>( \
#PROP, &MyClass::get##PROP, &MyClass::set##PROP) )
#define BEGIN_ENUM_SERIALIZER(PROP, DEF) \
{ typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, void> MySerializer; \
osg::ref_ptr<MySerializer> serializer = new MySerializer( \
#PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
#define BEGIN_ENUM_SERIALIZER2(PROP, TYPE, DEF) \
{ typedef osgDB::EnumSerializer<MyClass, TYPE, void> MySerializer; \
osg::ref_ptr<MySerializer> serializer = new MySerializer( \
#PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
#define BEGIN_ENUM_SERIALIZER3(PROP, DEF) \
{ typedef osgDB::EnumSerializer<MyClass, MyClass::PROP, bool> MySerializer; \
osg::ref_ptr<MySerializer> serializer = new MySerializer( \
#PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP)
#define ADD_ENUM_VALUE(VALUE) \
serializer->add(#VALUE, MyClass::VALUE)
#define END_ENUM_SERIALIZER() \
wrapper->addSerializer(serializer); }
}
#endif

View File

@@ -17,6 +17,7 @@ FOREACH( mylibfolder
osgTerrain
osgWidget
osgVolume
osgWrappers/serializers
osgWrappers/deprecated-dotosg
osgPlugins
)

View File

@@ -19,6 +19,11 @@ ENDIF()
SET(LIB_NAME osgDB)
SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME})
SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/DataTypes
${HEADER_PATH}/Serializer
${HEADER_PATH}/ObjectWrapper
${HEADER_PATH}/InputStream
${HEADER_PATH}/OutputStream
${HEADER_PATH}/Archive
${HEADER_PATH}/AuthenticationMap
${HEADER_PATH}/Callbacks
@@ -55,6 +60,10 @@ SET(LIB_PUBLIC_HEADERS
ADD_LIBRARY(${LIB_NAME}
${OPENSCENEGRAPH_USER_DEFINED_DYNAMIC_OR_STATIC}
${LIB_PUBLIC_HEADERS}
ObjectWrapper.cpp
InputStream.cpp
OutputStream.cpp
Compressors.cpp
Archive.cpp
AuthenticationMap.cpp
Callbacks.cpp
@@ -116,6 +125,11 @@ IF(OPENVRML_FOUND)
ADD_DEFINITIONS(-DUSE_VRML)
ENDIF()
IF( ZLIB_FOUND )
ADD_DEFINITIONS( -DUSE_ZLIB )
INCLUDE_DIRECTORIES( ${ZLIB_INCLUDE_DIR} )
SET(COMPRESSION_LIBRARIES ${ZLIB_LIBRARY})
ENDIF()
ADD_DEFINITIONS(-DOSG_PLUGIN_EXTENSION=${CMAKE_SHARED_MODULE_SUFFIX})
@@ -123,7 +137,11 @@ LINK_INTERNAL(${LIB_NAME}
osg
OpenThreads
)
LINK_EXTERNAL(${LIB_NAME} ${OSGDB_PLATFORM_SPECIFIC_LIBRARIES} )
LINK_EXTERNAL(${LIB_NAME} ${OSGDB_PLATFORM_SPECIFIC_LIBRARIES} ${COMPRESSION_LIBRARIES})
LINK_CORELIB_DEFAULT(${LIB_NAME})
IF( ZLIB_FOUND )
SET( TARGET_LIBRARIES_VARS ZLIB_LIBRARY )
ENDIF( ZLIB_FOUND )
INCLUDE(ModuleInstall OPTIONAL)

176
src/osgDB/Compressors.cpp Normal file
View File

@@ -0,0 +1,176 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#include <osg/Notify>
#include <osgDB/Registry>
#include <osgDB/Registry>
#include <osgDB/ObjectWrapper>
#include <sstream>
using namespace osgDB;
// Example compressor copying data to/from stream directly
class NullCompressor : public BaseCompressor
{
public:
NullCompressor() {}
virtual bool compress( std::ostream& fout, const std::string& src )
{
int size = src.size();
fout.write( (char*)&size, INT_SIZE );
fout.write( src.c_str(), src.size() );
return true;
}
virtual bool decompress( std::istream& fin, std::string& target )
{
int size = 0; fin.read( (char*)&size, INT_SIZE );
if ( size )
{
target.resize( size );
fin.read( (char*)target.c_str(), size );
}
return true;
}
};
REGISTER_COMPRESSOR( "null", NullCompressor )
#ifdef USE_ZLIB
#include <zlib.h>
#define CHUNK 32768
// ZLib compressor
class ZLibCompressor : public BaseCompressor
{
public:
ZLibCompressor() {}
virtual bool compress( std::ostream& fout, const std::string& src )
{
int ret, flush = Z_FINISH;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int level = 6;
int stategy = Z_DEFAULT_STRATEGY;
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit2( &strm, level, Z_DEFLATED,
15+16, // +16 to use gzip encoding
8, // default
stategy );
if ( ret != Z_OK ) return false;
strm.avail_in = src.size();
strm.next_in = (Bytef*)( &(*src.begin()) );
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
if ( ret == Z_STREAM_ERROR )
{
osg::notify(osg::NOTICE) << "Z_STREAM_ERROR" << std::endl;
return false;
}
have = CHUNK - strm.avail_out;
if ( have>0 ) fout.write( (const char*)out, have );
if ( fout.fail() )
{
(void)deflateEnd( &strm );
return false;
}
} while ( strm.avail_out==0 );
/* clean up and return */
(void)deflateEnd( &strm );
return true;
}
virtual bool decompress( std::istream& fin, std::string& target )
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2( &strm,
15 + 32 ); // autodected zlib or gzip header
if ( ret!=Z_OK )
{
osg::notify(osg::INFO) << "failed to init" << std::endl;
return ret!=0;
}
/* decompress until deflate stream ends or end of file */
do
{
fin.read( (char *)in, CHUNK );
strm.avail_in = fin.gcount();
if (strm.avail_in==0 ) break;
/* run inflate() on input until output buffer not full */
strm.next_in = in;
do
{
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate( &strm, Z_NO_FLUSH );
switch (ret)
{
case Z_NEED_DICT:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd( &strm );
return false;
}
have = CHUNK - strm.avail_out;
target.append( (char*)out, have );
} while ( strm.avail_out==0 );
/* done when inflate() says it's done */
} while ( ret!=Z_STREAM_END );
/* clean up and return */
(void)inflateEnd( &strm );
return ret==Z_STREAM_END ? true : false;
}
};
REGISTER_COMPRESSOR( "zlib", ZLibCompressor )
#endif

View File

@@ -11,6 +11,7 @@
* OpenSceneGraph Public License for more details.
*/
#include <osgDB/DotOsgWrapper>
#include <osgDB/Registry>
using namespace osgDB;
@@ -50,3 +51,26 @@ DotOsgWrapper::DotOsgWrapper(osg::Object* proto,
_readWriteMode = readWriteMode;
}
RegisterDotOsgWrapperProxy::RegisterDotOsgWrapperProxy(osg::Object* proto,
const std::string& name,
const std::string& associates,
DotOsgWrapper::ReadFunc readFunc,
DotOsgWrapper::WriteFunc writeFunc,
DotOsgWrapper::ReadWriteMode readWriteMode)
{
if (Registry::instance())
{
_wrapper = new DotOsgWrapper(proto,name,associates,readFunc,writeFunc,readWriteMode);
Registry::instance()->addDotOsgWrapper(_wrapper.get());
}
}
RegisterDotOsgWrapperProxy::~RegisterDotOsgWrapperProxy()
{
if (Registry::instance())
{
Registry::instance()->removeDotOsgWrapper(_wrapper.get());
}
}

764
src/osgDB/InputStream.cpp Normal file
View File

@@ -0,0 +1,764 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#include <osg/Notify>
#include <osg/ImageSequence>
#include <osgDB/ReadFile>
#include <osgDB/XmlParser>
#include <osgDB/FileNameUtils>
#include <osgDB/ObjectWrapper>
using namespace osgDB;
static std::string s_lastSchema;
InputStream::InputStream( std::istream* istream, const osgDB::Options* options )
: _readMode(READ_BINARY), _byteSwap(0), _useFloatMatrix(false),
_in(istream)
{
if ( !_in )
throw InputException(_currentField, "InputStream: Null stream specified.");
if ( !options ) return;
std::string schema;
StringList optionList;
split( options->getOptionString(), optionList );
for ( StringList::iterator itr=optionList.begin(); itr!=optionList.end(); ++itr )
{
const std::string& option = *itr;
if ( option=="Ascii" )
_readMode = READ_ASCII;
else
{
StringList keyAndValues;
split( option, keyAndValues, '=' );
if ( keyAndValues.size()<2 ) continue;
if ( keyAndValues[0]=="SchemaFile" )
{
schema = keyAndValues[1];
if ( s_lastSchema!=schema )
{
osgDB::ifstream schemaStream( schema.c_str(), std::ios::in );
if ( !schemaStream.fail() ) readSchema( schemaStream );
schemaStream.close();
s_lastSchema = schema;
}
}
else
osg::notify(osg::WARN) << "InputStream: Unknown option " << option << std::endl;
}
}
if ( schema.empty() )
{
resetSchema();
s_lastSchema.clear();
}
}
InputStream::~InputStream()
{
}
InputStream& InputStream::operator>>( osg::Vec2b& v )
{
char x, y; *this >> x >> y;
v.set( x, y );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec3b& v )
{
char x, y, z; *this >> x >> y >> z;
v.set( x, y, z );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec4b& v )
{
char x, y, z, w; *this >> x >> y >> z >> w;
v.set( x, y, z, w );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec4ub& v )
{
char r, g, b, a; *this >> r >> g >> b >> a;
v.set( r, g, b, a );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec2s& v )
{ *this >> v.x() >> v.y(); return *this; }
InputStream& InputStream::operator>>( osg::Vec3s& v )
{ *this >> v.x() >> v.y() >> v.z(); return *this; }
InputStream& InputStream::operator>>( osg::Vec4s& v )
{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
InputStream& InputStream::operator>>( osg::Vec2f& v )
{ *this >> v.x() >> v.y(); return *this; }
InputStream& InputStream::operator>>( osg::Vec3f& v )
{ *this >> v.x() >> v.y() >> v.z(); return *this; }
InputStream& InputStream::operator>>( osg::Vec4f& v )
{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
InputStream& InputStream::operator>>( osg::Vec2d& v )
{ *this >> v.x() >> v.y(); return *this; }
InputStream& InputStream::operator>>( osg::Vec3d& v )
{ *this >> v.x() >> v.y() >> v.z(); return *this; }
InputStream& InputStream::operator>>( osg::Vec4d& v )
{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
InputStream& InputStream::operator>>( osg::Quat& q )
{ *this >> q.x() >> q.y() >> q.z() >> q.w(); return *this; }
InputStream& InputStream::operator>>( osg::Plane& p )
{
double p0, p1, p2, p3; *this >> p0 >> p1 >> p2 >> p3;
p.set( p0, p1, p2, p3 ); return *this;
}
InputStream& InputStream::operator>>( osg::Matrixf& mat )
{
*this >> PROPERTY("Matrixf") >> BEGIN_BRACKET;
for ( int r=0; r<4; ++r )
{
*this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
}
*this >> END_BRACKET;
return *this;
}
InputStream& InputStream::operator>>( osg::Matrixd& mat )
{
*this >> PROPERTY("Matrixd") >> BEGIN_BRACKET;
for ( int r=0; r<4; ++r )
{
*this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
}
*this >> END_BRACKET;
return *this;
}
InputStream& InputStream::operator>>( ObjectGLenum& value )
{
GLenum e = 0;
if ( isBinary() )
{
_in->read( (char*)&e, GLENUM_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&e, GLENUM_SIZE );
}
else
{
std::string enumString;
*this >> enumString;
e = GlobalLookupTable::instance()->getValue("GL", enumString);
}
value.set( e );
return *this;
}
InputStream& InputStream::operator>>( ObjectProperty& prop )
{
int value = 0;
if ( isBinary() )
{
if ( prop._mapProperty )
{
_in->read( (char*)&value, INT_SIZE ); checkStream();
if ( _byteSwap ) osg::swapBytes( (char*)&value, INT_SIZE );
}
}
else
{
std::string enumString;
*this >> enumString;
if ( prop._mapProperty )
{
value =
GlobalLookupTable::instance()->getValue(prop._name, enumString);
}
else
{
if ( prop._name!=enumString )
{
osg::notify(osg::WARN) << "InputStream::operator>>(ObjectProperty&): Unmatched property "
<< enumString << ", expecting " << prop._name
<< ". At " << _currentField << std::endl;
}
prop._name = enumString;
}
}
prop.set( value );
return *this;
}
InputStream& InputStream::operator>>( ObjectMark& mark )
{
if ( !isBinary() )
{
std::string markString;
*this >> markString;
}
return *this;
}
osg::Array* InputStream::readArray()
{
osg::ref_ptr<osg::Array> array = NULL;
unsigned int id = 0;
*this >> PROPERTY("ArrayID") >> id;
ArrayMap::iterator itr = _arrayMap.find( id );
if ( itr!=_arrayMap.end() ) return itr->second.get();
DEF_MAPPEE(ArrayType, type);
*this >> type;
switch ( type.get() )
{
case ID_BYTE_ARRAY:
{
osg::ByteArray* ba = new osg::ByteArray;
readArrayImplementation( ba, CHAR_SIZE, true );
array = ba;
}
break;
case ID_UBYTE_ARRAY:
{
osg::UByteArray* uba = new osg::UByteArray;
readArrayImplementation( uba, CHAR_SIZE, true );
array = uba;
}
break;
case ID_SHORT_ARRAY:
{
osg::ShortArray* sa = new osg::ShortArray;
readArrayImplementation( sa, SHORT_SIZE, true );
array = sa;
}
break;
case ID_USHORT_ARRAY:
{
osg::UShortArray* usa = new osg::UShortArray;
readArrayImplementation( usa, SHORT_SIZE, true );
array = usa;
}
break;
case ID_INT_ARRAY:
{
osg::IntArray* ia = new osg::IntArray;
readArrayImplementation( ia, INT_SIZE, true );
array = ia;
}
break;
case ID_UINT_ARRAY:
{
osg::UIntArray* uia = new osg::UIntArray;
readArrayImplementation( uia, INT_SIZE, true );
array = uia;
}
break;
case ID_FLOAT_ARRAY:
{
osg::FloatArray* fa = new osg::FloatArray;
readArrayImplementation( fa, FLOAT_SIZE, true );
array = fa;
}
break;
case ID_DOUBLE_ARRAY:
{
osg::DoubleArray* da = new osg::DoubleArray;
readArrayImplementation( da, DOUBLE_SIZE, true );
array = da;
}
break;
case ID_VEC2B_ARRAY:
{
osg::Vec2bArray* va = new osg::Vec2bArray;
readArrayImplementation( va, 2*CHAR_SIZE );
array = va;
}
break;
case ID_VEC3B_ARRAY:
{
osg::Vec3bArray* va = new osg::Vec3bArray;
readArrayImplementation( va, 3*CHAR_SIZE );
array = va;
}
break;
case ID_VEC4B_ARRAY:
{
osg::Vec4bArray* va = new osg::Vec4bArray;
readArrayImplementation( va, 4*CHAR_SIZE );
array = va;
}
break;
case ID_VEC4UB_ARRAY:
{
osg::Vec4ubArray* va = new osg::Vec4ubArray;
readArrayImplementation( va, 4*CHAR_SIZE );
array = va;
}
break;
case ID_VEC2S_ARRAY:
{
osg::Vec2sArray* va = new osg::Vec2sArray;
readArrayImplementation( va, 2*SHORT_SIZE );
array = va;
}
break;
case ID_VEC3S_ARRAY:
{
osg::Vec3sArray* va = new osg::Vec3sArray;
readArrayImplementation( va, 3*SHORT_SIZE );
array = va;
}
break;
case ID_VEC4S_ARRAY:
{
osg::Vec4sArray* va = new osg::Vec4sArray;
readArrayImplementation( va, 4*SHORT_SIZE );
array = va;
}
break;
case ID_VEC2_ARRAY:
{
osg::Vec2Array* va = new osg::Vec2Array;
readArrayImplementation( va, 2*FLOAT_SIZE );
array = va;
}
break;
case ID_VEC3_ARRAY:
{
osg::Vec3Array* va = new osg::Vec3Array;
readArrayImplementation( va, 3*FLOAT_SIZE );
array = va;
}
break;
case ID_VEC4_ARRAY:
{
osg::Vec4Array* va = new osg::Vec4Array;
readArrayImplementation( va, 4*FLOAT_SIZE );
array = va;
}
break;
case ID_VEC2D_ARRAY:
{
osg::Vec2dArray* va = new osg::Vec2dArray;
readArrayImplementation( va, 2*DOUBLE_SIZE );
array = va;
}
break;
case ID_VEC3D_ARRAY:
{
osg::Vec3dArray* va = new osg::Vec3dArray;
readArrayImplementation( va, 3*DOUBLE_SIZE );
array = va;
}
break;
case ID_VEC4D_ARRAY:
{
osg::Vec4dArray* va = new osg::Vec4dArray;
readArrayImplementation( va, 4*DOUBLE_SIZE );
array = va;
}
break;
default:
throw InputException(_currentField, "InputStream::readArray(): Unsupported array type.");
}
_arrayMap[id] = array;
return array.release();
}
osg::PrimitiveSet* InputStream::readPrimitiveSet()
{
osg::ref_ptr<osg::PrimitiveSet> primitive = NULL;
DEF_MAPPEE(PrimitiveType, type);
DEF_MAPPEE(PrimitiveType, mode);
*this >> type >> mode;
switch ( type.get() )
{
case ID_DRAWARRAYS:
{
int first = 0, count = 0;
*this >> first >> count;
osg::DrawArrays* da = new osg::DrawArrays( mode.get(), first, count );
primitive = da;
}
break;
case ID_DRAWARRAY_LENGTH:
{
int first = 0, value = 0; unsigned int size = 0;
*this >> first >> size >> BEGIN_BRACKET;
osg::DrawArrayLengths* dl = new osg::DrawArrayLengths( mode.get(), first );
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
dl->push_back( value );
}
*this >> END_BRACKET;
primitive = dl;
}
break;
case ID_DRAWELEMENTS_UBYTE:
{
osg::DrawElementsUByte* de = new osg::DrawElementsUByte( mode.get() );
unsigned int size = 0; unsigned char value = 0;
*this >> size >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
de->push_back( value );
}
*this >> END_BRACKET;
primitive = de;
}
break;
case ID_DRAWELEMENTS_USHORT:
{
osg::DrawElementsUShort* de = new osg::DrawElementsUShort( mode.get() );
unsigned int size = 0; unsigned short value = 0;
*this >> size >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
de->push_back( value );
}
*this >> END_BRACKET;
primitive = de;
}
break;
case ID_DRAWELEMENTS_UINT:
{
osg::DrawElementsUInt* de = new osg::DrawElementsUInt( mode.get() );
unsigned int size = 0, value = 0;
*this >> size >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
de->push_back( value );
}
*this >> END_BRACKET;
primitive = de;
}
break;
default:
throw InputException(_currentField, "InputStream::readPrimitiveSet(): Unsupported array type.");
}
return primitive.release();
}
osg::Image* InputStream::readImage()
{
std::string name;
int writeHint, decision = IMAGE_EXTERNAL;
*this >> PROPERTY("FileName"); readWrappedString(name);
*this >> PROPERTY("WriteHint") >> writeHint >> decision;
osg::ref_ptr<osg::Image> image = NULL;
bool readFromExternal = true;
switch ( decision )
{
case IMAGE_INLINE_DATA:
if ( isBinary() )
{
image = new osg::Image;
// _origin, _s & _t & _r, _internalTextureFormat
int origin, s, t, r, internalFormat;
*this >> origin >> s >> t >> r >> internalFormat;
// _pixelFormat, _dataType, _packing, _allocationMode
int pixelFormat, dataType, packing, mode;
*this >> pixelFormat >> dataType >> packing >> mode;
// _data
unsigned int size = 0; *this >> size;
if ( size )
{
char* data = new char[size];
if ( !data )
throw InputException(_currentField, "InputStream::readImage() Out of memory.");
readCharArray( data, size );
image->setOrigin( (osg::Image::Origin)origin );
image->setImage( s, t, r, internalFormat, pixelFormat, dataType,
(unsigned char*)data, (osg::Image::AllocationMode)mode, packing );
}
// _mipmapData
unsigned int levelSize = 0; *this >> levelSize;
osg::Image::MipmapDataType levels(levelSize);
for ( unsigned int i=0; i<levelSize; ++i )
{
*this >> levels[i];
}
if ( levelSize>0 )
image->setMipmapLevels( levels );
readFromExternal = false;
}
break;
case IMAGE_INLINE_FILE:
if ( isBinary() )
{
unsigned int size = 0; *this >> size;
if ( size>0 )
{
char* data = new char[size];
if ( !data )
throw InputException(_currentField, "InputStream::readImage(): Out of memory.");
readCharArray( data, size );
std::string ext = osgDB::getFileExtension( name );
osgDB::ReaderWriter* reader =
osgDB::Registry::instance()->getReaderWriterForExtension( ext );
if ( reader )
{
std::stringstream inputStream;
inputStream.write( data, size );
osgDB::ReaderWriter::ReadResult rr = reader->readImage( inputStream );
if ( rr.validImage() )
image = rr.takeImage();
else
{
osg::notify(osg::WARN) << "InputStream::readImage(): "
<< rr.message() << std::endl;
}
}
else
{
osg::notify(osg::WARN) << "InputStream::readImage(): Unable to find a plugin for "
<< ext << std::endl;
}
delete[] data;
}
readFromExternal = false;
}
break;
case IMAGE_EXTERNAL: case IMAGE_WRITE_OUT:
break;
default:
break;
}
if ( readFromExternal )
image = osgDB::readImageFile( name );
if ( image.valid() )
{
image->setFileName( name );
image->setWriteHint( (osg::Image::WriteHint)writeHint );
}
image = static_cast<osg::Image*>( readObject(image.get()) );
return image.release();
}
osg::Object* InputStream::readObject( osg::Object* existingObj )
{
std::string className;
unsigned int id = 0;
*this >> className >> BEGIN_BRACKET >> PROPERTY("UniqueID") >> id;
IdentifierMap::iterator itr = _identifierMap.find( id );
if ( itr!=_identifierMap.end() )
{
advanceToCurrentEndBracket();
return itr->second.get();
}
ObjectWrapper* wrapper = ObjectRegistry::instance()->findWrapper( className );
if ( !wrapper )
{
osg::notify(osg::WARN) << "InputStream::readObject(): Unsupported wrapper class "
<< className << std::endl;
advanceToCurrentEndBracket();
return NULL;
}
osg::ref_ptr<osg::Object> obj = existingObj ? existingObj : wrapper->getProto()->cloneType();
if ( obj.valid() )
{
_identifierMap[id] = obj;
const StringList& associates = wrapper->getAssociates();
for ( StringList::const_iterator itr=associates.begin(); itr!=associates.end(); ++itr )
{
ObjectWrapper* assocWrapper = ObjectRegistry::instance()->findWrapper(*itr);
if ( !assocWrapper )
{
osg::notify(osg::WARN) << "InputStream::readObject(): Unsupported associated class "
<< *itr << std::endl;
continue;
}
_currentField = assocWrapper->getName();
assocWrapper->read( *this, *obj );
}
}
advanceToCurrentEndBracket();
return obj.release();
}
void InputStream::readSchema( std::istream& fin )
{
// Read from external ascii stream
std::string line;
while ( std::getline(fin, line) )
{
if ( line[0]=='#' ) continue; // Comment
StringList keyAndValue;
split( line, keyAndValue, '=' );
if ( keyAndValue.size()<2 ) continue;
setWrapperSchema( osgDB::trimEnclosingSpaces(keyAndValue[0]),
osgDB::trimEnclosingSpaces(keyAndValue[1]) );
}
}
InputStream::ReadType InputStream::start()
{
ReadType type = READ_UNKNOWN;
_currentField = "Header";
// Check OSG header information
unsigned int version = 0;
if ( isBinary() )
{
unsigned int headerLow = 0, headerHigh = 0;
*this >> headerLow >> headerHigh;
if ( headerLow!=OSG_HEADER_LOW || headerHigh!=OSG_HEADER_HIGH )
{
_in->seekg( 0, std::ios::beg );
_readMode = READ_ASCII;
}
else
{
unsigned int typeValue;
*this >> typeValue >> version;
type = static_cast<ReadType>(typeValue);
unsigned int matrixValueType; *this >> matrixValueType;
if ( matrixValueType==0 ) _useFloatMatrix = true;
else _useFloatMatrix = false;
}
}
if ( !isBinary() )
{
DEF_PROPERTY("#Ascii", header); *this >> header;
if ( header._name!="#Ascii" ) return READ_UNKNOWN;
std::string typeString; *this >> typeString;
if ( typeString=="Scene" ) type = READ_SCENE;
else if ( typeString=="Image" ) type = READ_IMAGE;
std::string osgName, osgVersion;
*this >> PROPERTY("#Version") >> version;
*this >> PROPERTY("#Generator") >> osgName >> osgVersion;
}
// Check file version
if ( version!=PLUGIN_VERSION )
{
osg::notify(osg::WARN) << "InputStream: Input data version " << version
<< " may be incompatible with current reader version "
<< PLUGIN_VERSION << std::endl;
}
return type;
}
void InputStream::decompress()
{
_currentField = "Decompression";
if ( !isBinary() ) return;
std::string compressorName; *this >> compressorName;
if ( compressorName=="0" ) return;
BaseCompressor* compressor =
ObjectRegistry::instance()->findCompressor(compressorName);
if ( !compressor )
{
osg::notify(osg::WARN) << "InputStream::decompress(): No such compressor "
<< compressorName << std::endl;
}
std::string data;
if ( !compressor->decompress(*_in, data) )
throw InputException(_currentField, "InputStream: Failed to decompress stream.");
_in = new std::stringstream(data);
}
// PROTECTED METHODS
void InputStream::setWrapperSchema( const std::string& name, const std::string& properties )
{
ObjectWrapper* wrapper = ObjectRegistry::instance()->findWrapper(name);
if ( !wrapper )
{
osg::notify(osg::WARN) << "InputStream::setSchema(): Unsupported wrapper class "
<< name << std::endl;
return;
}
StringList schema;
split( properties, schema );
wrapper->readSchema( schema );
}
void InputStream::resetSchema()
{
const ObjectRegistry::WrapperMap& wrappers = ObjectRegistry::instance()->getWrapperMap();
for ( ObjectRegistry::WrapperMap::const_iterator itr=wrappers.begin();
itr!=wrappers.end(); ++itr )
{
ObjectWrapper* wrapper = itr->second.get();
wrapper->resetSchema();
}
}
template<typename T>
void InputStream::readArrayImplementation( T* a, int readSize, bool useByteSwap )
{
int size = 0;
*this >> size >> BEGIN_BRACKET;
if ( size )
{
a->resize( size );
if ( isBinary() )
{
_in->read( (char*)&((*a)[0]), readSize*size ); checkStream();
if ( useByteSwap && _byteSwap )
{
for ( int i=0; i<size; ++i )
osg::swapBytes( (char*)&((*a)[i]), readSize );
}
}
else
{
for ( int i=0; i<size; ++i )
*this >> (*a)[i];
}
}
*this >> END_BRACKET;
}

478
src/osgDB/ObjectWrapper.cpp Normal file
View File

@@ -0,0 +1,478 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#include <osg/Notify>
#include <osg/BlendFunc>
#include <osg/ClampColor>
#include <osg/Fog>
#include <osg/FragmentProgram>
#include <osg/GL2Extensions>
#include <osg/PointSprite>
#include <osg/StateSet>
#include <osg/StencilTwoSided>
#include <osg/TexEnvCombine>
#include <osg/Texture>
#include <osg/TextureCubeMap>
#include <osg/TextureRectangle>
#include <osg/VertexProgram>
#include <osgDB/Options>
#include <osgDB/DataTypes>
#include <osgDB/ObjectWrapper>
#include <osgDB/Registry>
#include <sstream>
using namespace osgDB;
void osgDB::split( const std::string& src, StringList& list, char separator )
{
std::string::size_type start = src.find_first_not_of(separator);
while ( start!=std::string::npos )
{
std::string::size_type end = src.find_first_of(separator, start);
if ( end!=std::string::npos )
{
list.push_back( std::string(src, start, end-start) );
start = src.find_first_not_of(separator, end);
}
else
{
list.push_back( std::string(src, start, src.size()-start) );
start = end;
}
}
}
ObjectWrapper::ObjectWrapper( osg::Object* proto, const std::string& name,
const std::string& associates )
: osg::Referenced(),
_proto(proto), _name(name)
{
split( associates, _associates );
}
bool ObjectWrapper::read( InputStream& is, osg::Object& obj )
{
bool readOK = true;
for ( SerializerList::iterator itr=_serializers.begin();
itr!=_serializers.end(); ++itr )
{
if ( (*itr)->read(is, obj) ) continue;
osg::notify(osg::WARN) << "ObjectWrapper::read(): Error reading property "
<< _name << "::" << (*itr)->getName() << std::endl;
readOK = false;
}
return readOK;
}
bool ObjectWrapper::write( OutputStream& os, const osg::Object& obj )
{
bool writeOK = true;
for ( SerializerList::iterator itr=_serializers.begin();
itr!=_serializers.end(); ++itr )
{
if ( (*itr)->write(os, obj) ) continue;
osg::notify(osg::WARN) << "ObjectWrapper::write(): Error writing property "
<< _name << "::" << (*itr)->getName() << std::endl;
writeOK = false;
}
return writeOK;
}
bool ObjectWrapper::readSchema( const StringList& properties )
{
if ( !_backupSerializers.size() )
_backupSerializers = _serializers;
_serializers.clear();
unsigned int size = properties.size();
unsigned int serializersSize = _backupSerializers.size();
for ( unsigned int i=0; i<size; ++i )
{
if ( serializersSize<i )
{
osg::notify(osg::WARN) << "ObjectWrapper::readSchema(): Wrapper " << _name
<< ": Incompatible serializers size" << std::endl;
break;
}
const std::string& prop = properties[i];
if ( prop==_backupSerializers[i]->getName() )
{
_serializers.push_back( _backupSerializers[i] );
}
else
{
bool hasSerializer = false;
for ( SerializerList::iterator itr=_backupSerializers.begin();
itr!=_backupSerializers.end(); ++itr )
{
if ( prop!=(*itr)->getName() ) continue;
_serializers.push_back( *itr );
hasSerializer = true;
}
if ( !hasSerializer )
{
osg::notify(osg::WARN) << "ObjectWrapper::readSchema(): Wrapper " << _name
<< ": Unknown property " << prop << std::endl;
}
}
}
return size==_serializers.size();
}
void ObjectWrapper::writeSchema( StringList& properties )
{
for ( SerializerList::iterator itr=_serializers.begin();
itr!=_serializers.end(); ++itr )
{
properties.push_back( (*itr)->getName() );
}
}
GlobalLookupTable* GlobalLookupTable::instance()
{
static osg::ref_ptr<GlobalLookupTable> s_lookup = new GlobalLookupTable;
return s_lookup.get();
}
GlobalLookupTable::GlobalLookupTable()
{
IntLookup& glTable = _globalMap["GL"];
// Modes
glTable.add( "GL_ALPHA_TEST", GL_ALPHA_TEST );
glTable.add( "GL_BLEND", GL_BLEND );
glTable.add( "GL_COLOR_LOGIC_OP", GL_COLOR_LOGIC_OP );
glTable.add( "GL_COLOR_MATERIAL", GL_COLOR_MATERIAL );
glTable.add( "GL_CULL_FACE", GL_CULL_FACE );
glTable.add( "GL_DEPTH_TEST", GL_DEPTH_TEST );
glTable.add( "GL_FOG", GL_FOG );
glTable.add( "GL_FRAGMENT_PROGRAM_ARB", GL_FRAGMENT_PROGRAM_ARB );
glTable.add( "GL_LINE_STIPPLE", GL_LINE_STIPPLE );
glTable.add( "GL_POINT_SMOOTH", GL_POINT_SMOOTH );
glTable.add( "GL_POINT_SPRITE_ARB", GL_POINT_SPRITE_ARB );
glTable.add( "GL_POLYGON_OFFSET_FILL", GL_POLYGON_OFFSET_FILL );
glTable.add( "GL_POLYGON_OFFSET_LINE", GL_POLYGON_OFFSET_LINE );
glTable.add( "GL_POLYGON_OFFSET_POINT", GL_POLYGON_OFFSET_POINT );
glTable.add( "GL_POLYGON_STIPPLE", GL_POLYGON_STIPPLE );
glTable.add( "GL_SCISSOR_TEST", GL_SCISSOR_TEST);
glTable.add( "GL_STENCIL_TEST", GL_STENCIL_TEST );
glTable.add( "GL_STENCIL_TEST_TWO_SIDE", GL_STENCIL_TEST_TWO_SIDE );
glTable.add( "GL_VERTEX_PROGRAM_ARB", GL_VERTEX_PROGRAM_ARB );
glTable.add( "GL_COLOR_SUM", GL_COLOR_SUM );
glTable.add( "GL_LIGHTING", GL_LIGHTING );
glTable.add( "GL_NORMALIZE", GL_NORMALIZE );
glTable.add( "GL_RESCALE_NORMAL", GL_RESCALE_NORMAL );
glTable.add( "GL_TEXTURE_1D", GL_TEXTURE_1D );
glTable.add( "GL_TEXTURE_2D", GL_TEXTURE_2D );
glTable.add( "GL_TEXTURE_3D", GL_TEXTURE_3D );
glTable.add( "GL_TEXTURE_CUBE_MAP", GL_TEXTURE_CUBE_MAP );
glTable.add( "GL_TEXTURE_RECTANGLE", GL_TEXTURE_RECTANGLE );
glTable.add( "GL_TEXTURE_GEN_Q", GL_TEXTURE_GEN_Q );
glTable.add( "GL_TEXTURE_GEN_R", GL_TEXTURE_GEN_R );
glTable.add( "GL_TEXTURE_GEN_S", GL_TEXTURE_GEN_S );
glTable.add( "GL_TEXTURE_GEN_T", GL_TEXTURE_GEN_T );
glTable.add( "GL_CLIP_PLANE0", GL_CLIP_PLANE0 );
glTable.add( "GL_CLIP_PLANE1", GL_CLIP_PLANE1 );
glTable.add( "GL_CLIP_PLANE2", GL_CLIP_PLANE2 );
glTable.add( "GL_CLIP_PLANE3", GL_CLIP_PLANE3 );
glTable.add( "GL_CLIP_PLANE4", GL_CLIP_PLANE4 );
glTable.add( "GL_CLIP_PLANE5", GL_CLIP_PLANE5 );
glTable.add( "GL_LIGHT0", GL_LIGHT0 );
glTable.add( "GL_LIGHT1", GL_LIGHT1 );
glTable.add( "GL_LIGHT2", GL_LIGHT2 );
glTable.add( "GL_LIGHT3", GL_LIGHT3 );
glTable.add( "GL_LIGHT4", GL_LIGHT4 );
glTable.add( "GL_LIGHT5", GL_LIGHT5 );
glTable.add( "GL_LIGHT6", GL_LIGHT6 );
glTable.add( "GL_LIGHT7", GL_LIGHT7 );
// Functions
glTable.add( "NEVER", GL_NEVER );
glTable.add( "LESS", GL_LESS );
glTable.add( "EQUAL", GL_EQUAL );
glTable.add( "LEQUAL", GL_LEQUAL );
glTable.add( "GREATER", GL_GREATER );
glTable.add( "NOTEQUAL", GL_NOTEQUAL );
glTable.add( "GEQUAL", GL_GEQUAL );
glTable.add( "ALWAYS", GL_ALWAYS );
// Texture environment states
glTable.add( "REPLACE", GL_REPLACE );
glTable.add( "MODULATE", GL_MODULATE );
glTable.add( "ADD", GL_ADD );
glTable.add( "ADD_SIGNED", GL_ADD_SIGNED_ARB );
glTable.add( "INTERPOLATE", GL_INTERPOLATE_ARB );
glTable.add( "SUBTRACT", GL_SUBTRACT_ARB );
glTable.add( "DOT3_RGB", GL_DOT3_RGB_ARB );
glTable.add( "DOT3_RGBA", GL_DOT3_RGBA_ARB );
glTable.add( "CONSTANT", GL_CONSTANT_ARB );
glTable.add( "PRIMARY_COLOR", GL_PRIMARY_COLOR_ARB );
glTable.add( "PREVIOUS", GL_PREVIOUS_ARB );
glTable.add( "TEXTURE", GL_TEXTURE );
glTable.add( "TEXTURE0", GL_TEXTURE0 );
glTable.add( "TEXTURE1", GL_TEXTURE0+1 );
glTable.add( "TEXTURE2", GL_TEXTURE0+2 );
glTable.add( "TEXTURE3", GL_TEXTURE0+3 );
glTable.add( "TEXTURE4", GL_TEXTURE0+4 );
glTable.add( "TEXTURE5", GL_TEXTURE0+5 );
glTable.add( "TEXTURE6", GL_TEXTURE0+6 );
glTable.add( "TEXTURE7", GL_TEXTURE0+7 );
// Texture clamp modes
glTable.add( "CLAMP", GL_CLAMP );
glTable.add( "CLAMP_TO_EDGE", GL_CLAMP_TO_EDGE );
glTable.add( "CLAMP_TO_BORDER", GL_CLAMP_TO_BORDER_ARB );
glTable.add( "REPEAT", GL_REPEAT );
glTable.add( "MIRROR", GL_MIRRORED_REPEAT_IBM );
// Texture filter modes
glTable.add( "LINEAR", GL_LINEAR );
glTable.add( "LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR );
glTable.add( "LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST );
glTable.add( "NEAREST", GL_NEAREST );
glTable.add( "NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR );
glTable.add( "NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST );
// Texture formats
glTable.add( "GL_INTENSITY", GL_INTENSITY );
glTable.add( "GL_LUMINANCE", GL_LUMINANCE );
glTable.add( "GL_ALPHA", GL_ALPHA );
glTable.add( "GL_LUMINANCE_ALPHA", GL_LUMINANCE_ALPHA );
glTable.add( "GL_RGB", GL_RGB );
glTable.add( "GL_RGBA", GL_RGBA );
glTable.add( "GL_COMPRESSED_ALPHA_ARB", GL_COMPRESSED_ALPHA_ARB );
glTable.add( "GL_COMPRESSED_LUMINANCE_ARB", GL_COMPRESSED_LUMINANCE_ARB );
glTable.add( "GL_COMPRESSED_INTENSITY_ARB", GL_COMPRESSED_INTENSITY_ARB );
glTable.add( "GL_COMPRESSED_LUMINANCE_ALPHA_ARB", GL_COMPRESSED_LUMINANCE_ALPHA_ARB );
glTable.add( "GL_COMPRESSED_RGB_ARB", GL_COMPRESSED_RGB_ARB );
glTable.add( "GL_COMPRESSED_RGBA_ARB", GL_COMPRESSED_RGBA_ARB );
glTable.add( "GL_COMPRESSED_RGB_S3TC_DXT1_EXT", GL_COMPRESSED_RGB_S3TC_DXT1_EXT );
glTable.add( "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT", GL_COMPRESSED_RGBA_S3TC_DXT1_EXT );
glTable.add( "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT", GL_COMPRESSED_RGBA_S3TC_DXT3_EXT );
glTable.add( "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT", GL_COMPRESSED_RGBA_S3TC_DXT5_EXT );
// Texture source types
glTable.add( "GL_BYTE", GL_BYTE );
glTable.add( "GL_SHORT", GL_SHORT );
glTable.add( "GL_INT", GL_INT );
glTable.add( "GL_FLOAT", GL_FLOAT );
glTable.add( "GL_DOUBLE", GL_DOUBLE );
glTable.add( "GL_UNSIGNED_BYTE", GL_UNSIGNED_BYTE );
glTable.add( "GL_UNSIGNED_SHORT", GL_UNSIGNED_SHORT );
glTable.add( "GL_UNSIGNED_INT", GL_UNSIGNED_INT );
// Blend values
glTable.add( "DST_ALPHA", GL_DST_ALPHA );
glTable.add( "DST_COLOR", GL_DST_COLOR );
glTable.add( "ONE", GL_ONE );
glTable.add( "ONE_MINUS_DST_ALPHA", GL_ONE_MINUS_DST_ALPHA );
glTable.add( "ONE_MINUS_DST_COLOR", GL_ONE_MINUS_DST_COLOR );
glTable.add( "ONE_MINUS_SRC_ALPHA", GL_ONE_MINUS_SRC_ALPHA );
glTable.add( "ONE_MINUS_SRC_COLOR", GL_ONE_MINUS_SRC_COLOR );
glTable.add( "SRC_ALPHA", GL_SRC_ALPHA );
glTable.add( "SRC_ALPHA_SATURATE", GL_SRC_ALPHA_SATURATE );
glTable.add( "SRC_COLOR", GL_SRC_COLOR );
glTable.add( "CONSTANT_COLOR", GL_CONSTANT_COLOR );
glTable.add( "ONE_MINUS_CONSTANT_COLOR", GL_ONE_MINUS_CONSTANT_COLOR );
glTable.add( "CONSTANT_ALPHA", GL_CONSTANT_ALPHA );
glTable.add( "ONE_MINUS_CONSTANT_ALPHA", GL_ONE_MINUS_CONSTANT_ALPHA );
glTable.add( "ZERO", GL_ZERO );
// Fog coordinate sources
glTable.add( "COORDINATE", GL_FOG_COORDINATE );
glTable.add( "DEPTH", GL_FRAGMENT_DEPTH );
// Hint targets
glTable.add( "FOG_HINT", GL_FOG_HINT );
glTable.add( "GENERATE_MIPMAP_HINT", GL_GENERATE_MIPMAP_HINT_SGIS );
glTable.add( "LINE_SMOOTH_HINT", GL_LINE_SMOOTH_HINT );
glTable.add( "PERSPECTIVE_CORRECTION_HINT", GL_PERSPECTIVE_CORRECTION_HINT );
glTable.add( "POINT_SMOOTH_HINT", GL_POINT_SMOOTH_HINT );
glTable.add( "POLYGON_SMOOTH_HINT", GL_POLYGON_SMOOTH_HINT );
glTable.add( "TEXTURE_COMPRESSION_HINT", GL_TEXTURE_COMPRESSION_HINT_ARB );
glTable.add( "FRAGMENT_SHADER_DERIVATIVE_HINT", GL_FRAGMENT_SHADER_DERIVATIVE_HINT );
// Polygon modes
glTable.add( "POINT", GL_POINT );
glTable.add( "LINE", GL_LINE );
glTable.add( "FILL", GL_FILL );
// Misc
glTable.add( "BACK", GL_BACK );
glTable.add( "FRONT", GL_FRONT );
glTable.add( "FRONT_AND_BACK", GL_FRONT_AND_BACK );
glTable.add( "FIXED_ONLY", GL_FIXED_ONLY );
glTable.add( "FASTEST", GL_FASTEST );
glTable.add( "NICEST", GL_NICEST );
glTable.add( "DONT_CARE", GL_DONT_CARE );
IntLookup& arrayTable = _globalMap["ArrayType"];
arrayTable.add( "ByteArray", ID_BYTE_ARRAY );
arrayTable.add( "UByteArray", ID_UBYTE_ARRAY );
arrayTable.add( "ShortArray", ID_SHORT_ARRAY );
arrayTable.add( "UShortArray", ID_USHORT_ARRAY );
arrayTable.add( "IntArray", ID_INT_ARRAY );
arrayTable.add( "UIntArray", ID_UINT_ARRAY );
arrayTable.add( "FloatArray", ID_FLOAT_ARRAY );
arrayTable.add( "DoubleArray", ID_DOUBLE_ARRAY );
arrayTable.add( "Vec2bArray", ID_VEC2B_ARRAY );
arrayTable.add( "Vec3bArray", ID_VEC3B_ARRAY );
arrayTable.add( "Vec4bArray", ID_VEC4B_ARRAY );
arrayTable.add( "Vec4ubArray", ID_VEC4UB_ARRAY );
arrayTable.add( "Vec2sArray", ID_VEC2S_ARRAY );
arrayTable.add( "Vec3sArray", ID_VEC3S_ARRAY );
arrayTable.add( "Vec4sArray", ID_VEC4S_ARRAY );
arrayTable.add( "Vec2fArray", ID_VEC2_ARRAY );
arrayTable.add( "Vec3fArray", ID_VEC3_ARRAY );
arrayTable.add( "Vec4fArray", ID_VEC4_ARRAY );
arrayTable.add( "Vec2dArray", ID_VEC2D_ARRAY );
arrayTable.add( "Vec3dArray", ID_VEC3D_ARRAY );
arrayTable.add( "Vec4dArray", ID_VEC4D_ARRAY );
IntLookup& primitiveTable = _globalMap["PrimitiveType"];
primitiveTable.add( "DrawArrays", ID_DRAWARRAYS );
primitiveTable.add( "DrawArraysLength", ID_DRAWARRAY_LENGTH );
primitiveTable.add( "DrawElementsUByte", ID_DRAWELEMENTS_UBYTE );
primitiveTable.add( "DrawElementsUShort", ID_DRAWELEMENTS_USHORT );
primitiveTable.add( "DrawElementsUInt", ID_DRAWELEMENTS_UINT );
primitiveTable.add( "GL_POINTS", GL_POINTS );
primitiveTable.add( "GL_LINES", GL_LINES );
primitiveTable.add( "GL_LINE_STRIP", GL_LINE_STRIP );
primitiveTable.add( "GL_LINE_LOOP", GL_LINE_LOOP );
primitiveTable.add( "GL_TRIANGLES", GL_TRIANGLES );
primitiveTable.add( "GL_TRIANGLE_STRIP", GL_TRIANGLE_STRIP );
primitiveTable.add( "GL_TRIANGLE_FAN", GL_TRIANGLE_FAN );
primitiveTable.add( "GL_QUADS", GL_QUADS );
primitiveTable.add( "GL_QUAD_STRIP", GL_QUAD_STRIP );
primitiveTable.add( "GL_POLYGON", GL_POLYGON );
primitiveTable.add( "GL_LINES_ADJACENCY_EXT", GL_LINES_ADJACENCY_EXT );
primitiveTable.add( "GL_LINE_STRIP_ADJACENCY_EXT", GL_LINE_STRIP_ADJACENCY_EXT );
primitiveTable.add( "GL_TRIANGLES_ADJACENCY_EXT", GL_TRIANGLES_ADJACENCY_EXT );
primitiveTable.add( "GL_TRIANGLE_STRIP_ADJACENCY_EXT", GL_TRIANGLE_STRIP_ADJACENCY_EXT );
}
RegisterWrapperProxy::RegisterWrapperProxy( osg::Object* proto, const std::string& name,
const std::string& associates, AddPropFunc func )
{
_wrapper = new ObjectWrapper( proto, name, associates );
if ( func ) (*func)( _wrapper.get() );
ObjectRegistry::instance()->addWrapper( _wrapper.get() );
}
RegisterWrapperProxy::~RegisterWrapperProxy()
{
ObjectRegistry::instance()->removeWrapper( _wrapper.get() );
}
ObjectRegistry* ObjectRegistry::instance()
{
static osg::ref_ptr<ObjectRegistry> s_registry = new ObjectRegistry;
return s_registry.get();
}
void ObjectRegistry::addWrapper( ObjectWrapper* wrapper )
{
if ( !wrapper ) return;
WrapperMap::iterator itr = _wrappers.find( wrapper->getName() );
if ( itr!=_wrappers.end() )
{
osg::notify(osg::WARN) << "ObjectRegistry::addWrapper(): '" << wrapper->getName()
<< "' already exists." << std::endl;
}
_wrappers[wrapper->getName()] = wrapper;
}
void ObjectRegistry::removeWrapper( ObjectWrapper* wrapper )
{
if ( !wrapper ) return;
WrapperMap::iterator itr = _wrappers.find( wrapper->getName() );
if ( itr!=_wrappers.end() ) _wrappers.erase( itr );
}
ObjectWrapper* ObjectRegistry::findWrapper( const std::string& name )
{
WrapperMap::iterator itr = _wrappers.find( name );
if ( itr!=_wrappers.end() ) return itr->second.get();
// Load external libraries
std::string::size_type posDoubleColon = name.rfind("::");
if ( posDoubleColon!=std::string::npos )
{
std::string libName = std::string( name, 0, posDoubleColon );
std::string nodeKitLib = osgDB::Registry::instance()->createLibraryNameForNodeKit(libName);
if ( osgDB::Registry::instance()->loadLibrary(nodeKitLib)==osgDB::Registry::LOADED )
return findWrapper(name);
std::string pluginLib = osgDB::Registry::instance()->createLibraryNameForExtension(libName);
if ( osgDB::Registry::instance()->loadLibrary(pluginLib)==osgDB::Registry::LOADED )
return findWrapper(name);
}
return NULL;
}
void ObjectRegistry::addCompressor( BaseCompressor* compressor )
{
if ( !compressor ) return;
CompressorMap::iterator itr = _compressors.find( compressor->getName() );
if ( itr!=_compressors.end() )
{
osg::notify(osg::WARN) << "ObjectRegistry::addCompressor(): '" << compressor->getName()
<< "' already exists." << std::endl;
}
_compressors[compressor->getName()] = compressor;
}
void ObjectRegistry::removeCompressor( BaseCompressor* compressor )
{
if ( !compressor ) return;
CompressorMap::iterator itr = _compressors.find( compressor->getName() );
if ( itr!=_compressors.end() ) _compressors.erase( itr );
}
BaseCompressor* ObjectRegistry::findCompressor( const std::string& name )
{
CompressorMap::iterator itr = _compressors.find( name );
if ( itr!=_compressors.end() ) return itr->second.get();
// Load external libraries
std::string::size_type posDoubleColon = name.rfind("::");
if ( posDoubleColon!=std::string::npos )
{
std::string libName = std::string( name, 0, posDoubleColon );
std::string nodeKitLib = osgDB::Registry::instance()->createLibraryNameForNodeKit(libName);
if ( osgDB::Registry::instance()->loadLibrary(nodeKitLib)==osgDB::Registry::LOADED )
return findCompressor(name);
std::string pluginLib = osgDB::Registry::instance()->createLibraryNameForExtension(libName);
if ( osgDB::Registry::instance()->loadLibrary(pluginLib)==osgDB::Registry::LOADED )
return findCompressor(name);
}
return NULL;
}

625
src/osgDB/OutputStream.cpp Normal file
View File

@@ -0,0 +1,625 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#include <osg/Version>
#include <osg/Notify>
#include <osgDB/FileUtils>
#include <osgDB/WriteFile>
#include <osgDB/ObjectWrapper>
#include <fstream>
using namespace osgDB;
OutputStream::OutputStream( std::ostream* ostream, const osgDB::Options* options )
: _writeMode(WRITE_BINARY), _writeImageHint(WRITE_USE_IMAGE_HINT),
_readyForEndBracket(false), _indent(0),
_out(ostream)
{
if ( !_out )
throw OutputException(_currentField, "OutputStream: Null stream specified.");
if ( !options ) return;
StringList optionList;
split( options->getOptionString(), optionList );
for ( StringList::iterator itr=optionList.begin(); itr!=optionList.end(); ++itr )
{
const std::string& option = *itr;
if ( option=="Ascii" )
_writeMode = WRITE_ASCII;
else
{
StringList keyAndValues;
split( option, keyAndValues, '=' );
if ( keyAndValues.size()<2 ) continue;
if ( keyAndValues[0]=="SchemaFile" )
{
osgDB::ofstream schemaStream( keyAndValues[1].c_str(), std::ios::out );
if ( !schemaStream.fail() ) writeSchema( schemaStream );
schemaStream.close();
}
else if ( keyAndValues[0]=="Compressor" )
_compressorName = keyAndValues[1];
else if ( keyAndValues[0]=="WriteImageHint" )
{
if ( keyAndValues[1]=="IncludeData" ) _writeImageHint = WRITE_INLINE_DATA;
else if ( keyAndValues[1]=="IncludeFile" ) _writeImageHint = WRITE_INLINE_FILE;
else if ( keyAndValues[1]=="UseExternal" ) _writeImageHint = WRITE_USE_EXTERNAL;
else if ( keyAndValues[1]=="WriteOut" ) _writeImageHint = WRITE_EXTERNAL_FILE;
}
else
osg::notify(osg::WARN) << "OutputStream: Unknown option " << option << std::endl;
}
}
}
OutputStream::~OutputStream()
{
}
OutputStream& OutputStream::operator<<( const osg::Vec2b& v )
{ *this << v.x() << v.y(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec3b& v )
{ *this << v.x() << v.y() << v.z(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec4b& v )
{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec4ub& v )
{ *this << v.r() << v.g() << v.b() << v.a(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec2s& v )
{ *this << v.x() << v.y(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec3s& v )
{ *this << v.x() << v.y() << v.z(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec4s& v )
{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec2f& v )
{ *this << v.x() << v.y(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec3f& v )
{ *this << v.x() << v.y() << v.z(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec4f& v )
{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec2d& v )
{ *this << v.x() << v.y(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec3d& v )
{ *this << v.x() << v.y() << v.z(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Vec4d& v )
{ *this << v.x() << v.y() << v.z() << v.w(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Quat& q )
{ *this << q.x() << q.y() << q.z() << q.w(); return *this; }
OutputStream& OutputStream::operator<<( const osg::Plane& p )
{ *this << (double)p[0] << (double)p[1] << (double)p[2] << (double)p[3]; return *this; }
OutputStream& OutputStream::operator<<( const osg::Matrixf& mat )
{
*this << PROPERTY("Matrixf") << BEGIN_BRACKET << std::endl;
for ( int r=0; r<4; ++r )
{
*this << mat(r, 0) << mat(r, 1)
<< mat(r, 2) << mat(r, 3) << std::endl;
}
*this << END_BRACKET << std::endl;
return *this;
}
OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
{
*this << PROPERTY("Matrixd") << BEGIN_BRACKET << std::endl;
for ( int r=0; r<4; ++r )
{
*this << mat(r, 0) << mat(r, 1)
<< mat(r, 2) << mat(r, 3) << std::endl;
}
*this << END_BRACKET << std::endl;
return *this;
}
OutputStream& OutputStream::operator<<( const ObjectGLenum& value )
{
GLenum e = value.get();
if ( isBinary() )
{
_out->write((char*)&e, GLENUM_SIZE);
}
else
{
const std::string& enumString =
GlobalLookupTable::instance()->getString("GL", e);
*_out << enumString << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( const ObjectProperty& prop )
{
if ( isBinary() )
{
if ( prop._mapProperty )
_out->write( (char*)&(prop._value), INT_SIZE );
}
else
{
std::string enumString = prop._name;
if ( prop._mapProperty )
{
enumString =
GlobalLookupTable::instance()->getString(prop._name, prop._value);
}
*_out << enumString << ' ';
}
return *this;
}
OutputStream& OutputStream::operator<<( const ObjectMark& mark )
{
if ( !isBinary() )
{
int delta = mark._indentDelta;
if ( delta<0 && _readyForEndBracket )
{
if ( _indent<-delta ) delta = -_indent;
_readyForEndBracket = false;
_out->seekp( delta, std::ios::cur );
}
_indent += delta;
*this << mark._name;
}
return *this;
}
void OutputStream::writeArray( const osg::Array* a )
{
if ( !a ) return;
unsigned int id = findOrCreateArrayID( a );
*this << PROPERTY("ArrayID") << id;
if ( id<_arrayMap.size() ) // Shared array
{
*this << std::endl;
return;
}
switch ( a->getType() )
{
case osg::Array::ByteArrayType:
*this << MAPPEE(ArrayType, ID_BYTE_ARRAY);
writeArrayImplementation( static_cast<const osg::ByteArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::UByteArrayType:
*this << MAPPEE(ArrayType, ID_UBYTE_ARRAY);
writeArrayImplementation( static_cast<const osg::UByteArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::ShortArrayType:
*this << MAPPEE(ArrayType, ID_SHORT_ARRAY);
writeArrayImplementation( static_cast<const osg::ShortArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::UShortArrayType:
*this << MAPPEE(ArrayType, ID_USHORT_ARRAY);
writeArrayImplementation( static_cast<const osg::UShortArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::IntArrayType:
*this << MAPPEE(ArrayType, ID_INT_ARRAY);
writeArrayImplementation( static_cast<const osg::IntArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::UIntArrayType:
*this << MAPPEE(ArrayType, ID_UINT_ARRAY);
writeArrayImplementation( static_cast<const osg::UIntArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::FloatArrayType:
*this << MAPPEE(ArrayType, ID_FLOAT_ARRAY);
writeArrayImplementation( static_cast<const osg::FloatArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::DoubleArrayType:
*this << MAPPEE(ArrayType, ID_DOUBLE_ARRAY);
writeArrayImplementation( static_cast<const osg::DoubleArray*>(a), a->getNumElements(), 4 );
break;
case osg::Array::Vec2bArrayType:
*this << MAPPEE(ArrayType, ID_VEC2B_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec2bArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec3bArrayType:
*this << MAPPEE(ArrayType, ID_VEC3B_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec3bArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec4bArrayType:
*this << MAPPEE(ArrayType, ID_VEC4B_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec4bArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec4ubArrayType:
*this << MAPPEE(ArrayType, ID_VEC4UB_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec4ubArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec2sArrayType:
*this << MAPPEE(ArrayType, ID_VEC2S_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec2sArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec3sArrayType:
*this << MAPPEE(ArrayType, ID_VEC3S_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec3sArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec4sArrayType:
*this << MAPPEE(ArrayType, ID_VEC4S_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec4sArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec2ArrayType:
*this << MAPPEE(ArrayType, ID_VEC2_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec2Array*>(a), a->getNumElements() );
break;
case osg::Array::Vec3ArrayType:
*this << MAPPEE(ArrayType, ID_VEC3_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec3Array*>(a), a->getNumElements() );
break;
case osg::Array::Vec4ArrayType:
*this << MAPPEE(ArrayType, ID_VEC4_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec4Array*>(a), a->getNumElements() );
break;
case osg::Array::Vec2dArrayType:
*this << MAPPEE(ArrayType, ID_VEC4D_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec2dArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec3dArrayType:
*this << MAPPEE(ArrayType, ID_VEC4D_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec3dArray*>(a), a->getNumElements() );
break;
case osg::Array::Vec4dArrayType:
*this << MAPPEE(ArrayType, ID_VEC4D_ARRAY);
writeArrayImplementation( static_cast<const osg::Vec4dArray*>(a), a->getNumElements() );
break;
default:
throw OutputException(_currentField, "OutputStream::writeArray(): Unsupported array type.");
}
}
void OutputStream::writePrimitiveSet( const osg::PrimitiveSet* p )
{
if ( !p ) return;
switch ( p->getType() )
{
case osg::PrimitiveSet::DrawArraysPrimitiveType:
*this << MAPPEE(PrimitiveType, ID_DRAWARRAYS);
{
const osg::DrawArrays* da = static_cast<const osg::DrawArrays*>(p);
*this << MAPPEE(PrimitiveType, da->getMode())
<< da->getFirst() << da->getCount() << std::endl;
}
break;
case osg::PrimitiveSet::DrawArrayLengthsPrimitiveType:
*this << MAPPEE(PrimitiveType, ID_DRAWARRAY_LENGTH);
{
const osg::DrawArrayLengths* dl = static_cast<const osg::DrawArrayLengths*>(p);
*this << MAPPEE(PrimitiveType, dl->getMode()) << dl->getFirst();
writeArrayImplementation( dl, dl->size(), 4 );
}
break;
case osg::PrimitiveSet::DrawElementsUBytePrimitiveType:
*this << MAPPEE(PrimitiveType, ID_DRAWELEMENTS_UBYTE);
{
const osg::DrawElementsUByte* de = static_cast<const osg::DrawElementsUByte*>(p);
*this << MAPPEE(PrimitiveType, de->getMode());
writeArrayImplementation( de, de->size(), 4 );
}
break;
case osg::PrimitiveSet::DrawElementsUShortPrimitiveType:
*this << MAPPEE(PrimitiveType, ID_DRAWELEMENTS_USHORT);
{
const osg::DrawElementsUShort* de = static_cast<const osg::DrawElementsUShort*>(p);
*this << MAPPEE(PrimitiveType, de->getMode());
writeArrayImplementation( de, de->size(), 4 );
}
break;
case osg::PrimitiveSet::DrawElementsUIntPrimitiveType:
*this << MAPPEE(PrimitiveType, ID_DRAWELEMENTS_UINT);
{
const osg::DrawElementsUInt* de = static_cast<const osg::DrawElementsUInt*>(p);
*this << MAPPEE(PrimitiveType, de->getMode());
writeArrayImplementation( de, de->size(), 4 );
}
break;
default:
throw OutputException(_currentField, "OutputStream::writePrimitiveSet(): Unsupported primitive type.");
}
}
void OutputStream::writeImage( const osg::Image* img )
{
if ( !img ) return;
*this << PROPERTY("FileName"); writeWrappedString(img->getFileName()); *this << std::endl;
*this << PROPERTY("WriteHint") << (int)img->getWriteHint();
int decision = IMAGE_EXTERNAL;
switch ( _writeImageHint )
{
case OutputStream::WRITE_INLINE_DATA: decision = IMAGE_INLINE_DATA; break;
case OutputStream::WRITE_INLINE_FILE: decision = IMAGE_INLINE_FILE; break;
case OutputStream::WRITE_EXTERNAL_FILE: decision = IMAGE_EXTERNAL; break;
case OutputStream::WRITE_USE_EXTERNAL: decision = IMAGE_WRITE_OUT; break;
default:
if ( img->getWriteHint()==osg::Image::STORE_INLINE && isBinary() )
decision = IMAGE_INLINE_DATA;
else if ( img->getWriteHint()==osg::Image::EXTERNAL_FILE )
decision = IMAGE_WRITE_OUT;
break;
}
*this << decision << std::endl;
if ( decision==IMAGE_WRITE_OUT || _writeImageHint==WRITE_EXTERNAL_FILE )
{
bool result = osgDB::writeImageFile( *img, img->getFileName() );
osg::notify(osg::NOTICE) << "OutputStream::writeImage(): Write image data to external file "
<< img->getFileName() << std::endl;
if ( !result )
{
osg::notify(osg::WARN) << "OutputStream::writeImage(): Failed to write "
<< img->getFileName() << std::endl;
}
}
switch ( decision )
{
case IMAGE_INLINE_DATA:
if ( isBinary() )
{
*this << img->getOrigin(); // _origin
*this << img->s() << img->t() << img->r(); // _s & _t & _r
*this << img->getInternalTextureFormat(); // _internalTextureFormat
*this << img->getPixelFormat(); // _pixelFormat
*this << img->getDataType(); // _dataType
*this << img->getPacking(); // _packing
*this << img->getAllocationMode(); // _allocationMode
// _data
unsigned int size = img->getTotalSizeInBytesIncludingMipmaps();
*this << size; writeCharArray( (char*)img->data(), size );
// _mipmapData
const osg::Image::MipmapDataType& levels = img->getMipmapLevels();
*this << levels.size();
for ( osg::Image::MipmapDataType::const_iterator itr=levels.begin();
itr!=levels.end(); ++itr )
{
*this << *itr;
}
}
break;
case IMAGE_INLINE_FILE:
if ( isBinary() )
{
std::string fullPath = osgDB::findDataFile( img->getFileName() );
std::ifstream infile( fullPath.c_str(), std::ios::in|std::ios::binary );
if ( infile )
{
infile.seekg( 0, std::ios::end );
unsigned int size = infile.tellg();
*this << size;
if ( size>0 )
{
char* data = new char[size];
if ( !data )
throw OutputException(_currentField, "OutputStream::writeImage(): Out of memory.");
infile.seekg( 0, std::ios::beg );
infile.read( data, size );
writeCharArray( data, size );
delete[] data;
}
infile.close();
}
else
{
osg::notify(osg::WARN) << "OutputStream::writeImage(): Failed to open image file "
<< img->getFileName() << std::endl;
*this << (unsigned int)0;
}
}
break;
case IMAGE_EXTERNAL:
break;
default:
break;
}
writeObject( img );
}
void OutputStream::writeObject( const osg::Object* obj )
{
if ( !obj ) return;
std::string name = obj->libraryName();
name += std::string("::") + obj->className();
unsigned int id = findOrCreateObjectID( obj );
*this << name << BEGIN_BRACKET << std::endl; // Write object name
*this << PROPERTY("UniqueID") << id << std::endl; // Write object ID
// Check whether this is a shared object or not
if ( id>=_objectMap.size() )
{
ObjectWrapper* wrapper = ObjectRegistry::instance()->findWrapper( name );
if ( !wrapper )
{
osg::notify(osg::WARN) << "OutputStream::writeObject(): Unsupported wrapper class "
<< name << std::endl;
*this << END_BRACKET << std::endl;
return;
}
const StringList& associates = wrapper->getAssociates();
for ( StringList::const_iterator itr=associates.begin(); itr!=associates.end(); ++itr )
{
ObjectWrapper* assocWrapper = ObjectRegistry::instance()->findWrapper(*itr);
if ( !assocWrapper )
{
osg::notify(osg::WARN) << "OutputStream::writeObject(): Unsupported associated class "
<< *itr << std::endl;
continue;
}
_currentField = assocWrapper->getName();
assocWrapper->write( *this, *obj );
}
}
*this << END_BRACKET << std::endl;
}
void OutputStream::start( OutputStream::WriteType type )
{
_currentField = "Header";
if ( isBinary() )
{
*this << (unsigned int)OSG_HEADER_LOW << (unsigned int)OSG_HEADER_HIGH
<< (unsigned int)type << (unsigned int)PLUGIN_VERSION;
if ( sizeof(osg::Matrix::value_type)==FLOAT_SIZE ) *this << (unsigned int)0;
else *this << (unsigned int)1; // Record matrix value type of current built OSG
if ( !_compressorName.empty() )
{
BaseCompressor* compressor =
ObjectRegistry::instance()->findCompressor(_compressorName);
if ( !compressor )
{
osg::notify(osg::WARN) << "OutputStream::start(): No such compressor "
<< _compressorName << std::endl;
}
else
{
*this << _compressorName;
_out->flush();
_out = &_compressSource;
return;
}
}
*this << std::string("0");
}
else
{
std::string typeString("Unknown");
switch ( type )
{
case WRITE_SCENE: typeString = "Scene"; break;
case WRITE_IMAGE: typeString = "Image"; break;
default: break;
}
*this << PROPERTY("#Ascii") << typeString << std::endl;
*this << PROPERTY("#Version") << (unsigned int)PLUGIN_VERSION << std::endl;
*this << PROPERTY("#Generator") << std::string("OpenSceneGraph")
<< std::string(osgGetVersion()) << std::endl;
*this << std::endl;
}
}
void OutputStream::compress( std::ostream* ostream )
{
_currentField = "Compression";
if ( _compressorName.empty() || !isBinary() ) return;
BaseCompressor* compressor =
ObjectRegistry::instance()->findCompressor(_compressorName);
if ( !compressor || !ostream ) return;
if ( !compressor->compress(*ostream, _compressSource.str()) )
throw OutputException(_currentField, "OutputStream: Failed to compress stream.");
}
// PROTECTED METHODS
void OutputStream::writeSchema( std::ostream& fout )
{
// Write to external ascii stream
const ObjectRegistry::WrapperMap& wrappers = ObjectRegistry::instance()->getWrapperMap();
for ( ObjectRegistry::WrapperMap::const_iterator itr=wrappers.begin();
itr!=wrappers.end(); ++itr )
{
ObjectWrapper* wrapper = itr->second.get();
fout << itr->first << " =";
StringList properties;
wrapper->writeSchema( properties );
if ( properties.size()>0 )
{
for ( StringList::iterator sitr=properties.begin(); sitr!=properties.end(); ++sitr )
{
fout << ' ' << *sitr;
}
}
fout << std::endl;
}
}
template<typename T>
void OutputStream::writeArrayImplementation( const T* a, int writeSize, unsigned int numInRow )
{
*this << writeSize << BEGIN_BRACKET;
if ( numInRow>1 )
{
for ( int i=0; i<writeSize; ++i )
{
if ( !(i%numInRow) )
{
*this << std::endl << (*a)[i];
}
else
*this << (*a)[i];
}
*this << std::endl;
}
else
{
*this << std::endl;
for ( int i=0; i<writeSize; ++i )
*this << (*a)[i] << std::endl;
}
*this << END_BRACKET << std::endl;
}
unsigned int OutputStream::findOrCreateArrayID( const osg::Array* array )
{
ArrayMap::iterator itr = _arrayMap.find( array );
if ( itr==_arrayMap.end() )
{
unsigned int id = _arrayMap.size()+1;
_arrayMap[array] = id;
return id;
}
return itr->second;
}
unsigned int OutputStream::findOrCreateObjectID( const osg::Object* obj )
{
ObjectMap::iterator itr = _objectMap.find( obj );
if ( itr==_objectMap.end() )
{
unsigned int id = _objectMap.size()+1;
_objectMap[obj] = id;
return id;
}
return itr->second;
}

View File

@@ -229,9 +229,13 @@ Registry::Registry()
}
addFileExtensionAlias("osgs", "osg");
addFileExtensionAlias("shadow", "osgShadow");
addFileExtensionAlias("terrain", "osgTerrain");
addFileExtensionAlias("view", "osgViewer");
addFileExtensionAlias("osgt", "osg");
addFileExtensionAlias("osgb", "osg");
addFileExtensionAlias("osgx", "osg");
addFileExtensionAlias("osgShadow", "shadow");
addFileExtensionAlias("osgTerrain", "terrain");
addFileExtensionAlias("osgViewer", "view");
addFileExtensionAlias("sgi", "rgb");
addFileExtensionAlias("rgba", "rgb");

View File

@@ -1,5 +1,6 @@
SET(TARGET_SRC
ReaderWriterOSG.cpp
ReaderWriterOSG2.cpp
)
#### end var setup ###

View File

@@ -0,0 +1,221 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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.
*/
// Written by Wang Rui, (C) 2010
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgDB/ObjectWrapper>
using namespace osgDB;
class ReaderWriterOSG2 : public osgDB::ReaderWriter
{
public:
ReaderWriterOSG2()
{
supportsExtension( "osg2", "OpenSceneGraph extendable format" );
supportsExtension( "osgt", "OpenSceneGraph extendable ascii format" );
supportsExtension( "osgb", "OpenSceneGraph extendable binary format" );
supportsOption( "Ascii", "Import/Export option: Force the writer export ascii file" );
supportsOption( "SchemaFile=<file>", "Import/Export option: Use/Record a ascii schema file" );
supportsOption( "Compressor=<name>", "Export option: Use an inbuilt or user-defined compressor" );
supportsOption( "WriteImageHint=<hint>", "Export option: Hint of writing image to stream: "
"<IncludeData> writes Image::data() directly; "
"<IncludeFile> writes the image file itself to stream; "
"<UseExternal> writes only the filename; "
"<WriteOut> writes Image::data() to disk as external file." );
std::string filename = osgDB::Registry::instance()->createLibraryNameForExtension("serializers_osg");
if (osgDB::Registry::instance()->loadLibrary(filename)==osgDB::Registry::LOADED)
{
osg::notify(osg::NOTICE)<<"Constructor ReaderWriterOSG2 - loaded OK"<<std::endl;
}
else
{
osg::notify(osg::NOTICE)<<"Constructor ReaderWriterOSG2 - failed to load"<<std::endl;
}
}
virtual const char* className() const
{ return "OpenSceneGraph Native Format Reader/Writer"; }
virtual ReadResult readObject( const std::string& file, const Options* options ) const
{ return readNode(file, options); }
virtual ReadResult readObject( std::istream& fin, const Options* options ) const
{ return readNode(fin, options); }
virtual ReadResult readImage( const std::string& file, const Options* options ) const
{
std::string ext = osgDB::getLowerCaseFileExtension( file );
if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND;
osg::ref_ptr<Options> local_opt = options ?
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
osgDB::ifstream istream( fileName.c_str(), std::ios::out|std::ios::binary );
return readImage( istream, local_opt.get() );
}
virtual ReadResult readImage( std::istream& fin, const Options* options ) const
{
try
{
InputStream is( &fin, options );
if ( is.start()!=InputStream::READ_IMAGE )
return ReadResult::FILE_NOT_HANDLED;
is.decompress();
return is.readImage();
}
catch ( InputException e )
{
return e.getError() + " At " + e.getField();
}
}
virtual ReadResult readNode( const std::string& file, const Options* options ) const
{
std::string ext = osgDB::getLowerCaseFileExtension( file );
if ( !acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
std::string fileName = osgDB::findDataFile( file, options );
if ( fileName.empty() ) return ReadResult::FILE_NOT_FOUND;
osg::ref_ptr<Options> local_opt = options ?
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
osgDB::ifstream istream( fileName.c_str(), std::ios::out|std::ios::binary );
return readNode( istream, local_opt.get() );
}
virtual ReadResult readNode( std::istream& fin, const Options* options ) const
{
try
{
InputStream is( &fin, options );
if ( is.start()!=InputStream::READ_SCENE )
return ReadResult::FILE_NOT_HANDLED;
is.decompress();
return dynamic_cast<osg::Node*>( is.readObject() );
}
catch ( InputException e )
{
return e.getError() + " At " + e.getField();
}
}
virtual WriteResult writeObject( const osg::Object& object, const std::string& fileName, const Options* options ) const
{
const osg::Node* node = dynamic_cast<const osg::Node*>( &object );
if ( node ) return writeNode( *node, fileName, options );
const osg::Image* image = dynamic_cast<const osg::Image*>( &object );
if ( image ) return writeImage( *image, fileName, options );
return WriteResult::FILE_NOT_HANDLED;
}
virtual WriteResult writeObject( const osg::Object& object, std::ostream& fout, const Options* options ) const
{
const osg::Node* node = dynamic_cast<const osg::Node*>( &object );
if ( node ) return writeNode( *node, fout, options );
const osg::Image* image = dynamic_cast<const osg::Image*>( &object );
if ( image ) return writeImage( *image, fout, options );
return WriteResult::FILE_NOT_HANDLED;
}
virtual WriteResult writeImage( const osg::Image& image, const std::string& fileName, const Options* options ) const
{
std::string ext = osgDB::getFileExtension( fileName );
if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
osg::ref_ptr<Options> local_opt = options ?
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
if( local_opt->getDatabasePathList().empty() )
local_opt->setDatabasePath( osgDB::getFilePath(fileName) );
if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
osgDB::ofstream fout( fileName.c_str(), std::ios::out|std::ios::binary );
if ( !fout ) return WriteResult::ERROR_IN_WRITING_FILE;
WriteResult result = writeImage( image, fout, local_opt.get() );
fout.close();
return result;
}
virtual WriteResult writeImage( const osg::Image& image, std::ostream& fout, const Options* options ) const
{
try
{
OutputStream os( &fout, options );
os.start( OutputStream::WRITE_IMAGE );
os.writeImage( &image );
os.compress( &fout );
if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
return WriteResult::FILE_SAVED;
}
catch ( OutputException e )
{
osg::notify(osg::WARN) << "ReaderWriterOSG2::writeImage(): " << e.getError()
<< " At " << e.getField() << std::endl;
}
return WriteResult::FILE_NOT_HANDLED;
}
virtual WriteResult writeNode( const osg::Node& node, const std::string& fileName, const Options* options ) const
{
std::string ext = osgDB::getFileExtension( fileName );
if ( !acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
osg::ref_ptr<Options> local_opt = options ?
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
if ( local_opt->getDatabasePathList().empty() )
local_opt->setDatabasePath( osgDB::getFilePath(fileName) );
if ( ext=="osgt" ) local_opt->setOptionString( local_opt->getOptionString() + " Ascii" );
osgDB::ofstream fout( fileName.c_str(), std::ios::out|std::ios::binary );
if ( !fout ) return WriteResult::ERROR_IN_WRITING_FILE;
WriteResult result = writeNode( node, fout, local_opt.get() );
fout.close();
return result;
}
virtual WriteResult writeNode( const osg::Node& node, std::ostream& fout, const Options* options ) const
{
try
{
OutputStream os( &fout, options );
os.start( OutputStream::WRITE_SCENE );
os.writeObject( &node );
os.compress( &fout );
if ( fout.fail() ) return WriteResult::ERROR_IN_WRITING_FILE;
return WriteResult::FILE_SAVED;
}
catch ( OutputException e )
{
osg::notify(osg::WARN) << "ReaderWriterOSG2::writeNode(): " << e.getError()
<< " At " << e.getField() << std::endl;
}
return WriteResult::FILE_NOT_HANDLED;
}
};
REGISTER_OSGPLUGIN( osg2, ReaderWriterOSG2 )

View File

@@ -0,0 +1,36 @@
#---------------------------------------------------
# OSG CMAKE SUPPORT
# (C) by Michael Wagner, mtw@shared-reality.com 2005
# (C) Eric Wing, Luigi Calori and Robert Osfield 2006-2007
#---------------------------------------------------
PROJECT(OSG_PLUGINS_MASTER)
IF(NOT DYNAMIC_OPENSCENEGRAPH)
ADD_DEFINITIONS(-DOSG_LIBRARY_STATIC)
ENDIF()
IF(NOT MSVC)
SET(LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH}/${OSG_PLUGINS}")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OSG_PLUGINS}")
ENDIF()
SET(CMAKE_SHARED_MODULE_PREFIX ${OSG_PLUGIN_PREFIX})
IF(MSVC80 OR MSVC90)
IF(NOT OSG_MSVC_GENERATE_PLUGINS_AND_WRAPPERS_MANIFESTS)
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO")
ENDIF()
ENDIF()
SET(TARGET_DEFAULT_PREFIX "osgdb_serializers_")
SET(TARGET_DEFAULT_LABEL_PREFIX "Plugins")
SET(TARGET_COMMON_LIBRARIES
OpenThreads
osg
osgDB
osgUtil
)
ADD_SUBDIRECTORY(osg)

View File

@@ -0,0 +1,23 @@
#include <osg/AlphaFunc>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( AlphaFunc,
new osg::AlphaFunc,
osg::AlphaFunc,
"osg::Object osg::StateAttribute osg::AlphaFunc" )
{
BEGIN_ENUM_SERIALIZER2( Function, osg::AlphaFunc::ComparisonFunction, ALWAYS );
ADD_ENUM_VALUE( NEVER );
ADD_ENUM_VALUE( LESS );
ADD_ENUM_VALUE( EQUAL );
ADD_ENUM_VALUE( LEQUAL );
ADD_ENUM_VALUE( GREATER );
ADD_ENUM_VALUE( NOTEQUAL );
ADD_ENUM_VALUE( GEQUAL );
ADD_ENUM_VALUE( ALWAYS );
END_ENUM_SERIALIZER(); // _comparisonFunc
ADD_FLOAT_SERIALIZER( ReferenceValue, 1.0f ); // _referenceValue
}

View File

@@ -0,0 +1,75 @@
#undef OBJECT_CAST
#define OBJECT_CAST dynamic_cast
#include <osg/AnimationPath>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkTimeControlPointMap( const osg::AnimationPath& path )
{
return path.getTimeControlPointMap().size()>0;
}
static bool readTimeControlPointMap( osgDB::InputStream& is, osg::AnimationPath& path )
{
unsigned int size = 0; is >> size;
if ( size>0 )
{
is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
double time = 0.0;
osg::Vec3d pos, scale;
osg::Quat rot;
is >> osgDB::PROPERTY("Time") >> time >> osgDB::BEGIN_BRACKET;
is >> osgDB::PROPERTY("Position") >> pos;
is >> osgDB::PROPERTY("Rotation") >> rot;
is >> osgDB::PROPERTY("Scale") >> scale;
is >> osgDB::END_BRACKET;
path.insert( time, osg::AnimationPath::ControlPoint(pos, rot, scale) );
}
is >> osgDB::END_BRACKET;
}
return true;
}
static bool writeTimeControlPointMap( osgDB::OutputStream& os, const osg::AnimationPath& path )
{
const osg::AnimationPath::TimeControlPointMap& map = path.getTimeControlPointMap();
os << map.size();
if ( map.size()>0 )
{
os << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::AnimationPath::TimeControlPointMap::const_iterator itr=map.begin();
itr!=map.end(); ++itr )
{
const osg::AnimationPath::ControlPoint& pt = itr->second;
os << osgDB::PROPERTY("Time") << itr->first << osgDB::BEGIN_BRACKET << std::endl;
os << osgDB::PROPERTY("Position") << pt.getPosition() << std::endl;
os << osgDB::PROPERTY("Rotation") << pt.getRotation() << std::endl;
os << osgDB::PROPERTY("Scale") << pt.getScale() << std::endl;
os << osgDB::END_BRACKET << std::endl;
}
os << osgDB::END_BRACKET;
}
os << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( AnimationPath,
new osg::AnimationPath,
osg::AnimationPath,
"osg::Object osg::AnimationPath" )
{
ADD_USER_SERIALIZER( TimeControlPointMap ); // _timeControlPointMap
BEGIN_ENUM_SERIALIZER( LoopMode, NO_LOOPING );
ADD_ENUM_VALUE( SWING );
ADD_ENUM_VALUE( LOOP );
ADD_ENUM_VALUE( NO_LOOPING );
END_ENUM_SERIALIZER(); //_loopMode
}
#undef OBJECT_CAST
#define OBJECT_CAST static_cast

View File

@@ -0,0 +1,23 @@
#undef OBJECT_CAST
#define OBJECT_CAST dynamic_cast
#include <osg/AnimationPath>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( AnimationPathCallback,
new osg::AnimationPathCallback,
osg::AnimationPathCallback,
"osg::Object osg::NodeCallback osg::AnimationPathCallback" )
{
ADD_OBJECT_SERIALIZER( AnimationPath, osg::AnimationPath, NULL ); // _animationPath
ADD_VEC3D_SERIALIZER( PivotPoint, osg::Vec3d() ); // _pivotPoint
ADD_BOOL_SERIALIZER( UseInverseMatrix, false ); // _useInverseMatrix
ADD_DOUBLE_SERIALIZER( TimeOffset, 0.0 ); // _timeOffset
ADD_DOUBLE_SERIALIZER( TimeMultiplier, 1.0 ); // _timeMultiplier
ADD_BOOL_SERIALIZER( Pause, false ); // _pause
}
#undef OBJECT_CAST
#define OBJECT_CAST static_cast

View File

@@ -0,0 +1,11 @@
#include <osg/AudioStream>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( AudioSink,
/*new osg::AudioSink*/NULL,
osg::AudioSink,
"osg::Object osg::AudioSink" )
{
}

View File

@@ -0,0 +1,11 @@
#include <osg/AudioStream>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( AudioStream,
/*new osg::AudioStream*/NULL,
osg::AudioStream,
"osg::Object osg::AudioStream" )
{
}

View File

@@ -0,0 +1,27 @@
#include <osg/AutoTransform>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( AutoTransform,
new osg::AutoTransform,
osg::AutoTransform,
"osg::Object osg::Node osg::Group osg::Transform osg::AutoTransform" )
{
ADD_DOUBLE_SERIALIZER( MinimumScale, 0.0 ); // _minimumScale
ADD_DOUBLE_SERIALIZER( MaximumScale, 0.0 ); // _maximumScale
ADD_VEC3D_SERIALIZER( Position, osg::Vec3d() ); // _position
ADD_VEC3D_SERIALIZER( Scale, osg::Vec3d() ); // _scale
ADD_VEC3D_SERIALIZER( PivotPoint, osg::Vec3d() ); // _pivotPoint
ADD_FLOAT_SERIALIZER( AutoUpdateEyeMovementTolerance, 0.0f ); // _autoUpdateEyeMovementTolerance
BEGIN_ENUM_SERIALIZER( AutoRotateMode, NO_ROTATION );
ADD_ENUM_VALUE( NO_ROTATION );
ADD_ENUM_VALUE( ROTATE_TO_SCREEN );
ADD_ENUM_VALUE( ROTATE_TO_CAMERA );
END_ENUM_SERIALIZER(); // _autoRotateMode
ADD_BOOL_SERIALIZER( AutoScaleToScreen, false ); // _autoScaleToScreen
ADD_QUAT_SERIALIZER( Rotation, osg::Quat() ); // _rotation
ADD_FLOAT_SERIALIZER( AutoScaleTransitionWidthRatio, 0.25f ); // _autoScaleTransitionWidthRatio
}

View File

@@ -0,0 +1,50 @@
#include <osg/Billboard>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkPositionList( const osg::Billboard& node )
{
return node.getPositionList().size()>0;
}
static bool readPositionList( osgDB::InputStream& is, osg::Billboard& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Vec3d pos; is >> pos;
node.setPosition( i, pos );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writePositionList( osgDB::OutputStream& os, const osg::Billboard& node )
{
const osg::Billboard::PositionList& posList = node.getPositionList();
os << posList.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::Billboard::PositionList::const_iterator itr=posList.begin();
itr!=posList.end(); ++itr )
{
os << osg::Vec3d(*itr) << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Billboard,
new osg::Billboard,
osg::Billboard,
"osg::Object osg::Node osg::Geode osg::Billboard" )
{
BEGIN_ENUM_SERIALIZER( Mode, AXIAL_ROT );
ADD_ENUM_VALUE( POINT_ROT_EYE );
ADD_ENUM_VALUE( POINT_ROT_WORLD );
ADD_ENUM_VALUE( AXIAL_ROT );
END_ENUM_SERIALIZER(); // _mode
ADD_VEC3_SERIALIZER( Axis, osg::Vec3f() ); // _axis
ADD_VEC3_SERIALIZER( Normal, osg::Vec3f() ); // _normal
ADD_USER_SERIALIZER( PositionList ); // _positionList
}

View File

@@ -0,0 +1,12 @@
#include <osg/BlendColor>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( BlendColor,
new osg::BlendColor,
osg::BlendColor,
"osg::Object osg::StateAttribute osg::BlendColor" )
{
ADD_VEC4_SERIALIZER( ConstantColor, osg::Vec4() ); // _constantColor
}

View File

@@ -0,0 +1,32 @@
#include <osg/BlendEquation>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( BlendEquation,
new osg::BlendEquation,
osg::BlendEquation,
"osg::Object osg::StateAttribute osg::BlendEquation" )
{
BEGIN_ENUM_SERIALIZER2( EquationRGB, osg::BlendEquation::Equation, FUNC_ADD );
ADD_ENUM_VALUE( RGBA_MIN );
ADD_ENUM_VALUE( RGBA_MAX );
ADD_ENUM_VALUE( ALPHA_MIN );
ADD_ENUM_VALUE( ALPHA_MAX );
ADD_ENUM_VALUE( LOGIC_OP );
ADD_ENUM_VALUE( FUNC_ADD );
ADD_ENUM_VALUE( FUNC_SUBTRACT );
ADD_ENUM_VALUE( FUNC_REVERSE_SUBTRACT );
END_ENUM_SERIALIZER(); // _equationRGB
BEGIN_ENUM_SERIALIZER2( EquationAlpha, osg::BlendEquation::Equation, FUNC_ADD );
ADD_ENUM_VALUE( RGBA_MIN );
ADD_ENUM_VALUE( RGBA_MAX );
ADD_ENUM_VALUE( ALPHA_MIN );
ADD_ENUM_VALUE( ALPHA_MAX );
ADD_ENUM_VALUE( LOGIC_OP );
ADD_ENUM_VALUE( FUNC_ADD );
ADD_ENUM_VALUE( FUNC_SUBTRACT );
ADD_ENUM_VALUE( FUNC_REVERSE_SUBTRACT );
END_ENUM_SERIALIZER(); // _equationAlpha
}

View File

@@ -0,0 +1,15 @@
#include <osg/BlendFunc>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( BlendFunc,
new osg::BlendFunc,
osg::BlendFunc,
"osg::Object osg::StateAttribute osg::BlendFunc" )
{
ADD_GLENUM_SERIALIZER( SourceRGB, GLenum, GL_ONE ); // _source_factor
ADD_GLENUM_SERIALIZER( SourceAlpha, GLenum, GL_ONE ); // _source_factor_alpha
ADD_GLENUM_SERIALIZER( DestinationRGB, GLenum, GL_ONE ); // _destination_factor
ADD_GLENUM_SERIALIZER( DestinationAlpha, GLenum, GL_ONE ); // _destination_factor_alpha
}

View File

@@ -0,0 +1,14 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Box,
new osg::Box,
osg::Box,
"osg::Object osg::Shape osg::Box" )
{
ADD_VEC3_SERIALIZER( Center, osg::Vec3() ); // _center
ADD_VEC3_SERIALIZER( HalfLengths, osg::Vec3() ); // _halfLengths
ADD_QUAT_SERIALIZER( Rotation, osg::Quat() ); // _rotation
}

View File

@@ -0,0 +1,5 @@
FILE(GLOB TARGET_SRC *.cpp)
FILE(GLOB TARGET_H *.h)
#### end var setup ###
SETUP_PLUGIN(osg)

View File

@@ -0,0 +1,271 @@
#include <osg/Camera>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
BEGIN_USER_TABLE( RenderOrder, osg::Camera );
ADD_USER_VALUE( PRE_RENDER );
ADD_USER_VALUE( NESTED_RENDER );
ADD_USER_VALUE( POST_RENDER );
END_USER_TABLE()
USER_READ_FUNC( RenderOrder, readOrderValue )
USER_WRITE_FUNC( RenderOrder, writeOrderValue )
BEGIN_USER_TABLE( BufferComponent, osg::Camera );
ADD_USER_VALUE( DEPTH_BUFFER );
ADD_USER_VALUE( STENCIL_BUFFER );
ADD_USER_VALUE( PACKED_DEPTH_STENCIL_BUFFER );
ADD_USER_VALUE( COLOR_BUFFER );
ADD_USER_VALUE( COLOR_BUFFER0 );
ADD_USER_VALUE( COLOR_BUFFER1 );
ADD_USER_VALUE( COLOR_BUFFER2 );
ADD_USER_VALUE( COLOR_BUFFER3 );
ADD_USER_VALUE( COLOR_BUFFER4 );
ADD_USER_VALUE( COLOR_BUFFER5 );
ADD_USER_VALUE( COLOR_BUFFER6 );
ADD_USER_VALUE( COLOR_BUFFER7 );
ADD_USER_VALUE( COLOR_BUFFER8 );
ADD_USER_VALUE( COLOR_BUFFER9 );
ADD_USER_VALUE( COLOR_BUFFER10 );
ADD_USER_VALUE( COLOR_BUFFER11 );
ADD_USER_VALUE( COLOR_BUFFER12 );
ADD_USER_VALUE( COLOR_BUFFER13 );
ADD_USER_VALUE( COLOR_BUFFER14 );
ADD_USER_VALUE( COLOR_BUFFER15 );
END_USER_TABLE()
USER_READ_FUNC( BufferComponent, readBufferComponent )
USER_WRITE_FUNC( BufferComponent, writeBufferComponent )
static osg::Camera::Attachment readBufferAttachment( osgDB::InputStream& is )
{
osg::Camera::Attachment attachment;
char type = -1; is >> osgDB::PROPERTY("Type") >> type;
if ( type==0 )
{
is >> osgDB::PROPERTY("InternalFormat") >> attachment._internalFormat;
return attachment;
}
else if ( type==1 )
{
is >> osgDB::PROPERTY("Image");
attachment._image = dynamic_cast<osg::Image*>( is.readObject() );
}
else if ( type==2 )
{
is >> osgDB::PROPERTY("Texture");
attachment._texture = dynamic_cast<osg::Texture*>( is.readObject() );
is >> osgDB::PROPERTY("Level") >> attachment._level;
is >> osgDB::PROPERTY("Face") >> attachment._face;
is >> osgDB::PROPERTY("MipMapGeneration") >> attachment._mipMapGeneration;
}
else
return attachment;
is >> osgDB::PROPERTY("MultisampleSamples") >> attachment._multisampleSamples;
is >> osgDB::PROPERTY("MultisampleColorSamples") >> attachment._multisampleColorSamples;
return attachment;
}
static void writeBufferAttachment( osgDB::OutputStream& os, const osg::Camera::Attachment& attachment )
{
os << osgDB::PROPERTY("Type");
if ( attachment._internalFormat!=GL_NONE )
{
os << (char)0 << std::endl;
os << osgDB::PROPERTY("InternalFormat") << GLENUM(attachment._internalFormat) << std::endl;
return;
}
else if ( attachment._image.valid() )
{
os << (char)1 << std::endl;
os << osgDB::PROPERTY("Image") << attachment._image.get();
}
else if ( attachment._texture.valid() )
{
os << (char)2 << std::endl;
os << osgDB::PROPERTY("Texture") << attachment._texture.get();
os << osgDB::PROPERTY("Level") << attachment._level << std::endl;
os << osgDB::PROPERTY("Face") << attachment._face << std::endl;
os << osgDB::PROPERTY("MipMapGeneration") << attachment._mipMapGeneration << std::endl;
}
else
{
os << (char)-1 << std::endl;
return;
}
os << osgDB::PROPERTY("MultisampleSamples") << attachment._multisampleSamples << std::endl;
os << osgDB::PROPERTY("MultisampleColorSamples") << attachment._multisampleColorSamples << std::endl;
}
// _clearMask
static bool checkClearMask( const osg::Camera& node )
{
return node.getClearMask()!=(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}
static bool readClearMask( osgDB::InputStream& is, osg::Camera& node )
{
GLbitfield mask = 0;
if ( is.isBinary() )
{
int maskValue; is >> maskValue;
mask = (GLbitfield)maskValue;
}
else
{
std::string maskSetString; is >> maskSetString;
osgDB::StringList maskList; osgDB::split( maskSetString, maskList, '|' );
for ( unsigned int i=0; i<maskList.size(); ++i )
{
const std::string& maskValue = maskList[i];
if ( maskValue=="COLOR" ) mask |= GL_COLOR_BUFFER_BIT;
else if ( maskValue=="DEPTH" ) mask |= GL_DEPTH_BUFFER_BIT;
else if ( maskValue=="ACCUM" ) mask |= GL_ACCUM_BUFFER_BIT;
else if ( maskValue=="STENCIL" ) mask |= GL_STENCIL_BUFFER_BIT;
}
}
node.setClearMask( mask );
return true;
}
static bool writeClearMask( osgDB::OutputStream& os, const osg::Camera& node )
{
GLbitfield mask = node.getClearMask();
if ( os.isBinary() )
os << (int)mask;
else
{
std::string maskString;
if ( mask==GL_COLOR_BUFFER_BIT ) maskString += std::string("COLOR|");
if ( mask==GL_DEPTH_BUFFER_BIT ) maskString += std::string("DEPTH|");
if ( mask==GL_ACCUM_BUFFER_BIT ) maskString += std::string("ACCUM|");
if ( mask==GL_STENCIL_BUFFER_BIT ) maskString += std::string("STENCIL|");
if ( !maskString.size() ) maskString = std::string("NONE|");
os << maskString.substr(0, maskString.size()-1) << std::endl;
}
return true;
}
// _renderOrder & _renderOrderNum
static bool checkRenderOrder( const osg::Camera& node )
{
return true;
}
static bool readRenderOrder( osgDB::InputStream& is, osg::Camera& node )
{
int order = readOrderValue(is);
int orderNumber = 0; is >> orderNumber;
node.setRenderOrder( static_cast<osg::Camera::RenderOrder>(order), orderNumber );
return true;
}
static bool writeRenderOrder( osgDB::OutputStream& os, const osg::Camera& node )
{
writeOrderValue( os, (int)node.getRenderOrder() );
os << node.getRenderOrderNum() << std::endl;
return true;
}
// _bufferAttachmentMap
static bool checkBufferAttachmentMap( const osg::Camera& node )
{
return node.getBufferAttachmentMap().size()>0;
}
static bool readBufferAttachmentMap( osgDB::InputStream& is, osg::Camera& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
is >> osgDB::PROPERTY("Attachment");
osg::Camera::BufferComponent bufferComponent =
static_cast<osg::Camera::BufferComponent>( readBufferComponent(is) );
is >> osgDB::BEGIN_BRACKET;
osg::Camera::Attachment attachment = readBufferAttachment(is);
is >> osgDB::END_BRACKET;
if ( attachment._internalFormat!=GL_NONE )
{
node.attach( bufferComponent, attachment._internalFormat );
}
else if ( attachment._image.valid() )
{
node.attach( bufferComponent, attachment._image.get(),
attachment._multisampleSamples, attachment._multisampleColorSamples );
}
else if ( attachment._texture.valid() )
{
node.attach( bufferComponent, attachment._texture.get(),
attachment._level, attachment._face, attachment._mipMapGeneration,
attachment._multisampleSamples, attachment._multisampleColorSamples );
}
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeBufferAttachmentMap( osgDB::OutputStream& os, const osg::Camera& node )
{
const osg::Camera::BufferAttachmentMap& map = node.getBufferAttachmentMap();
os << map.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::Camera::BufferAttachmentMap::const_iterator itr=map.begin();
itr!=map.end(); ++itr )
{
os << osgDB::PROPERTY("Attachment"); writeBufferComponent( os, itr->first );
os << osgDB::BEGIN_BRACKET << std::endl;
writeBufferAttachment( os, itr->second );
os << osgDB::END_BRACKET << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Camera,
new osg::Camera,
osg::Camera,
"osg::Object osg::Node osg::Group osg::Transform osg::Camera" )
{
ADD_BOOL_SERIALIZER( AllowEventFocus, true ); // _allowEventFocus
ADD_USER_SERIALIZER( ClearMask ); // _clearMask
ADD_VEC4_SERIALIZER( ClearColor, osg::Vec4() ); // _clearColor
ADD_VEC4_SERIALIZER( ClearAccum, osg::Vec4() ); // _clearAccum
ADD_DOUBLE_SERIALIZER( ClearDepth, 1.0 ); // _clearDepth
ADD_INT_SERIALIZER( ClearStencil, 0 ); // _clearStencil
ADD_OBJECT_SERIALIZER( ColorMask, osg::ColorMask, NULL ); // _colorMask
ADD_OBJECT_SERIALIZER( Viewport, osg::Viewport, NULL ); // _viewport
BEGIN_ENUM_SERIALIZER( TransformOrder, PRE_MULTIPLY );
ADD_ENUM_VALUE( PRE_MULTIPLY );
ADD_ENUM_VALUE( POST_MULTIPLY );
END_ENUM_SERIALIZER(); // _transformOrder
BEGIN_ENUM_SERIALIZER( ProjectionResizePolicy, HORIZONTAL );
ADD_ENUM_VALUE( FIXED );
ADD_ENUM_VALUE( HORIZONTAL );
ADD_ENUM_VALUE( VERTICAL );
END_ENUM_SERIALIZER(); // _projectionResizePolicy
ADD_MATRIXD_SERIALIZER( ProjectionMatrix, osg::Matrixd() ); // _projectionMatrix
ADD_MATRIXD_SERIALIZER( ViewMatrix, osg::Matrixd() ); // _viewMatrix
ADD_USER_SERIALIZER( RenderOrder ); // _renderOrder & _renderOrderNum
ADD_GLENUM_SERIALIZER( DrawBuffer, GLenum, GL_NONE ); // _drawBuffer
ADD_GLENUM_SERIALIZER( ReadBuffer, GLenum, GL_NONE ); // _readBuffer
BEGIN_ENUM_SERIALIZER( RenderTargetImplementation, FRAME_BUFFER );
ADD_ENUM_VALUE( FRAME_BUFFER_OBJECT );
ADD_ENUM_VALUE( PIXEL_BUFFER_RTT );
ADD_ENUM_VALUE( PIXEL_BUFFER );
ADD_ENUM_VALUE( FRAME_BUFFER );
ADD_ENUM_VALUE( SEPERATE_WINDOW );
END_ENUM_SERIALIZER(); // _renderTargetImplementation
ADD_USER_SERIALIZER( BufferAttachmentMap ); // _bufferAttachmentMap
ADD_OBJECT_SERIALIZER( InitialDrawCallback, osg::Camera::DrawCallback, NULL ); // _initialDrawCallback
ADD_OBJECT_SERIALIZER( PreDrawCallback, osg::Camera::DrawCallback, NULL ); // _preDrawCallback
ADD_OBJECT_SERIALIZER( PostDrawCallback, osg::Camera::DrawCallback, NULL ); // _postDrawCallback
ADD_OBJECT_SERIALIZER( FinalDrawCallback, osg::Camera::DrawCallback, NULL ); // _finalDrawCallback
}

View File

@@ -0,0 +1,22 @@
#include <osg/CameraView>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( CameraView,
new osg::CameraView,
osg::CameraView,
"osg::Object osg::Node osg::Group osg::Transform osg::CameraView" )
{
ADD_VEC3D_SERIALIZER( Position, osg::Vec3d() ); // _position
ADD_QUAT_SERIALIZER( Attitude, osg::Quat() ); // _attitude
ADD_DOUBLE_SERIALIZER( FieldOfView, 60.0 ); // _fieldOfView
BEGIN_ENUM_SERIALIZER( FieldOfViewMode, VERTICAL );
ADD_ENUM_VALUE( UNCONSTRAINED );
ADD_ENUM_VALUE( HORIZONTAL );
ADD_ENUM_VALUE( VERTICAL );
END_ENUM_SERIALIZER(); // _fieldOfViewMode
ADD_DOUBLE_SERIALIZER( FocalLength, 0.0 ); // _focalLength
}

View File

@@ -0,0 +1,15 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Capsule,
new osg::Capsule,
osg::Capsule,
"osg::Object osg::Shape osg::Capsule" )
{
ADD_VEC3_SERIALIZER( Center, osg::Vec3() ); // _center
ADD_FLOAT_SERIALIZER( Radius, 0.0f ); // _radius
ADD_FLOAT_SERIALIZER( Height, 0.0f ); // _height
ADD_QUAT_SERIALIZER( Rotation, osg::Quat() ); // _rotation
}

View File

@@ -0,0 +1,14 @@
#include <osg/ClampColor>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ClampColor,
new osg::ClampColor,
osg::ClampColor,
"osg::Object osg::StateAttribute osg::ClampColor" )
{
ADD_GLENUM_SERIALIZER( ClampVertexColor, GLenum, GL_FIXED_ONLY ); // _clampVertexColor
ADD_GLENUM_SERIALIZER( ClampFragmentColor, GLenum, GL_FIXED_ONLY ); // _clampFragmentColor
ADD_GLENUM_SERIALIZER( ClampReadColor, GLenum, GL_FIXED_ONLY ); // _clampReadColor
}

View File

@@ -0,0 +1,63 @@
#include <osg/ClearNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _clearMask
static bool checkClearMask( const osg::ClearNode& node )
{
return node.getClearMask()!=(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}
static bool readClearMask( osgDB::InputStream& is, osg::ClearNode& node )
{
GLbitfield mask = GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
if ( is.isBinary() )
{
int maskValue; is >> maskValue;
mask = (GLbitfield)maskValue;
}
else
{
std::string maskSetString; is >> maskSetString;
osgDB::StringList maskList; osgDB::split( maskSetString, maskList, '|' );
for ( unsigned int i=0; i<maskList.size(); ++i )
{
const std::string& maskValue = maskList[i];
if ( maskValue=="COLOR" ) mask |= GL_COLOR_BUFFER_BIT;
else if ( maskValue=="DEPTH" ) mask |= GL_DEPTH_BUFFER_BIT;
else if ( maskValue=="ACCUM" ) mask |= GL_ACCUM_BUFFER_BIT;
else if ( maskValue=="STENCIL" ) mask |= GL_STENCIL_BUFFER_BIT;
}
}
node.setClearMask( mask );
return true;
}
static bool writeClearMask( osgDB::OutputStream& os, const osg::ClearNode& node )
{
GLbitfield mask = node.getClearMask();
if ( os.isBinary() )
os << (int)mask;
else
{
std::string maskString;
if ( mask==GL_COLOR_BUFFER_BIT ) maskString += std::string("COLOR|");
if ( mask==GL_DEPTH_BUFFER_BIT ) maskString += std::string("DEPTH|");
if ( mask==GL_ACCUM_BUFFER_BIT ) maskString += std::string("ACCUM|");
if ( mask==GL_STENCIL_BUFFER_BIT ) maskString += std::string("STENCIL|");
if ( !maskString.size() ) maskString = std::string("NONE|");
os << maskString.substr(0, maskString.size()-1) << std::endl;
}
return true;
}
REGISTER_OBJECT_WRAPPER( ClearNode,
new osg::ClearNode,
osg::ClearNode,
"osg::Object osg::Node osg::Group osg::ClearNode" )
{
ADD_BOOL_SERIALIZER( RequiresClear, true ); // _requiresClear
ADD_VEC4_SERIALIZER( ClearColor, osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f) ); // _clearColor
ADD_USER_SERIALIZER( ClearMask ); // _clearMask
}

View File

@@ -0,0 +1,17 @@
#include <osg/ClipNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ClipNode,
new osg::ClipNode,
osg::ClipNode,
"osg::Object osg::Node osg::Group osg::ClipNode" )
{
ADD_LIST_SERIALIZER( ClipPlaneList, osg::ClipNode::ClipPlaneList ); // _planes
BEGIN_ENUM_SERIALIZER( ReferenceFrame, RELATIVE_RF );
ADD_ENUM_VALUE( RELATIVE_RF );
ADD_ENUM_VALUE( ABSOLUTE_RF );
END_ENUM_SERIALIZER(); // _referenceFrame
}

View File

@@ -0,0 +1,13 @@
#include <osg/ClipPlane>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ClipPlane,
new osg::ClipPlane,
osg::ClipPlane,
"osg::Object osg::StateAttribute osg::ClipPlane" )
{
ADD_VEC4D_SERIALIZER( ClipPlane, osg::Vec4d() ); // _clipPlane
ADD_UINT_SERIALIZER( ClipPlaneNum, 0 ); // _clipPlaneNum
}

View File

@@ -0,0 +1,21 @@
#undef OBJECT_CAST
#define OBJECT_CAST dynamic_cast
#include <osg/ClusterCullingCallback>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ClusterCullingCallback,
new osg::ClusterCullingCallback,
osg::ClusterCullingCallback,
"osg::Object osg::NodeCallback osg::ClusterCullingCallback" )
{
ADD_VEC3_SERIALIZER( ControlPoint, osg::Vec3() ); // _controlPoint
ADD_VEC3_SERIALIZER( Normal, osg::Vec3() ); // _normal
ADD_FLOAT_SERIALIZER( Radius, -1.0f ); // _radius
ADD_FLOAT_SERIALIZER( Deviation, -1.0f ); // _deviation
}
#undef OBJECT_CAST
#define OBJECT_CAST static_cast

View File

@@ -0,0 +1,15 @@
#include <osg/ColorMask>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ColorMask,
new osg::ColorMask,
osg::ColorMask,
"osg::Object osg::StateAttribute osg::ColorMask" )
{
ADD_BOOL_SERIALIZER( RedMask, true ); // _red
ADD_BOOL_SERIALIZER( GreenMask, true ); // _green
ADD_BOOL_SERIALIZER( BlueMask, true ); // _blue
ADD_BOOL_SERIALIZER( AlphaMask, true ); // _alpha
}

View File

@@ -0,0 +1,12 @@
#include <osg/ColorMatrix>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ColorMatrix,
new osg::ColorMatrix,
osg::ColorMatrix,
"osg::Object osg::StateAttribute osg::ColorMatrix" )
{
ADD_MATRIX_SERIALIZER( Matrix, osg::Matrix() ); // _matrix
}

View File

@@ -0,0 +1,42 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkChildren( const osg::CompositeShape& shape )
{
return shape.getNumChildren()>0;
}
static bool readChildren( osgDB::InputStream& is, osg::CompositeShape& shape )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Shape* child = dynamic_cast<osg::Shape*>( is.readObject() );
if ( child ) shape.addChild( child );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeChildren( osgDB::OutputStream& os, const osg::CompositeShape& shape )
{
unsigned int size = shape.getNumChildren();
os << size << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<size; ++i )
{
os << shape.getChild(i);
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( CompositeShape,
new osg::CompositeShape,
osg::CompositeShape,
"osg::Object osg::Shape osg::CompositeShape" )
{
ADD_OBJECT_SERIALIZER( Shape, osg::Shape, NULL ); // _shape
ADD_USER_SERIALIZER( Children ); //_children
}

View File

@@ -0,0 +1,15 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Cone,
new osg::Cone,
osg::Cone,
"osg::Object osg::Shape osg::Cone" )
{
ADD_VEC3_SERIALIZER( Center, osg::Vec3() ); // _center
ADD_FLOAT_SERIALIZER( Radius, 0.0f ); // _radius
ADD_FLOAT_SERIALIZER( Height, 0.0f ); // _height
ADD_QUAT_SERIALIZER( Rotation, osg::Quat() ); // _rotation
}

View File

@@ -0,0 +1,11 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ConvexHull,
new osg::ConvexHull,
osg::ConvexHull,
"osg::Object osg::Shape osg::TriangleMesh osg::ConvexHull" )
{
}

View File

@@ -0,0 +1,90 @@
#include <osg/ConvexPlanarOccluder>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static void readConvexPlanarPolygon( osgDB::InputStream& is, osg::ConvexPlanarPolygon& polygon )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Vec3d vertex; is >> vertex;
polygon.add( vertex );
}
is >> osgDB::END_BRACKET;
}
static void writeConvexPlanarPolygon( osgDB::OutputStream& os, const osg::ConvexPlanarPolygon& polygon )
{
const osg::ConvexPlanarPolygon::VertexList& vertices = polygon.getVertexList();
os << vertices.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::ConvexPlanarPolygon::VertexList::const_iterator itr=vertices.begin();
itr!=vertices.end(); ++itr )
{
os << osg::Vec3d(*itr) << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
}
// _occluder
static bool checkOccluder( const osg::ConvexPlanarOccluder& obj )
{
return obj.getOccluder().getVertexList().size()>0;
}
static bool readOccluder( osgDB::InputStream& is, osg::ConvexPlanarOccluder& obj )
{
osg::ConvexPlanarPolygon polygon;
readConvexPlanarPolygon( is, polygon );
obj.setOccluder( polygon );
return true;
}
static bool writeOccluder( osgDB::OutputStream& os, const osg::ConvexPlanarOccluder& obj )
{
writeConvexPlanarPolygon( os, obj.getOccluder() );
return true;
}
// _holeList
static bool checkHoles( const osg::ConvexPlanarOccluder& obj )
{
return obj.getHoleList().size()>0;
}
static bool readHoles( osgDB::InputStream& is, osg::ConvexPlanarOccluder& obj )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::ConvexPlanarPolygon polygon;
is >> osgDB::PROPERTY("Polygon");
readConvexPlanarPolygon( is, polygon );
obj.addHole( polygon );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeHoles( osgDB::OutputStream& os, const osg::ConvexPlanarOccluder& obj )
{
const osg::ConvexPlanarOccluder::HoleList& holes = obj.getHoleList();
os << holes.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::ConvexPlanarOccluder::HoleList::const_iterator itr=holes.begin();
itr!=holes.end(); ++itr )
{
os << osgDB::PROPERTY("Polygon");
writeConvexPlanarPolygon( os, *itr );
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( ConvexPlanarOccluder,
new osg::ConvexPlanarOccluder,
osg::ConvexPlanarOccluder,
"osg::Object osg::ConvexPlanarOccluder" )
{
ADD_USER_SERIALIZER( Occluder ); // _occluder
ADD_USER_SERIALIZER( Holes ); // _holeList
}

View File

@@ -0,0 +1,14 @@
#include <osg/CoordinateSystemNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( CoordinateSystemNode,
new osg::CoordinateSystemNode,
osg::CoordinateSystemNode,
"osg::Object osg::Node osg::Group osg::CoordinateSystemNode" )
{
ADD_STRING_SERIALIZER( Format, "" ); // _format
ADD_STRING_SERIALIZER( CoordinateSystem, "" ); // _cs
ADD_OBJECT_SERIALIZER( EllipsoidModel, osg::EllipsoidModel, NULL ); // _ellipsoidModel
}

View File

@@ -0,0 +1,16 @@
#include <osg/CullFace>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( CullFace,
new osg::CullFace,
osg::CullFace,
"osg::Object osg::StateAttribute osg::CullFace" )
{
BEGIN_ENUM_SERIALIZER( Mode, BACK );
ADD_ENUM_VALUE( FRONT );
ADD_ENUM_VALUE( BACK );
ADD_ENUM_VALUE( FRONT_AND_BACK );
END_ENUM_SERIALIZER(); // _mode
}

View File

@@ -0,0 +1,15 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Cylinder,
new osg::Cylinder,
osg::Cylinder,
"osg::Object osg::Shape osg::Cylinder" )
{
ADD_VEC3_SERIALIZER( Center, osg::Vec3() ); // _center
ADD_FLOAT_SERIALIZER( Radius, 0.0f ); // _radius
ADD_FLOAT_SERIALIZER( Height, 0.0f ); // _height
ADD_QUAT_SERIALIZER( Rotation, osg::Quat() ); // _rotation
}

View File

@@ -0,0 +1,25 @@
#include <osg/Depth>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Depth,
new osg::Depth,
osg::Depth,
"osg::Object osg::StateAttribute osg::Depth" )
{
BEGIN_ENUM_SERIALIZER( Function, LESS );
ADD_ENUM_VALUE( NEVER );
ADD_ENUM_VALUE( LESS );
ADD_ENUM_VALUE( EQUAL );
ADD_ENUM_VALUE( LEQUAL );
ADD_ENUM_VALUE( GREATER );
ADD_ENUM_VALUE( NOTEQUAL );
ADD_ENUM_VALUE( GEQUAL );
ADD_ENUM_VALUE( ALWAYS );
END_ENUM_SERIALIZER(); // _func
ADD_DOUBLE_SERIALIZER( ZNear, 0.0 ); // _zNear
ADD_DOUBLE_SERIALIZER( ZFar, 1.0 ); // _zFar
ADD_BOOL_SERIALIZER( WriteMask, true ); // _depthWriteMask
}

View File

@@ -0,0 +1,36 @@
#include <osg/DrawPixels>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkArea( const osg::DrawPixels& drawable )
{
return drawable.getUseSubImage();
}
static bool readArea( osgDB::InputStream& is, osg::DrawPixels& drawable )
{
unsigned int x, y, w, h;
is >> x >> y >> w >> h;
drawable.setSubImageDimensions( x, y, w, h );
return true;
}
static bool writeArea( osgDB::OutputStream& os, const osg::DrawPixels& drawable )
{
unsigned int x, y, w, h;
drawable.getSubImageDimensions( x, y, w, h );
os << x << y << w << h << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( DrawPixels,
new osg::DrawPixels,
osg::DrawPixels,
"osg::Object osg::Drawable osg::DrawPixels" )
{
ADD_VEC3_SERIALIZER( Position, osg::Vec3() ); // _position
ADD_IMAGE_SERIALIZER( Image, osg::Image, NULL ); // _image
ADD_BOOL_SERIALIZER( UseSubImage, false ); // _useSubImage
ADD_USER_SERIALIZER( Area ); // _offsetX, _offsetY, _width, _height
}

View File

@@ -0,0 +1,56 @@
#include <osg/Drawable>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkInitialBound( const osg::Drawable& drawable )
{
return drawable.getInitialBound().valid();
}
static bool readInitialBound( osgDB::InputStream& is, osg::Drawable& drawable )
{
bool valid = false; is >> valid;
if ( valid )
{
osg::Vec3d min, max;
is >> osgDB::BEGIN_BRACKET >> osgDB::PROPERTY("Minimum") >> min;
is >> osgDB::PROPERTY("Maximum") >> max >> osgDB::END_BRACKET;
drawable.setInitialBound( osg::BoundingBox(min, max) );
}
return true;
}
static bool writeInitialBound( osgDB::OutputStream& os, const osg::Drawable& drawable )
{
const osg::BoundingBox& bb = drawable.getInitialBound();
os << bb.valid();
if ( bb.valid() )
{
os << osgDB::BEGIN_BRACKET << std::endl;
os << osgDB::PROPERTY("Minimum") << osg::Vec3d(bb._min) << std::endl;
os << osgDB::PROPERTY("Maximum") << osg::Vec3d(bb._max) << std::endl;
os << osgDB::END_BRACKET;
}
os << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Drawable,
/*new osg::Drawable*/NULL,
osg::Drawable,
"osg::Object osg::Drawable" )
{
ADD_OBJECT_SERIALIZER( StateSet, osg::StateSet, NULL ); // _stateset
ADD_USER_SERIALIZER( InitialBound ); // _initialBound
ADD_OBJECT_SERIALIZER( ComputeBoundingBoxCallback,
osg::Drawable::ComputeBoundingBoxCallback, NULL ); // _computeBoundCallback
ADD_OBJECT_SERIALIZER( Shape, osg::Shape, NULL ); // _shape
ADD_BOOL_SERIALIZER( SupportsDisplayList, true ); // _supportsDisplayList
ADD_BOOL_SERIALIZER( UseDisplayList, true ); // _useDisplayList
ADD_BOOL_SERIALIZER( UseVertexBufferObjects, false ); // _useVertexBufferObjects
ADD_OBJECT_SERIALIZER( UpdateCallback, osg::Drawable::UpdateCallback, NULL ); // _updateCallback
ADD_OBJECT_SERIALIZER( EventCallback, osg::Drawable::EventCallback, NULL ); // _eventCallback
ADD_OBJECT_SERIALIZER( CullCallback, osg::Drawable::CullCallback, NULL ); // _cullCallback
ADD_OBJECT_SERIALIZER( DrawCallback, osg::Drawable::DrawCallback, NULL ); // _drawCallback
}

View File

@@ -0,0 +1,13 @@
#include <osg/CoordinateSystemNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( EllipsoidModel,
new osg::EllipsoidModel,
osg::EllipsoidModel,
"osg::Object osg::EllipsoidModel" )
{
ADD_DOUBLE_SERIALIZER( RadiusEquator, 0.0 ); // _radiusEquator
ADD_DOUBLE_SERIALIZER( RadiusPolar, 0.0 ); // _radiusPolar
}

View File

@@ -0,0 +1,22 @@
#include <osg/Fog>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Fog,
new osg::Fog,
osg::Fog,
"osg::Object osg::StateAttribute osg::Fog" )
{
BEGIN_ENUM_SERIALIZER( Mode, LINEAR );
ADD_ENUM_VALUE( LINEAR );
ADD_ENUM_VALUE( EXP );
ADD_ENUM_VALUE( EXP2 );
END_ENUM_SERIALIZER(); // _mode
ADD_FLOAT_SERIALIZER( Start, 0.0f ); // _start
ADD_FLOAT_SERIALIZER( End, 1.0f ); // _end
ADD_FLOAT_SERIALIZER( Density, 1.0f ); // _density
ADD_VEC4_SERIALIZER( Color, osg::Vec4() ); // _color
ADD_GLENUM_SERIALIZER( FogCoordinateSource, GLint, GL_NONE ); // _fogCoordinateSource
}

View File

@@ -0,0 +1,78 @@
#include <osg/FragmentProgram>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _programLocalParameters
static bool checkLocalParameters( const osg::FragmentProgram& fp )
{
return fp.getLocalParameters().size()>0;
}
static bool readLocalParameters( osgDB::InputStream& is, osg::FragmentProgram& fp )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
GLuint key; osg::Vec4d value;
is >> key >> value;
fp.setProgramLocalParameter( key, value );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeLocalParameters( osgDB::OutputStream& os, const osg::FragmentProgram& fp )
{
const osg::FragmentProgram::LocalParamList& params = fp.getLocalParameters();
os << params.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::FragmentProgram::LocalParamList::const_iterator itr=params.begin();
itr!=params.end(); ++itr )
{
os << itr->first << osg::Vec4d(itr->second) << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
// _matrixList
static bool checkMatrices( const osg::FragmentProgram& fp )
{
return fp.getMatrices().size()>0;
}
static bool readMatrices( osgDB::InputStream& is, osg::FragmentProgram& fp )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
unsigned int key; osg::Matrixd value;
is >> key >> value;
fp.setMatrix( key, value );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeMatrices( osgDB::OutputStream& os, const osg::FragmentProgram& fp )
{
const osg::FragmentProgram::MatrixList& matrices = fp.getMatrices();
os << matrices.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::FragmentProgram::MatrixList::const_iterator itr=matrices.begin();
itr!=matrices.end(); ++itr )
{
os << (unsigned int)itr->first << osg::Matrixd(itr->second) << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( FragmentProgram,
new osg::FragmentProgram,
osg::FragmentProgram,
"osg::Object osg::StateAttribute osg::FragmentProgram" )
{
ADD_STRING_SERIALIZER( FragmentProgram, "" ); // _fragmentProgram
ADD_USER_SERIALIZER( LocalParameters ); // _programLocalParameters
ADD_USER_SERIALIZER( Matrices ); // _matrixList
}

View File

@@ -0,0 +1,15 @@
#include <osg/FrontFace>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( FrontFace,
new osg::FrontFace,
osg::FrontFace,
"osg::Object osg::StateAttribute osg::FrontFace" )
{
BEGIN_ENUM_SERIALIZER( Mode, COUNTER_CLOCKWISE );
ADD_ENUM_VALUE( CLOCKWISE );
ADD_ENUM_VALUE( COUNTER_CLOCKWISE );
END_ENUM_SERIALIZER(); // _mode
}

View File

@@ -0,0 +1,41 @@
#include <osg/Geode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkDrawables( const osg::Geode& node )
{
return node.getNumDrawables()>0;
}
static bool readDrawables( osgDB::InputStream& is, osg::Geode& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>( is.readObject() );
if ( drawable ) node.addDrawable( drawable );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeDrawables( osgDB::OutputStream& os, const osg::Geode& node )
{
unsigned int size = node.getNumDrawables();
os << size << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<size; ++i )
{
os << node.getDrawable(i);
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Geode,
new osg::Geode,
osg::Geode,
"osg::Object osg::Node osg::Geode" )
{
ADD_USER_SERIALIZER( Drawables ); // _drawables
}

View File

@@ -0,0 +1,115 @@
#include <osg/Geometry>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
BEGIN_USER_TABLE( AttributeBinding, osg::Geometry );
ADD_USER_VALUE( BIND_OFF );
ADD_USER_VALUE( BIND_OVERALL );
ADD_USER_VALUE( BIND_PER_PRIMITIVE_SET );
ADD_USER_VALUE( BIND_PER_PRIMITIVE );
ADD_USER_VALUE( BIND_PER_VERTEX );
END_USER_TABLE()
USER_READ_FUNC( AttributeBinding, readAttributeBinding )
USER_WRITE_FUNC( AttributeBinding, writeAttributeBinding )
static void readArrayData( osgDB::InputStream& is, osg::Geometry::ArrayData& data )
{
bool hasArray = false;
is >> osgDB::PROPERTY("Array") >> hasArray;
if ( hasArray ) data.array = is.readArray();
bool hasIndices = false;
is >> osgDB::PROPERTY("Indices") >> hasIndices;
if ( hasIndices ) data.indices = dynamic_cast<osg::IndexArray*>( is.readArray() );
is >> osgDB::PROPERTY("Binding");
data.binding = (osg::Geometry::AttributeBinding)readAttributeBinding(is);
int normalizeValue = 0;
is >> osgDB::PROPERTY("Normalize") >> normalizeValue;
data.normalize = normalizeValue;
}
static void writeArrayData( osgDB::OutputStream& os, const osg::Geometry::ArrayData& data )
{
os << osgDB::PROPERTY("Array") << data.array.valid();
if ( data.array.valid() ) os << data.array.get();
else os << std::endl;
os << osgDB::PROPERTY("Indices") << data.indices.valid();
if ( data.indices.valid() ) os << data.indices.get();
else os << std::endl;
os << osgDB::PROPERTY("Binding"); writeAttributeBinding(os, data.binding); os << std::endl;
os << osgDB::PROPERTY("Normalize") << (int)data.normalize << std::endl;
}
#define ADD_ARRAYDATA_FUNCTIONS( PROP ) \
static bool check##PROP( const osg::Geometry& geom ) \
{ return geom.get##PROP().array.valid(); } \
static bool read##PROP( osgDB::InputStream& is, osg::Geometry& geom ) { \
osg::Geometry::ArrayData data; \
is >> osgDB::BEGIN_BRACKET; readArrayData(is, data); \
is >> osgDB::END_BRACKET; \
geom.set##PROP(data); \
return true; \
} \
static bool write##PROP( osgDB::OutputStream& os, const osg::Geometry& geom ) { \
os << osgDB::BEGIN_BRACKET << std::endl; \
writeArrayData(os, geom.get##PROP()); \
os << osgDB::END_BRACKET << std::endl; \
return true; \
}
ADD_ARRAYDATA_FUNCTIONS( VertexData )
ADD_ARRAYDATA_FUNCTIONS( NormalData )
ADD_ARRAYDATA_FUNCTIONS( ColorData )
ADD_ARRAYDATA_FUNCTIONS( SecondaryColorData )
ADD_ARRAYDATA_FUNCTIONS( FogCoordData )
#define ADD_ARRAYLIST_FUNCTIONS( PROP, LISTNAME ) \
static bool check##PROP( const osg::Geometry& geom ) \
{ return geom.get##LISTNAME().size()>0; } \
static bool read##PROP( osgDB::InputStream& is, osg::Geometry& geom ) { \
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET; \
for ( unsigned int i=0; i<size; ++i ) { \
osg::Geometry::ArrayData data; \
is >> osgDB::PROPERTY("Data") >> osgDB::BEGIN_BRACKET; \
readArrayData(is, data); \
is >> osgDB::END_BRACKET; geom.set##PROP(i, data); } \
is >> osgDB::END_BRACKET; \
return true; \
} \
static bool write##PROP( osgDB::OutputStream& os, const osg::Geometry& geom ) { \
const osg::Geometry::ArrayDataList& LISTNAME = geom.get##LISTNAME(); \
os << LISTNAME.size() << osgDB::BEGIN_BRACKET << std::endl; \
for ( osg::Geometry::ArrayDataList::const_iterator itr=LISTNAME.begin(); \
itr!=LISTNAME.end(); ++itr ) { \
os << osgDB::PROPERTY("Data") << osgDB::BEGIN_BRACKET << std::endl; \
writeArrayData(os, *itr); os << osgDB::END_BRACKET << std::endl; \
} \
os << osgDB::END_BRACKET << std::endl; \
return true; \
}
ADD_ARRAYLIST_FUNCTIONS( TexCoordData, TexCoordArrayList )
ADD_ARRAYLIST_FUNCTIONS( VertexAttribData, VertexAttribArrayList )
REGISTER_OBJECT_WRAPPER( Geometry,
new osg::Geometry,
osg::Geometry,
"osg::Object osg::Drawable osg::Geometry" )
{
ADD_LIST_SERIALIZER( PrimitiveSetList, osg::Geometry::PrimitiveSetList ); // _primitives
ADD_USER_SERIALIZER( VertexData ); // _vertexData
ADD_USER_SERIALIZER( NormalData ); // _normalData
ADD_USER_SERIALIZER( ColorData ); // _colorData
ADD_USER_SERIALIZER( SecondaryColorData ); // _secondaryColorData
ADD_USER_SERIALIZER( FogCoordData ); // _fogCoordData
ADD_USER_SERIALIZER( TexCoordData ); // _texCoordList
ADD_USER_SERIALIZER( VertexAttribData ); // _vertexAttribList
ADD_BOOL_SERIALIZER( FastPathHint, true ); // _fastPathHint
ADD_OBJECT_SERIALIZER( InternalOptimizedGeometry, osg::Geometry, NULL ); // _internalOptimizedGeometry
}

View File

@@ -0,0 +1,41 @@
#include <osg/Group>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkChildren( const osg::Group& node )
{
return node.getNumChildren()>0;
}
static bool readChildren( osgDB::InputStream& is, osg::Group& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Node* child = dynamic_cast<osg::Node*>( is.readObject() );
if ( child ) node.addChild( child );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeChildren( osgDB::OutputStream& os, const osg::Group& node )
{
unsigned int size = node.getNumChildren();
os << size << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<size; ++i )
{
os << node.getChild(i);
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Group,
new osg::Group,
osg::Group,
"osg::Object osg::Node osg::Group" )
{
ADD_USER_SERIALIZER( Children ); // _children
}

View File

@@ -0,0 +1,73 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _columns, _rows
static bool checkArea( const osg::HeightField& shape )
{
return true;
}
static bool readArea( osgDB::InputStream& is, osg::HeightField& shape )
{
unsigned int numCols, numRows;
is >> numCols >> numRows;
shape.allocate( numCols, numRows );
return true;
}
static bool writeArea( osgDB::OutputStream& os, const osg::HeightField& shape )
{
os << shape.getNumColumns() << shape.getNumRows() << std::endl;
return true;
}
// _heights
static bool checkHeights( const osg::HeightField& shape )
{
return shape.getFloatArray()!=NULL;
}
static bool readHeights( osgDB::InputStream& is, osg::HeightField& shape )
{
bool hasArray; is >> hasArray;
if ( !hasArray ) return true;
osg::FloatArray* array = dynamic_cast<osg::FloatArray*>( is.readArray() );
if ( array )
{
unsigned int numCols = shape.getNumColumns(), numRows = shape.getNumRows();
if ( array->size()<numRows*numCols ) return false;
unsigned int index = 0;
for ( unsigned int r=0; r<numRows; ++r )
{
for ( unsigned int c=0; c<numCols; ++c )
shape.setHeight( c, r, (*array)[index++] );
}
}
return true;
}
static bool writeHeights( osgDB::OutputStream& os, const osg::HeightField& shape )
{
os << (shape.getFloatArray()!=NULL);
os.writeArray( shape.getFloatArray() );
return true;
}
REGISTER_OBJECT_WRAPPER( HeightField,
new osg::HeightField,
osg::HeightField,
"osg::Object osg::Shape osg::HeightField" )
{
ADD_USER_SERIALIZER( Area ); // _columns, _rows
ADD_VEC3_SERIALIZER( Origin, osg::Vec3() ); // _origin
ADD_FLOAT_SERIALIZER( XInterval, 0.0f ); // _dx
ADD_FLOAT_SERIALIZER( YInterval, 0.0f ); // _dy
ADD_FLOAT_SERIALIZER( SkirtHeight, 0.0f ); // _skirtHeight
ADD_UINT_SERIALIZER( BorderWidth, 0 ); // _borderWidth
ADD_QUAT_SERIALIZER( Rotation, osg::Quat() ); // _rotation
ADD_USER_SERIALIZER( Heights ); // _heights
}

View File

@@ -0,0 +1,13 @@
#include <osg/Hint>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Hint,
new osg::Hint,
osg::Hint,
"osg::Object osg::StateAttribute osg::Hint" )
{
ADD_GLENUM_SERIALIZER( Target, GLenum, GL_NONE ); // _target
ADD_GLENUM_SERIALIZER( Mode, GLenum, GL_DONT_CARE ); // _mode
}

View File

@@ -0,0 +1,12 @@
#include <osg/Image>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Image,
new osg::Image,
osg::Image,
"osg::Object osg::Image" )
{
// Everything is done in OutputStream and InputStream classes
}

View File

@@ -0,0 +1,86 @@
#include <osg/ImageSequence>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _fileNames
static bool checkFileNames( const osg::ImageSequence& image )
{
return image.getNumImageFiles()>0;
}
static bool readFileNames( osgDB::InputStream& is, osg::ImageSequence& image )
{
unsigned int files = 0; is >> files >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<files; ++i )
{
std::string filename; is.readWrappedString( filename );
image.addImageFile( filename );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeFileNames( osgDB::OutputStream& os, const osg::ImageSequence& image )
{
const osg::ImageSequence::FileNames& files = image.getFileNames();
os << files.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::ImageSequence::FileNames::const_iterator itr=files.begin();
itr!=files.end(); ++itr )
{
os.writeWrappedString( *itr );
os << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
// _images
static bool checkImages( const osg::ImageSequence& image )
{
return image.getNumImages()>0;
}
static bool readImages( osgDB::InputStream& is, osg::ImageSequence& image )
{
unsigned int images = 0; is >> images >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<images; ++i )
{
osg::Image* img = dynamic_cast<osg::Image*>( is.readObject() );
if ( img ) image.addImage( img );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeImages( osgDB::OutputStream& os, const osg::ImageSequence& image )
{
const osg::ImageSequence::Images& images = image.getImages();
os << images.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::ImageSequence::Images::const_iterator itr=images.begin();
itr!=images.end(); ++itr )
{
os.writeObject( (*itr).get() );
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( ImageSequence,
new osg::ImageSequence,
osg::ImageSequence,
"osg::Object osg::Image osg::ImageStream osg::ImageSequence" )
{
ADD_DOUBLE_SERIALIZER( ReferenceTime, DBL_MAX ); // _referenceTime
ADD_DOUBLE_SERIALIZER( TimeMultiplier, 1.0 ); // _timeMultiplier
BEGIN_ENUM_SERIALIZER( Mode, PRE_LOAD_ALL_IMAGES );
ADD_ENUM_VALUE( PRE_LOAD_ALL_IMAGES );
ADD_ENUM_VALUE( PAGE_AND_RETAIN_IMAGES );
ADD_ENUM_VALUE( PAGE_AND_DISCARD_USED_IMAGES );
END_ENUM_SERIALIZER(); // _mode
ADD_DOUBLE_SERIALIZER( Length, 1.0 ); // _length
ADD_USER_SERIALIZER( FileNames ); // _fileNames
ADD_USER_SERIALIZER( Images ); // _images
}

View File

@@ -0,0 +1,17 @@
#include <osg/ImageStream>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ImageStream,
new osg::ImageStream,
osg::ImageStream,
"osg::Object osg::Image osg::ImageStream" )
{
BEGIN_ENUM_SERIALIZER( LoopingMode, NO_LOOPING );
ADD_ENUM_VALUE( NO_LOOPING );
ADD_ENUM_VALUE( LOOPING );
END_ENUM_SERIALIZER(); // _loopingMode
ADD_LIST_SERIALIZER( AudioStreams, osg::ImageStream::AudioStreams ); // _audioStreams
}

View File

@@ -0,0 +1,76 @@
#include <osg/LOD>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _userDefinedCenter, _radius
static bool checkUserCenter( const osg::LOD& node )
{
return node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER;
}
static bool readUserCenter( osgDB::InputStream& is, osg::LOD& node )
{
osg::Vec3d center; double radius;
is >> center >> radius;
node.setCenter( center ); node.setRadius( radius );
return true;
}
static bool writeUserCenter( osgDB::OutputStream& os, const osg::LOD& node )
{
os << osg::Vec3d(node.getCenter()) << (double)node.getRadius() << std::endl;
return true;
}
// _rangeList
static bool checkRangeList( const osg::LOD& node )
{
return node.getNumRanges()>0;
}
static bool readRangeList( osgDB::InputStream& is, osg::LOD& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
float min, max;
is >> min >> max;
node.setRange( i, min, max );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeRangeList( osgDB::OutputStream& os, const osg::LOD& node )
{
const osg::LOD::RangeList& ranges = node.getRangeList();
os << ranges.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::LOD::RangeList::const_iterator itr=ranges.begin();
itr!=ranges.end(); ++itr )
{
os << itr->first << itr->second << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( LOD,
new osg::LOD,
osg::LOD,
"osg::Object osg::Node osg::Group osg::LOD" )
{
BEGIN_ENUM_SERIALIZER( CenterMode, USE_BOUNDING_SPHERE_CENTER );
ADD_ENUM_VALUE( USE_BOUNDING_SPHERE_CENTER );
ADD_ENUM_VALUE( USER_DEFINED_CENTER );
END_ENUM_SERIALIZER(); // _centerMode
ADD_USER_SERIALIZER( UserCenter ); // _userDefinedCenter, _radius
BEGIN_ENUM_SERIALIZER( RangeMode, DISTANCE_FROM_EYE_POINT );
ADD_ENUM_VALUE( DISTANCE_FROM_EYE_POINT );
ADD_ENUM_VALUE( PIXEL_SIZE_ON_SCREEN );
END_ENUM_SERIALIZER(); // _rangeMode
ADD_USER_SERIALIZER( RangeList ); // _rangeList
}

View File

@@ -0,0 +1,22 @@
#include <osg/Light>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Light,
new osg::Light,
osg::Light,
"osg::Object osg::StateAttribute osg::Light" )
{
ADD_INT_SERIALIZER( LightNum, 0 ); // _lightnum
ADD_VEC4_SERIALIZER( Ambient, osg::Vec4() ); // _ambient
ADD_VEC4_SERIALIZER( Diffuse, osg::Vec4() ); // _diffuse
ADD_VEC4_SERIALIZER( Specular, osg::Vec4() ); // _specular
ADD_VEC4_SERIALIZER( Position, osg::Vec4() ); // _position
ADD_VEC3_SERIALIZER( Direction, osg::Vec3() ); // _direction
ADD_FLOAT_SERIALIZER( ConstantAttenuation, 1.0f ); // _constant_attenuation
ADD_FLOAT_SERIALIZER( LinearAttenuation, 0.0f ); // _linear_attenuation
ADD_FLOAT_SERIALIZER( QuadraticAttenuation, 0.0f ); // _quadratic_attenuation
ADD_FLOAT_SERIALIZER( SpotExponent, 0.0f ); // _spot_exponent
ADD_FLOAT_SERIALIZER( SpotCutoff, 180.0f ); // _spot_cutoff
}

View File

@@ -0,0 +1,20 @@
#include <osg/LightModel>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( LightModel,
new osg::LightModel,
osg::LightModel,
"osg::Object osg::StateAttribute osg::LightModel" )
{
ADD_VEC4_SERIALIZER( AmbientIntensity, osg::Vec4() ); // _ambient
BEGIN_ENUM_SERIALIZER( ColorControl, SINGLE_COLOR );
ADD_ENUM_VALUE( SEPARATE_SPECULAR_COLOR );
ADD_ENUM_VALUE( SINGLE_COLOR );
END_ENUM_SERIALIZER(); // _colorControl
ADD_BOOL_SERIALIZER( LocalViewer, false ); // _localViewer
ADD_BOOL_SERIALIZER( TwoSided, false ); // _twoSided
}

View File

@@ -0,0 +1,17 @@
#include <osg/LightSource>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( LightSource,
new osg::LightSource,
osg::LightSource,
"osg::Object osg::Node osg::Group osg::LightSource" )
{
ADD_OBJECT_SERIALIZER( Light, osg::Light, NULL ); // _light
BEGIN_ENUM_SERIALIZER( ReferenceFrame, RELATIVE_RF );
ADD_ENUM_VALUE( RELATIVE_RF );
ADD_ENUM_VALUE( ABSOLUTE_RF );
END_ENUM_SERIALIZER(); // _referenceFrame
}

View File

@@ -0,0 +1,13 @@
#include <osg/LineStipple>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( LineStipple,
new osg::LineStipple,
osg::LineStipple,
"osg::Object osg::StateAttribute osg::LineStipple" )
{
ADD_INT_SERIALIZER( Factor, 1 ); // _factor
ADD_HEXSHORT_SERIALIZER( Pattern, 0xffff ); // _pattern
}

View File

@@ -0,0 +1,12 @@
#include <osg/LineWidth>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( LineWidth,
new osg::LineWidth,
osg::LineWidth,
"osg::Object osg::StateAttribute osg::LineWidth" )
{
ADD_FLOAT_SERIALIZER( Width, 1.0f ); // _width
}

View File

@@ -0,0 +1,29 @@
#include <osg/LogicOp>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( LogicOp,
new osg::LogicOp,
osg::LogicOp,
"osg::Object osg::StateAttribute osg::LogicOp" )
{
BEGIN_ENUM_SERIALIZER( Opcode, COPY );
ADD_ENUM_VALUE( CLEAR );
ADD_ENUM_VALUE( SET );
ADD_ENUM_VALUE( COPY );
ADD_ENUM_VALUE( COPY_INVERTED );
ADD_ENUM_VALUE( NOOP );
ADD_ENUM_VALUE( INVERT );
ADD_ENUM_VALUE( AND );
ADD_ENUM_VALUE( NAND );
ADD_ENUM_VALUE( OR );
ADD_ENUM_VALUE( NOR );
ADD_ENUM_VALUE( XOR );
ADD_ENUM_VALUE( EQUIV );
ADD_ENUM_VALUE( AND_REVERSE );
ADD_ENUM_VALUE( AND_INVERTED );
ADD_ENUM_VALUE( OR_REVERSE );
ADD_ENUM_VALUE( OR_INVERTED );
END_ENUM_SERIALIZER(); // _opcode
}

View File

@@ -0,0 +1,53 @@
#include <osg/Material>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
#define MATERIAL_FUNC( PROP, TYPE ) \
static bool check##PROP( const osg::Material& attr ) { return true; } \
static bool read##PROP( osgDB::InputStream& is, osg::Material& attr ) { \
bool frontAndBack; TYPE value1, value2; \
is >> frontAndBack; \
is >> osgDB::PROPERTY("Front") >> value1; \
is >> osgDB::PROPERTY("Back") >> value2; \
if ( frontAndBack ) \
attr.set##PROP(osg::Material::FRONT_AND_BACK, value1); \
else { \
attr.set##PROP(osg::Material::FRONT, value1); \
attr.set##PROP(osg::Material::BACK, value2); \
} \
return true; \
} \
static bool write##PROP( osgDB::OutputStream& os, const osg::Material& attr ) { \
os << attr.get##PROP##FrontAndBack(); \
os << osgDB::PROPERTY("Front") << TYPE(attr.get##PROP(osg::Material::FRONT)); \
os << osgDB::PROPERTY("Back") << TYPE(attr.get##PROP(osg::Material::BACK)) << std::endl; \
return true; \
}
MATERIAL_FUNC( Ambient, osg::Vec4f )
MATERIAL_FUNC( Diffuse, osg::Vec4f )
MATERIAL_FUNC( Specular, osg::Vec4f )
MATERIAL_FUNC( Emission, osg::Vec4f )
MATERIAL_FUNC( Shininess, float )
REGISTER_OBJECT_WRAPPER( Material,
new osg::Material,
osg::Material,
"osg::Object osg::StateAttribute osg::Material" )
{
BEGIN_ENUM_SERIALIZER( ColorMode, OFF );
ADD_ENUM_VALUE( AMBIENT );
ADD_ENUM_VALUE( DIFFUSE );
ADD_ENUM_VALUE( SPECULAR );
ADD_ENUM_VALUE( EMISSION );
ADD_ENUM_VALUE( AMBIENT_AND_DIFFUSE );
ADD_ENUM_VALUE( OFF );
END_ENUM_SERIALIZER(); // _colorMode
ADD_USER_SERIALIZER( Ambient ); // _ambient
ADD_USER_SERIALIZER( Diffuse ); // _diffuse
ADD_USER_SERIALIZER( Specular ); // _specular
ADD_USER_SERIALIZER( Emission ); // _emission
ADD_USER_SERIALIZER( Shininess ); // _shininess
}

View File

@@ -0,0 +1,12 @@
#include <osg/MatrixTransform>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( MatrixTransform,
new osg::MatrixTransform,
osg::MatrixTransform,
"osg::Object osg::Node osg::Group osg::Transform osg::MatrixTransform" )
{
ADD_MATRIX_SERIALIZER( Matrix, osg::Matrix() ); // _matrix
}

View File

@@ -0,0 +1,19 @@
#include <osg/Multisample>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Multisample,
new osg::Multisample,
osg::Multisample,
"osg::Object osg::StateAttribute osg::Multisample" )
{
ADD_FLOAT_SERIALIZER( Coverage, 0.0f ); // _coverage
ADD_BOOL_SERIALIZER( Invert, false ); // _invert
BEGIN_ENUM_SERIALIZER2( Hint, osg::Multisample::Mode, DONT_CARE );
ADD_ENUM_VALUE( FASTEST );
ADD_ENUM_VALUE( NICEST );
ADD_ENUM_VALUE( DONT_CARE );
END_ENUM_SERIALIZER(); // _mode
}

View File

@@ -0,0 +1,82 @@
#include <osg/Node>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _initialBound
static bool checkInitialBound( const osg::Node& node )
{
return node.getInitialBound().valid();
}
static bool readInitialBound( osgDB::InputStream& is, osg::Node& node )
{
osg::Vec3d center;
double radius;
bool valid;
is >> valid >> osgDB::BEGIN_BRACKET;
is >> osgDB::PROPERTY("Center") >> center;
is >> osgDB::PROPERTY("Radius") >> radius >> osgDB::END_BRACKET;
node.setInitialBound( osg::BoundingSphere(center, radius) );
return true;
}
static bool writeInitialBound( osgDB::OutputStream& os, const osg::Node& node )
{
const osg::BoundingSphere& bs = node.getInitialBound();
os << bs.valid() << osgDB::BEGIN_BRACKET << std::endl;
os << osgDB::PROPERTY("Center") << osg::Vec3d(bs.center()) << std::endl;
os << osgDB::PROPERTY("Radius") << double(bs.radius()) << std::endl;
os << osgDB::END_BRACKET << std::endl;
return true;
}
// _descriptions
static bool checkDescriptions( const osg::Node& node )
{
return node.getDescriptions().size()>0;
}
static bool readDescriptions( osgDB::InputStream& is, osg::Node& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
std::string value;
is.readWrappedString( value );
node.addDescription( value );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeDescriptions( osgDB::OutputStream& os, const osg::Node& node )
{
const osg::Node::DescriptionList& slist = node.getDescriptions();
os << slist.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::Node::DescriptionList::const_iterator itr=slist.begin();
itr!=slist.end(); ++itr )
{
os.writeWrappedString( *itr );
os << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Node,
new osg::Node,
osg::Node,
"osg::Object osg::Node" )
{
ADD_USER_SERIALIZER( InitialBound ); // _initialBound
ADD_OBJECT_SERIALIZER( ComputeBoundingSphereCallback,
osg::Node::ComputeBoundingSphereCallback, NULL ); // _computeBoundCallback
ADD_OBJECT_SERIALIZER( UpdateCallback, osg::NodeCallback, NULL ); // _updateCallback
ADD_OBJECT_SERIALIZER( EventCallback, osg::NodeCallback, NULL ); // _eventCallback
ADD_OBJECT_SERIALIZER( CullCallback, osg::NodeCallback, NULL ); // _cullCallback
ADD_BOOL_SERIALIZER( CullingActive, true ); // _cullingActive
ADD_HEXINT_SERIALIZER( NodeMask, 0xffffffff ); // _nodeMask
ADD_USER_SERIALIZER( Descriptions ); // _descriptions
ADD_OBJECT_SERIALIZER( StateSet, osg::StateSet, NULL ); // _stateset
}

View File

@@ -0,0 +1,18 @@
#undef OBJECT_CAST
#define OBJECT_CAST dynamic_cast
#include <osg/Node>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( NodeCallback,
new osg::NodeCallback,
osg::NodeCallback,
"osg::Object osg::NodeCallback" )
{
ADD_OBJECT_SERIALIZER( NestedCallback, osg::NodeCallback, NULL ); // _nestedCallback
}
#undef OBJECT_CAST
#define OBJECT_CAST static_cast

View File

@@ -0,0 +1,18 @@
#undef OBJECT_CAST
#define OBJECT_CAST dynamic_cast
#include <osg/NodeTrackerCallback>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( NodeTrackerCallback,
new osg::NodeTrackerCallback,
osg::NodeTrackerCallback,
"osg::Object osg::NodeCallback osg::NodeTrackerCallback" )
{
ADD_OBJECT_SERIALIZER( TrackNode, osg::Node, NULL ); // _trackNodePath
}
#undef OBJECT_CAST
#define OBJECT_CAST static_cast

View File

@@ -0,0 +1,18 @@
#include <osg/Object>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Object,
/*new osg::Object*/NULL,
osg::Object,
"osg::Object" )
{
ADD_STRING_SERIALIZER( Name, "" ); // _name
BEGIN_ENUM_SERIALIZER( DataVariance, UNSPECIFIED );
ADD_ENUM_VALUE( STATIC );
ADD_ENUM_VALUE( DYNAMIC );
ADD_ENUM_VALUE( UNSPECIFIED );
END_ENUM_SERIALIZER(); // _dataVariance
}

View File

@@ -0,0 +1,12 @@
#include <osg/OccluderNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( OccluderNode,
new osg::OccluderNode,
osg::OccluderNode,
"osg::Object osg::Node osg::Group osg::OccluderNode" )
{
ADD_OBJECT_SERIALIZER( Occluder, osg::ConvexPlanarOccluder, NULL ); // _occluder
}

View File

@@ -0,0 +1,15 @@
#include <osg/OcclusionQueryNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( OcclusionQueryNode,
new osg::OcclusionQueryNode,
osg::OcclusionQueryNode,
"osg::Object osg::Node osg::Group osg::OcclusionQueryNode" )
{
ADD_BOOL_SERIALIZER( QueriesEnabled, true ); // _enabled
ADD_UINT_SERIALIZER( VisibilityThreshold, 0 ); // _visThreshold
ADD_INT_SERIALIZER( QueryFrameCount, 0 ); // _queryFrameCount
ADD_BOOL_SERIALIZER( DebugDisplay, false ); // _debugBB
}

View File

@@ -0,0 +1,58 @@
#include <osg/PagedLOD>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkRangeDataList( const osg::PagedLOD& node )
{
return node.getNumFileNames()>0;
}
static bool readRangeDataList( osgDB::InputStream& is, osg::PagedLOD& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
std::string name; is.readWrappedString( name );
float offset, scale;
double timeStamp;
int frameNumber;
is >> offset >> scale >> timeStamp >> frameNumber;
node.setFileName( i, name );
node.setPriorityOffset( i, offset );
node.setPriorityScale( i, scale );
node.setTimeStamp( i, timeStamp );
node.setFrameNumber( i, frameNumber );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeRangeDataList( osgDB::OutputStream& os, const osg::PagedLOD& node )
{
unsigned int size = node.getNumFileNames();
os << size << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<size; ++i )
{
os.writeWrappedString( node.getFileName(i) );
os << node.getPriorityOffset(i) << node.getPriorityScale(i)
<< node.getTimeStamp(i) << node.getFrameNumber(i) << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( PagedLOD,
new osg::PagedLOD,
osg::PagedLOD,
"osg::Object osg::Node osg::LOD osg::PagedLOD" )
{
// Note: osg::Group is not in the list to prevent recording dynamic loaded children
ADD_STRING_SERIALIZER( DatabasePath, "" ); // _databasePath
ADD_INT_SERIALIZER( FrameNumberOfLastTraversal, 0 ); // _frameNumberOfLastTraversal
ADD_UINT_SERIALIZER( NumChildrenThatCannotBeExpired, 0 ); // _numChildrenThatCannotBeExpired
ADD_BOOL_SERIALIZER( DisableExternalChildrenPaging, false ); // _disableExternalChildrenPaging
ADD_USER_SERIALIZER( RangeDataList ); // _perRangeDataList
}

View File

@@ -0,0 +1,16 @@
#include <osg/Point>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Point,
new osg::Point,
osg::Point,
"osg::Object osg::StateAttribute osg::Point" )
{
ADD_FLOAT_SERIALIZER( Size, 0.0f ); // _size
ADD_FLOAT_SERIALIZER( FadeThresholdSize, 0.0f ); // _fadeThresholdSize
ADD_VEC3_SERIALIZER( DistanceAttenuation, osg::Vec3() ); // _distanceAttenuation
ADD_FLOAT_SERIALIZER( MinSize, 0.0f ); // _minSize
ADD_FLOAT_SERIALIZER( MaxSize, 0.0f ); // _maxSize
}

View File

@@ -0,0 +1,15 @@
#include <osg/PointSprite>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( PointSprite,
new osg::PointSprite,
osg::PointSprite,
"osg::Object osg::StateAttribute osg::PointSprite" )
{
BEGIN_ENUM_SERIALIZER( CoordOriginMode, UPPER_LEFT );
ADD_ENUM_VALUE( UPPER_LEFT );
ADD_ENUM_VALUE( LOWER_LEFT );
END_ENUM_SERIALIZER(); // _coordOriginMode
}

View File

@@ -0,0 +1,58 @@
#include <osg/PolygonMode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
BEGIN_USER_TABLE( Mode, osg::PolygonMode );
ADD_USER_VALUE( POINT );
ADD_USER_VALUE( LINE );
ADD_USER_VALUE( FILL );
END_USER_TABLE()
USER_READ_FUNC( Mode, readModeValue )
USER_WRITE_FUNC( Mode, writeModeValue )
// _modeFront, _modeBack
static bool checkMode( const osg::PolygonMode& attr )
{
return true;
}
static bool readMode( osgDB::InputStream& is, osg::PolygonMode& attr )
{
bool frontAndBack;
is >> osgDB::PROPERTY("UseFrontAndBack") >> frontAndBack;
is >> osgDB::PROPERTY("Front"); int value1 = readModeValue(is);
is >> osgDB::PROPERTY("Back"); int value2 = readModeValue(is);
if ( frontAndBack )
attr.setMode( osg::PolygonMode::FRONT_AND_BACK, (osg::PolygonMode::Mode)value1 );
else
{
attr.setMode(osg::PolygonMode::FRONT, (osg::PolygonMode::Mode)value1);
attr.setMode(osg::PolygonMode::BACK, (osg::PolygonMode::Mode)value2);
}
return true;
}
static bool writeMode( osgDB::OutputStream& os, const osg::PolygonMode& attr )
{
os << osgDB::PROPERTY("UseFrontAndBack") << attr.getFrontAndBack() << std::endl;
os << osgDB::PROPERTY("Front");
writeModeValue( os, (int)attr.getMode(osg::PolygonMode::FRONT) );
os << std::endl;
os << osgDB::PROPERTY("Back");
writeModeValue( os, (int)attr.getMode(osg::PolygonMode::BACK) );
os << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( PolygonMode,
new osg::PolygonMode,
osg::PolygonMode,
"osg::Object osg::StateAttribute osg::PolygonMode" )
{
ADD_USER_SERIALIZER( Mode ); // _modeFront, _modeBack
}

View File

@@ -0,0 +1,13 @@
#include <osg/PolygonOffset>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( PolygonOffset,
new osg::PolygonOffset,
osg::PolygonOffset,
"osg::Object osg::StateAttribute osg::PolygonOffset" )
{
ADD_FLOAT_SERIALIZER( Factor, 0.0f ); // _factor
ADD_FLOAT_SERIALIZER( Units, 0.0f ); // _units
}

View File

@@ -0,0 +1,58 @@
#include <osg/PolygonStipple>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkMask( const osg::PolygonStipple& attr )
{
return true;
}
static bool readMask( osgDB::InputStream& is, osg::PolygonStipple& attr )
{
char mask[128] = {0};
if ( is.isBinary() )
{
unsigned int size; is >> size;
is.readCharArray( mask, size );
}
else
{
is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<128; ++i )
{
is >> std::hex >> mask[i] >> std::dec;
}
is >> osgDB::END_BRACKET;
}
attr.setMask( (GLubyte*)mask );
return true;
}
static bool writeMask( osgDB::OutputStream& os, const osg::PolygonStipple& attr )
{
if ( os.isBinary() )
{
os << (unsigned int)128;
os.writeCharArray( (char*)attr.getMask(), 128 );
}
else
{
const GLubyte* mask = attr.getMask();
os << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<128; ++i )
{
os << std::hex << mask[i] << std::dec << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
}
return true;
}
REGISTER_OBJECT_WRAPPER( PolygonStipple,
new osg::PolygonStipple,
osg::PolygonStipple,
"osg::Object osg::StateAttribute osg::PolygonStipple" )
{
ADD_USER_SERIALIZER( Mask ); // _mask
}

View File

@@ -0,0 +1,15 @@
#include <osg/PositionAttitudeTransform>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( PositionAttitudeTransform,
new osg::PositionAttitudeTransform,
osg::PositionAttitudeTransform,
"osg::Object osg::Node osg::Group osg::Transform osg::PositionAttitudeTransform" )
{
ADD_VEC3D_SERIALIZER( Position, osg::Vec3d() ); // _position
ADD_QUAT_SERIALIZER( Attitude, osg::Quat() ); // _attitude
ADD_VEC3D_SERIALIZER( Scale, osg::Vec3d() ); // _scale
ADD_VEC3D_SERIALIZER( PivotPoint, osg::Vec3d() ); // _pivotPoint
}

View File

@@ -0,0 +1,91 @@
#include <osg/Program>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
#define PROGRAM_LIST_FUNC( PROP, TYPE, DATA ) \
static bool check##PROP(const osg::Program& attr) \
{ return attr.get##TYPE().size()>0; } \
static bool read##PROP(osgDB::InputStream& is, osg::Program& attr) { \
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET; \
for ( unsigned int i=0; i<size; ++i ) { \
std::string key; unsigned int value; \
is >> key >> value; attr.add##DATA(key, value); \
} \
is >> osgDB::END_BRACKET; \
return true; \
} \
static bool write##PROP( osgDB::OutputStream& os, const osg::Program& attr ) \
{ \
const osg::Program::TYPE& plist = attr.get##TYPE(); \
os << plist.size() << osgDB::BEGIN_BRACKET << std::endl; \
for ( osg::Program::TYPE::const_iterator itr=plist.begin(); \
itr!=plist.end(); ++itr ) { \
os << itr->first << itr->second << std::endl; \
} \
os << osgDB::END_BRACKET << std::endl; \
return true; \
}
PROGRAM_LIST_FUNC( AttribBinding, AttribBindingList, BindAttribLocation )
PROGRAM_LIST_FUNC( FragDataBinding, FragDataBindingList, BindFragDataLocation )
#define PROGRAM_PARAMETER_FUNC( PROP, NAME ) \
static bool check##PROP(const osg::Program& attr) \
{ return attr.getParameter(NAME)!=GL_NONE; } \
static bool read##PROP(osgDB::InputStream& is, osg::Program& attr) { \
int value; is >> osgDB::PROPERTY(#NAME) >> value; \
attr.setParameter(NAME, value); \
return true; \
} \
static bool write##PROP(osgDB::OutputStream& os, const osg::Program& attr) { \
os << osgDB::PROPERTY(#NAME) << (int)attr.getParameter(NAME) << std::endl; \
return true; \
}
PROGRAM_PARAMETER_FUNC( GeometryVerticesOut, GL_GEOMETRY_VERTICES_OUT_EXT )
PROGRAM_PARAMETER_FUNC( GeometryInputType, GL_GEOMETRY_INPUT_TYPE_EXT )
PROGRAM_PARAMETER_FUNC( GeometryOutputType, GL_GEOMETRY_OUTPUT_TYPE_EXT )
// _shaderList
static bool checkShaders( const osg::Program& attr )
{
return attr.getNumShaders()>0;
}
static bool readShaders( osgDB::InputStream& is, osg::Program& attr )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Shader* shader = dynamic_cast<osg::Shader*>( is.readObject() );
if ( shader ) attr.addShader( shader );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeShaders( osgDB::OutputStream& os, const osg::Program& attr )
{
unsigned int size = attr.getNumShaders();
os << size << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<size; ++i )
{
os << attr.getShader(i);
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Program,
new osg::Program,
osg::Program,
"osg::Object osg::StateAttribute osg::Program" )
{
ADD_USER_SERIALIZER( AttribBinding ); // _attribBindingList
ADD_USER_SERIALIZER( FragDataBinding ); // _fragDataBindingList
ADD_USER_SERIALIZER( Shaders ); // _shaderList
ADD_USER_SERIALIZER( GeometryVerticesOut ); // _geometryVerticesOut
ADD_USER_SERIALIZER( GeometryInputType ); // _geometryInputType
ADD_USER_SERIALIZER( GeometryOutputType ); // _geometryOutputType
}

View File

@@ -0,0 +1,12 @@
#include <osg/Projection>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Projection,
new osg::Projection,
osg::Projection,
"osg::Object osg::Node osg::Group osg::Projection" )
{
ADD_MATRIX_SERIALIZER( Matrix, osg::Matrix() ); // _matrix
}

View File

@@ -0,0 +1,79 @@
#include <osg/ProxyNode>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// _filenameList
static bool checkFileNames( const osg::ProxyNode& node )
{
return node.getNumFileNames()>0;
}
static bool readFileNames( osgDB::InputStream& is, osg::ProxyNode& node )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
std::string value;
is.readWrappedString( value );
node.setFileName( i, value );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeFileNames( osgDB::OutputStream& os, const osg::ProxyNode& node )
{
os << node.getNumFileNames() << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<node.getNumFileNames(); ++i )
{
os.writeWrappedString( node.getFileName(i) );
os << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
// _userDefinedCenter, _radius
static bool checkUserCenter( const osg::ProxyNode& node )
{
return node.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER;
}
static bool readUserCenter( osgDB::InputStream& is, osg::ProxyNode& node )
{
osg::Vec3d center; double radius;
is >> center >> radius;
node.setCenter( center ); node.setRadius( radius );
return true;
}
static bool writeUserCenter( osgDB::OutputStream& os, const osg::ProxyNode& node )
{
os << osg::Vec3d(node.getCenter()) << (double)node.getRadius() << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( ProxyNode,
new osg::ProxyNode,
osg::ProxyNode,
"osg::Object osg::Node osg::ProxyNode" )
{
// Note: osg::Group is not in the list to prevent recording dynamic loaded children
ADD_USER_SERIALIZER( FileNames ); // _filenameList
ADD_STRING_SERIALIZER( DatabasePath, "" ); // _databasePath
BEGIN_ENUM_SERIALIZER( LoadingExternalReferenceMode, LOAD_IMMEDIATELY );
ADD_ENUM_VALUE( LOAD_IMMEDIATELY );
ADD_ENUM_VALUE( DEFER_LOADING_TO_DATABASE_PAGER );
ADD_ENUM_VALUE( NO_AUTOMATIC_LOADING );
END_ENUM_SERIALIZER(); // _loadingExtReference
BEGIN_ENUM_SERIALIZER( CenterMode, USE_BOUNDING_SPHERE_CENTER );
ADD_ENUM_VALUE( USE_BOUNDING_SPHERE_CENTER );
ADD_ENUM_VALUE( USER_DEFINED_CENTER );
END_ENUM_SERIALIZER(); // _centerMode
ADD_USER_SERIALIZER( UserCenter ); // _userDefinedCenter, _radius
}

View File

@@ -0,0 +1,31 @@
#include <osg/Scissor>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkArea( const osg::Scissor& attr )
{
return true;
}
static bool readArea( osgDB::InputStream& is, osg::Scissor& attr )
{
int x, y, w, h;
is >> x >> y >> w >> h;
attr.setScissor( x, y, w, h );
return true;
}
static bool writeArea( osgDB::OutputStream& os, const osg::Scissor& attr )
{
os << attr.x() << attr.y() << attr.width() << attr.height() << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Scissor,
new osg::Scissor,
osg::Scissor,
"osg::Object osg::StateAttribute osg::Scissor" )
{
ADD_USER_SERIALIZER( Area ); // _x, _y, _width, _height
}

View File

@@ -0,0 +1,34 @@
#include <osg/Sequence>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Sequence,
new osg::Sequence,
osg::Sequence,
"osg::Object osg::Node osg::Group osg::Sequence" )
{
ADD_LIST_SERIALIZER( TimeList, std::vector<double> ); // _frameTime
BEGIN_ENUM_SERIALIZER( LoopMode, LOOP );
ADD_ENUM_VALUE( LOOP );
ADD_ENUM_VALUE( SWING );
END_ENUM_SERIALIZER(); // _loopMode
ADD_INT_SERIALIZER( Begin, 0 ); // _begin
ADD_INT_SERIALIZER( End, -1 ); // _end
ADD_FLOAT_SERIALIZER( Speed, 0.0f ); // _speed
ADD_INT_SERIALIZER( NumRepeats, -1 ); // _nreps
ADD_DOUBLE_SERIALIZER( DefaultTime, 1.0 ); // _defaultTime
ADD_DOUBLE_SERIALIZER( LastFrameTime, 0.0 ); // _lastFrameTime
BEGIN_ENUM_SERIALIZER2( Mode, osg::Sequence::SequenceMode, STOP );
ADD_ENUM_VALUE( START );
ADD_ENUM_VALUE( STOP );
ADD_ENUM_VALUE( PAUSE );
ADD_ENUM_VALUE( RESUME );
END_ENUM_SERIALIZER(); // _mode
ADD_BOOL_SERIALIZER( Sync, false ); // _sync
ADD_BOOL_SERIALIZER( ClearOnStop, false ); // _clearOnStop
}

View File

@@ -0,0 +1,15 @@
#include <osg/ShadeModel>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ShadeModel,
new osg::ShadeModel,
osg::ShadeModel,
"osg::Object osg::StateAttribute osg::ShadeModel" )
{
BEGIN_ENUM_SERIALIZER( Mode, SMOOTH );
ADD_ENUM_VALUE( FLAT );
ADD_ENUM_VALUE( SMOOTH );
END_ENUM_SERIALIZER(); // _mode
}

View File

@@ -0,0 +1,61 @@
#include <osg/Shader>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static bool checkShaderSource( const osg::Shader& shader )
{
return !shader.getShaderSource().empty();
}
static bool readShaderSource( osgDB::InputStream& is, osg::Shader& shader )
{
std::string code;
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
std::string line;
is.readWrappedString( line );
code.append( line ); code.append( 1, '\n' );
}
is >> osgDB::END_BRACKET;
shader.setShaderSource( code );
return true;
}
static bool writeShaderSource( osgDB::OutputStream& os, const osg::Shader& shader )
{
std::vector<std::string> lines;
std::istringstream iss( shader.getShaderSource() );
std::string line;
while ( std::getline(iss, line) )
{
lines.push_back( line );
}
os << lines.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( std::vector<std::string>::const_iterator itr=lines.begin();
itr!=lines.end(); ++itr )
{
os.writeWrappedString( *itr );
os << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( Shader,
new osg::Shader,
osg::Shader,
"osg::Object osg::Shader" )
{
BEGIN_ENUM_SERIALIZER3( Type, UNDEFINED );
ADD_ENUM_VALUE( VERTEX );
ADD_ENUM_VALUE( FRAGMENT );
ADD_ENUM_VALUE( GEOMETRY );
ADD_ENUM_VALUE( UNDEFINED );
END_ENUM_SERIALIZER(); // _type
ADD_USER_SERIALIZER( ShaderSource ); // _shaderSource
ADD_OBJECT_SERIALIZER( ShaderBinary, osg::ShaderBinary, NULL ); // _shaderBinary
}

View File

@@ -0,0 +1,58 @@
#include <osg/Shader>
#include <osgDB/ObjectWrapper>
#include <osgDB/Serializer>
static bool checkData( const osg::ShaderBinary& sb )
{
return sb.getSize()>0;
}
static bool readData( osgDB::InputStream& is, osg::ShaderBinary& sb )
{
unsigned int size; is >> size;
char* data = new char[size];
if ( is.isBinary() )
{
is.readCharArray( data, size );
}
else
{
is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
is >> std::hex >> data[i] >> std::dec;
}
is >> osgDB::END_BRACKET;
}
sb.assign( size, (unsigned char*)data );
delete data;
return true;
}
static bool writeData( osgDB::OutputStream& os, const osg::ShaderBinary& sb )
{
if ( os.isBinary() )
{
os << (unsigned int)sb.getSize();
os.writeCharArray( (char*)sb.getData(), sb.getSize() );
}
else
{
const unsigned char* data = sb.getData();
os << osgDB::BEGIN_BRACKET << std::endl;
for ( unsigned int i=0; i<sb.getSize(); ++i )
{
os << std::hex << data[i] << std::dec << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
}
return true;
}
REGISTER_OBJECT_WRAPPER( ShaderBinary,
new osg::ShaderBinary,
osg::ShaderBinary,
"osg::Object osg::ShaderBinary" )
{
ADD_USER_SERIALIZER( Data ); // _data
}

View File

@@ -0,0 +1,11 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Shape,
/*new osg::Shape*/NULL,
osg::Shape,
"osg::Object osg::Shape" )
{
}

View File

@@ -0,0 +1,13 @@
#include <osg/ShapeDrawable>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ShapeDrawable,
new osg::ShapeDrawable,
osg::ShapeDrawable,
"osg::Object osg::Drawable osg::ShapeDrawable" )
{
ADD_VEC4_SERIALIZER( Color, osg::Vec4() ); // _color
ADD_OBJECT_SERIALIZER( TessellationHints, osg::TessellationHints, NULL ); // _tessellationHints
}

View File

@@ -0,0 +1,13 @@
#include <osg/Shape>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Sphere,
new osg::Sphere,
osg::Sphere,
"osg::Object osg::Shape osg::Sphere" )
{
ADD_VEC3_SERIALIZER( Center, osg::Vec3() ); // _center
ADD_FLOAT_SERIALIZER( Radius, 0.0f ); // _radius
}

View File

@@ -0,0 +1,13 @@
#include <osg/StateAttribute>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( StateAttribute,
/*new osg::StateAttribute*/NULL,
osg::StateAttribute,
"osg::Object osg::StateAttribute" )
{
ADD_OBJECT_SERIALIZER( UpdateCallback, osg::StateAttributeCallback, NULL ); // _updateCallback
ADD_OBJECT_SERIALIZER( EventCallback, osg::StateAttributeCallback, NULL ); // _eventCallback
}

View File

@@ -0,0 +1,306 @@
#include <osg/StateSet>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
static int readValue( osgDB::InputStream& is )
{
int value = osg::StateAttribute::INHERIT;
if ( is.isBinary() )
is >> value;
else
{
std::string enumValue;
is >> enumValue;
if ( enumValue=="OFF" ) value = osg::StateAttribute::OFF;
else if ( enumValue=="ON" ) value = osg::StateAttribute::ON;
else if ( enumValue=="INHERIT" ) value = osg::StateAttribute::INHERIT;
else if ( enumValue=="OFF|OVERRIDE" )
value = osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE;
else if ( enumValue=="OFF|PROTECTED" )
value = osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED;
else if ( enumValue=="ON|OVERRIDE" )
value = osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE;
else if ( enumValue=="ON|PROTECTED" )
value = osg::StateAttribute::ON|osg::StateAttribute::PROTECTED;
}
return value;
}
static void readModes( osgDB::InputStream& is, osg::StateSet::ModeList& modes )
{
unsigned int size = 0; is >> size;
if ( size>0 )
{
is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
DEF_GLENUM(mode); is >> mode;
int value = readValue( is );
modes[mode.get()] = (osg::StateAttribute::Values)value;
}
is >> osgDB::END_BRACKET;
}
}
static void readAttributes( osgDB::InputStream& is, osg::StateSet::AttributeList& attrs )
{
unsigned int size = 0; is >> size;
if ( size>0 )
{
is >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::StateAttribute* sa = dynamic_cast<osg::StateAttribute*>( is.readObject() );
is >> osgDB::PROPERTY("Value");
int value = readValue( is );
if ( sa )
attrs[sa->getTypeMemberPair()] = osg::StateSet::RefAttributePair(sa,value);
}
is >> osgDB::END_BRACKET;
}
}
static void writeValue( osgDB::OutputStream& os, int value )
{
if ( os.isBinary() )
os << value;
else
{
if ( value==osg::StateAttribute::OFF ) os << std::string("OFF");
else if ( value==osg::StateAttribute::ON ) os << std::string("ON");
else if ( value==osg::StateAttribute::INHERIT ) os << std::string("INHERIT");
else if ( value==osg::StateAttribute::OFF+osg::StateAttribute::OVERRIDE )
os << std::string("OFF|OVERRIDE");
else if ( value==osg::StateAttribute::OFF+osg::StateAttribute::PROTECTED )
os << std::string("OFF|PROTECTED");
else if ( value==osg::StateAttribute::ON+osg::StateAttribute::OVERRIDE )
os << std::string("ON|OVERRIDE");
else if ( value==osg::StateAttribute::ON+osg::StateAttribute::PROTECTED )
os << std::string("ON|PROTECTED");
else os << std::string("INHERIT");
}
}
static void writeModes( osgDB::OutputStream& os, const osg::StateSet::ModeList& modes )
{
os << modes.size();
if ( modes.size()>0 )
{
os << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::StateSet::ModeList::const_iterator itr=modes.begin();
itr!=modes.end(); ++itr )
{
os << GLENUM(itr->first);
writeValue(os, itr->second);
os << std::endl;
}
os << osgDB::END_BRACKET;
}
os << std::endl;
}
static void writeAttributes( osgDB::OutputStream& os, const osg::StateSet::AttributeList& attrs )
{
os << attrs.size();
if ( attrs.size()>0 )
{
os << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::StateSet::AttributeList::const_iterator itr=attrs.begin();
itr!=attrs.end(); ++itr )
{
os << itr->second.first.get();
os << osgDB::PROPERTY("Value");
writeValue(os, itr->second.second);
os << std::endl;
}
os << osgDB::END_BRACKET;
}
os << std::endl;
}
// _modeList
static bool checkModeList( const osg::StateSet& ss )
{
return ss.getModeList().size()>0;
}
static bool readModeList( osgDB::InputStream& is, osg::StateSet& ss )
{
osg::StateSet::ModeList modes; readModes( is, modes );
for ( osg::StateSet::ModeList::iterator itr=modes.begin();
itr!=modes.end(); ++itr )
{
ss.setMode( itr->first, itr->second );
}
return true;
}
static bool writeModeList( osgDB::OutputStream& os, const osg::StateSet& ss )
{
writeModes( os, ss.getModeList() );
return true;
}
// _attributeList
static bool checkAttributeList( const osg::StateSet& ss )
{
return ss.getAttributeList().size()>0;
}
static bool readAttributeList( osgDB::InputStream& is, osg::StateSet& ss )
{
osg::StateSet::AttributeList attrs; readAttributes( is, attrs );
for ( osg::StateSet::AttributeList::iterator itr=attrs.begin();
itr!=attrs.end(); ++itr )
{
ss.setAttribute( itr->second.first, itr->second.second );
}
return true;
}
static bool writeAttributeList( osgDB::OutputStream& os, const osg::StateSet& ss )
{
writeAttributes( os, ss.getAttributeList() );
return true;
}
// _textureModeList
static bool checkTextureModeList( const osg::StateSet& ss )
{
return ss.getTextureModeList().size()>0;
}
static bool readTextureModeList( osgDB::InputStream& is, osg::StateSet& ss )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
osg::StateSet::ModeList modes;
for ( unsigned int i=0; i<size; ++i )
{
is >> osgDB::PROPERTY("Data");
readModes( is, modes );
for ( osg::StateSet::ModeList::iterator itr=modes.begin();
itr!=modes.end(); ++itr )
{
ss.setTextureMode( i, itr->first, itr->second );
}
modes.clear();
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeTextureModeList( osgDB::OutputStream& os, const osg::StateSet& ss )
{
const osg::StateSet::TextureModeList& tml = ss.getTextureModeList();
os << tml.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::StateSet::TextureModeList::const_iterator itr=tml.begin();
itr!=tml.end(); ++itr )
{
os << osgDB::PROPERTY("Data");
writeModes( os, *itr );
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
// _textureAttributeList
static bool checkTextureAttributeList( const osg::StateSet& ss )
{
return ss.getTextureAttributeList().size()>0;
}
static bool readTextureAttributeList( osgDB::InputStream& is, osg::StateSet& ss )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
osg::StateSet::AttributeList attrs;
for ( unsigned int i=0; i<size; ++i )
{
is >> osgDB::PROPERTY("Data");
readAttributes( is, attrs );
for ( osg::StateSet::AttributeList::iterator itr=attrs.begin();
itr!=attrs.end(); ++itr )
{
ss.setTextureAttribute( i, itr->second.first, itr->second.second );
}
attrs.clear();
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeTextureAttributeList( osgDB::OutputStream& os, const osg::StateSet& ss )
{
const osg::StateSet::TextureAttributeList& tal = ss.getTextureAttributeList();
os << tal.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::StateSet::TextureAttributeList::const_iterator itr=tal.begin();
itr!=tal.end(); ++itr )
{
os << osgDB::PROPERTY("Data");
writeAttributes( os, *itr );
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
// _uniformList
static bool checkUniformList( const osg::StateSet& ss )
{
return ss.getUniformList().size()>0;
}
static bool readUniformList( osgDB::InputStream& is, osg::StateSet& ss )
{
unsigned int size = 0; is >> size >> osgDB::BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
osg::Uniform* uniform = dynamic_cast<osg::Uniform*>( is.readObject() );
is >> osgDB::PROPERTY("Value");
int value = readValue( is );
if ( uniform )
ss.addUniform( uniform, (osg::StateAttribute::Values)value );
}
is >> osgDB::END_BRACKET;
return true;
}
static bool writeUniformList( osgDB::OutputStream& os, const osg::StateSet& ss )
{
const osg::StateSet::UniformList& ul = ss.getUniformList();
os << ul.size() << osgDB::BEGIN_BRACKET << std::endl;
for ( osg::StateSet::UniformList::const_iterator itr=ul.begin();
itr!=ul.end(); ++itr )
{
os << itr->second.first.get();
os << osgDB::PROPERTY("Value");
writeValue(os, itr->second.second);
os << std::endl;
}
os << osgDB::END_BRACKET << std::endl;
return true;
}
REGISTER_OBJECT_WRAPPER( StateSet,
new osg::StateSet,
osg::StateSet,
"osg::Object osg::StateSet" )
{
ADD_USER_SERIALIZER( ModeList ); // _modeList
ADD_USER_SERIALIZER( AttributeList ); // _attributeList
ADD_USER_SERIALIZER( TextureModeList ); // _textureModeList
ADD_USER_SERIALIZER( TextureAttributeList ); // _textureAttributeList
ADD_USER_SERIALIZER( UniformList ); // _uniformList
ADD_INT_SERIALIZER( RenderingHint, osg::StateSet::DEFAULT_BIN ); // _renderingHint
BEGIN_ENUM_SERIALIZER( RenderBinMode, INHERIT_RENDERBIN_DETAILS );
ADD_ENUM_VALUE( INHERIT_RENDERBIN_DETAILS );
ADD_ENUM_VALUE( USE_RENDERBIN_DETAILS );
ADD_ENUM_VALUE( OVERRIDE_RENDERBIN_DETAILS );
END_ENUM_SERIALIZER(); // _binMode
ADD_INT_SERIALIZER( BinNumber, 0 ); // _binNum
ADD_STRING_SERIALIZER( BinName, "" ); // _binName
ADD_BOOL_SERIALIZER( NestRenderBins, true ); // _nestRenderBins
ADD_OBJECT_SERIALIZER( UpdateCallback, osg::StateSet::Callback, NULL ); // _updateCallback
ADD_OBJECT_SERIALIZER( EventCallback, osg::StateSet::Callback, NULL ); // _eventCallback
}

View File

@@ -0,0 +1,59 @@
#include <osg/Stencil>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( Stencil,
new osg::Stencil,
osg::Stencil,
"osg::Object osg::StateAttribute osg::Stencil" )
{
BEGIN_ENUM_SERIALIZER( Function, ALWAYS );
ADD_ENUM_VALUE( NEVER );
ADD_ENUM_VALUE( LESS );
ADD_ENUM_VALUE( EQUAL );
ADD_ENUM_VALUE( LEQUAL );
ADD_ENUM_VALUE( GREATER );
ADD_ENUM_VALUE( NOTEQUAL );
ADD_ENUM_VALUE( GEQUAL );
ADD_ENUM_VALUE( ALWAYS );
END_ENUM_SERIALIZER(); // _func
ADD_INT_SERIALIZER( FunctionRef, 0 ); // _funcRef
ADD_HEXINT_SERIALIZER( FunctionMask, ~0u ); // _funcMask
BEGIN_ENUM_SERIALIZER2( StencilFailOperation, osg::Stencil::Operation, KEEP );
ADD_ENUM_VALUE( KEEP );
ADD_ENUM_VALUE( ZERO );
ADD_ENUM_VALUE( REPLACE );
ADD_ENUM_VALUE( INCR );
ADD_ENUM_VALUE( DECR );
ADD_ENUM_VALUE( INVERT );
ADD_ENUM_VALUE( INCR_WRAP );
ADD_ENUM_VALUE( DECR_WRAP );
END_ENUM_SERIALIZER(); // _sfail
BEGIN_ENUM_SERIALIZER2( StencilPassAndDepthFailOperation, osg::Stencil::Operation, KEEP );
ADD_ENUM_VALUE( KEEP );
ADD_ENUM_VALUE( ZERO );
ADD_ENUM_VALUE( REPLACE );
ADD_ENUM_VALUE( INCR );
ADD_ENUM_VALUE( DECR );
ADD_ENUM_VALUE( INVERT );
ADD_ENUM_VALUE( INCR_WRAP );
ADD_ENUM_VALUE( DECR_WRAP );
END_ENUM_SERIALIZER(); // _zfail
BEGIN_ENUM_SERIALIZER2( StencilPassAndDepthPassOperation, osg::Stencil::Operation, KEEP );
ADD_ENUM_VALUE( KEEP );
ADD_ENUM_VALUE( ZERO );
ADD_ENUM_VALUE( REPLACE );
ADD_ENUM_VALUE( INCR );
ADD_ENUM_VALUE( DECR );
ADD_ENUM_VALUE( INVERT );
ADD_ENUM_VALUE( INCR_WRAP );
ADD_ENUM_VALUE( DECR_WRAP );
END_ENUM_SERIALIZER(); // _zpass
ADD_HEXINT_SERIALIZER( WriteMask, ~0u ); // _writeMask
}

View File

@@ -0,0 +1,79 @@
#include <osg/StencilTwoSided>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
BEGIN_USER_TABLE( Function, osg::StencilTwoSided );
ADD_USER_VALUE( NEVER );
ADD_USER_VALUE( LESS );
ADD_USER_VALUE( EQUAL );
ADD_USER_VALUE( LEQUAL );
ADD_USER_VALUE( GREATER );
ADD_USER_VALUE( NOTEQUAL );
ADD_USER_VALUE( GEQUAL );
ADD_USER_VALUE( ALWAYS );
END_USER_TABLE()
USER_READ_FUNC( Function, readFunction )
USER_WRITE_FUNC( Function, writeFunction )
BEGIN_USER_TABLE( Operation, osg::StencilTwoSided );
ADD_USER_VALUE( KEEP );
ADD_USER_VALUE( ZERO );
ADD_USER_VALUE( REPLACE );
ADD_USER_VALUE( INCR );
ADD_USER_VALUE( DECR );
ADD_USER_VALUE( INVERT );
ADD_USER_VALUE( INCR_WRAP );
ADD_USER_VALUE( DECR_WRAP );
END_USER_TABLE()
USER_READ_FUNC( Operation, readOperation )
USER_WRITE_FUNC( Operation, writeOperation )
#define STENCIL_INT_VALUE_FUNC( PROP, TYPE ) \
static bool check##PROP( const osg::StencilTwoSided& attr ) { return true; } \
static bool read##PROP( osgDB::InputStream& is, osg::StencilTwoSided& attr ) { \
TYPE value1; is >> osgDB::PROPERTY("Front") >> value1; \
TYPE value2; is >> osgDB::PROPERTY("Back") >> value2; \
attr.set##PROP(osg::StencilTwoSided::FRONT, value1); \
attr.set##PROP(osg::StencilTwoSided::BACK, value2); return true; } \
static bool write##PROP( osgDB::OutputStream& os, const osg::StencilTwoSided& attr ) { \
os << osgDB::PROPERTY("Front") << attr.get##PROP(osg::StencilTwoSided::FRONT); \
os << osgDB::PROPERTY("Back") << attr.get##PROP(osg::StencilTwoSided::BACK); \
os << std::endl; return true; }
#define STENCIL_USER_VALUE_FUNC( PROP, TYPE ) \
static bool check##PROP( const osg::StencilTwoSided& attr ) { return true; } \
static bool read##PROP( osgDB::InputStream& is, osg::StencilTwoSided& attr ) { \
is >> osgDB::PROPERTY("Front"); int value1 = read##TYPE(is); \
is >> osgDB::PROPERTY("Back"); int value2 = read##TYPE(is); \
attr.set##PROP(osg::StencilTwoSided::FRONT, (osg::StencilTwoSided::TYPE)value1); \
attr.set##PROP(osg::StencilTwoSided::BACK, (osg::StencilTwoSided::TYPE)value2); \
return true; } \
static bool write##PROP( osgDB::OutputStream& os, const osg::StencilTwoSided& attr ) { \
os << osgDB::PROPERTY("Front"); write##TYPE(os, (int)attr.get##PROP(osg::StencilTwoSided::FRONT)); \
os << osgDB::PROPERTY("Back"); write##TYPE(os, (int)attr.get##PROP(osg::StencilTwoSided::BACK)); \
os << std::endl; return true; }
STENCIL_USER_VALUE_FUNC( Function, Function )
STENCIL_INT_VALUE_FUNC( FunctionRef, int )
STENCIL_INT_VALUE_FUNC( FunctionMask, unsigned int )
STENCIL_USER_VALUE_FUNC( StencilFailOperation, Operation )
STENCIL_USER_VALUE_FUNC( StencilPassAndDepthFailOperation, Operation )
STENCIL_USER_VALUE_FUNC( StencilPassAndDepthPassOperation, Operation )
STENCIL_INT_VALUE_FUNC( WriteMask, unsigned int )
REGISTER_OBJECT_WRAPPER( StencilTwoSided,
new osg::StencilTwoSided,
osg::StencilTwoSided,
"osg::Object osg::StateAttribute osg::StencilTwoSided" )
{
ADD_USER_SERIALIZER( Function ); // _func
ADD_USER_SERIALIZER( FunctionRef ); // _funcRef
ADD_USER_SERIALIZER( FunctionMask ); // _funcMask
ADD_USER_SERIALIZER( StencilFailOperation ); // _sfail
ADD_USER_SERIALIZER( StencilPassAndDepthFailOperation ); // _zfail
ADD_USER_SERIALIZER( StencilPassAndDepthPassOperation ); // _zpass
ADD_USER_SERIALIZER( WriteMask ); // _writeMask
}

Some files were not shown because too many files have changed in this diff Show More