Files
OpenSceneGraph/src/osgWrappers/serializers/osg/Geometry.cpp

193 lines
8.0 KiB
C++

#include <osg/Geometry>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
// #define USE_GEOMETRY_FINALIZER_CALLBACK
static void add_user_value_func_AttributeBinding(osgDB::IntLookup* lookup)
{
lookup->add("BIND_OFF",0); // ADD_USER_VALUE("ADD_USER_VALUE( BIND_OFF );
lookup->add("BIND_OVERALL",1); // ADD_USER_VALUE( BIND_OVERALL );
lookup->add("BIND_PER_PRIMITIVE_SET",2); // ADD_USER_VALUE( BIND_PER_PRIMITIVE_SET );
lookup->add("BIND_PER_PRIMITIVE",3); //ADD_USER_VALUE( BIND_PER_PRIMITIVE );
lookup->add("BIND_PER_VERTEX",4); // ADD_USER_VALUE( BIND_PER_VERTEX );
}
static osgDB::UserLookupTableProxy s_user_lookup_table_AttributeBinding(&add_user_value_func_AttributeBinding);
USER_READ_FUNC( AttributeBinding, readAttributeBinding )
USER_WRITE_FUNC( AttributeBinding, writeAttributeBinding )
static osg::Array* readArray( osgDB::InputStream& is)
{
osg::ref_ptr<osg::Array> array;
bool hasArray = false;
is >> is.PROPERTY("Array") >> hasArray;
if ( hasArray ) array = is.readArray();
bool hasIndices = false;
is >> is.PROPERTY("Indices") >> hasIndices;
if ( hasIndices )
{
osg::ref_ptr<osg::Array> indices_array = is.readArray();
osg::ref_ptr<osg::IndexArray> indices = dynamic_cast<osg::IndexArray*>( indices_array.get() );
if (array.valid() && indices.valid()) array->setUserData(indices.get());
}
is >> is.PROPERTY("Binding");
int binding = readAttributeBinding(is);
if (array.valid()) array->setBinding(static_cast<osg::Array::Binding>(binding));
int normalizeValue = 0;
is >> is.PROPERTY("Normalize") >> normalizeValue;
if (array.valid()) array->setNormalize(normalizeValue!=0);
return array.release();
}
static void writeArray( osgDB::OutputStream& os, const osg::Array* array)
{
os << os.PROPERTY("Array") << (array!=0);
if ( array!=0 ) os << array;
else os << std::endl;
const osg::IndexArray* indices = (array!=0) ? dynamic_cast<const osg::IndexArray*>(array->getUserData()) : 0;
os << os.PROPERTY("Indices") << (indices!=0);
if ( indices!=0 ) os << indices;
else os << std::endl;
os << os.PROPERTY("Binding"); writeAttributeBinding(os, osg::getBinding(array)); os << std::endl;
os << os.PROPERTY("Normalize") << ((array!=0 && array->getNormalize()) ? 1:0) << std::endl;
}
#define ADD_ARRAYDATA_FUNCTIONS( ORIGINAL_PROP, PROP ) \
static bool check##ORIGINAL_PROP( const osg::Geometry& geom ) \
{ return geom.get##PROP()!=0; } \
static bool read##ORIGINAL_PROP( osgDB::InputStream& is, osg::Geometry& geom ) { \
is >> is.BEGIN_BRACKET; \
osg::Array* array = readArray(is); \
geom.set##PROP(array); \
is >> is.END_BRACKET; \
return true; \
} \
static bool write##ORIGINAL_PROP( osgDB::OutputStream& os, const osg::Geometry& geom ) { \
os << os.BEGIN_BRACKET << std::endl; \
writeArray(os, geom.get##PROP()); \
os << os.END_BRACKET << std::endl; \
return true; \
}
ADD_ARRAYDATA_FUNCTIONS( VertexData, VertexArray )
ADD_ARRAYDATA_FUNCTIONS( NormalData, NormalArray )
ADD_ARRAYDATA_FUNCTIONS( ColorData, ColorArray )
ADD_ARRAYDATA_FUNCTIONS( SecondaryColorData, SecondaryColorArray )
ADD_ARRAYDATA_FUNCTIONS( FogCoordData, FogCoordArray )
#define ADD_ARRAYLIST_FUNCTIONS( ORIGINAL_PROP, PROP, LISTNAME ) \
static bool check##ORIGINAL_PROP( const osg::Geometry& geom ) \
{ return geom.get##LISTNAME().size()>0; } \
static bool read##ORIGINAL_PROP( osgDB::InputStream& is, osg::Geometry& geom ) { \
unsigned int size = is.readSize(); is >> is.BEGIN_BRACKET; \
for ( unsigned int i=0; i<size; ++i ) { \
is >> is.PROPERTY("Data") >> is.BEGIN_BRACKET; \
osg::Array* array = readArray(is); \
geom.set##PROP(i, array); \
is >> is.END_BRACKET; } \
is >> is.END_BRACKET; \
return true; \
} \
static bool write##ORIGINAL_PROP( osgDB::OutputStream& os, const osg::Geometry& geom ) { \
const osg::Geometry::ArrayList& LISTNAME = geom.get##LISTNAME(); \
os.writeSize(LISTNAME.size()); os << os.BEGIN_BRACKET << std::endl; \
for ( osg::Geometry::ArrayList::const_iterator itr=LISTNAME.begin(); \
itr!=LISTNAME.end(); ++itr ) { \
os << os.PROPERTY("Data") << os.BEGIN_BRACKET << std::endl; \
writeArray(os, itr->get()); os << os.END_BRACKET << std::endl; \
} \
os << os.END_BRACKET << std::endl; \
return true; \
}
ADD_ARRAYLIST_FUNCTIONS( TexCoordData, TexCoordArray, TexCoordArrayList )
ADD_ARRAYLIST_FUNCTIONS( VertexAttribData, VertexAttribArray, VertexAttribArrayList )
struct GeometryFinishedObjectReadCallback : public osgDB::FinishedObjectReadCallback
{
virtual void objectRead(osgDB::InputStream&, osg::Object& obj)
{
osg::Geometry& geometry = static_cast<osg::Geometry&>(obj);
if (geometry.getUseVertexBufferObjects())
{
geometry.setUseVertexBufferObjects(false);
geometry.setUseVertexBufferObjects(true);
}
}
};
// implement backwards compatibility with reading/writing the FastPathHint
static bool checkFastPathHint( const osg::Geometry& geom ) { return false; }
static bool readFastPathHint( osgDB::InputStream& is, osg::Geometry& geom )
{
// Compatibility info:
// Previous Geometry wrapper (before 3.1.8) require a bool fast-path serializer.
// It saves "FastPathHint true" in ascii mode and a single [bool] in binary mode.
// Becoming a user serializer, the serializer will first read the name "FastPathHint"
// or a [bool] in the checking process, then call the reading function as here. So,
// we will only need to read one more bool variable in ascii mode; otherwise do nothing
bool value = false;
if ( !is.isBinary() ) is >> value;
return true;
}
static bool writeFastPathHint( osgDB::OutputStream& os, const osg::Geometry& geom )
{
return true;
}
REGISTER_OBJECT_WRAPPER( Geometry,
new osg::Geometry,
osg::Geometry,
"osg::Object osg::Node osg::Drawable osg::Geometry" )
{
{
UPDATE_TO_VERSION_SCOPED( 154 )
ADDED_ASSOCIATE("osg::Node")
}
//ADD_LIST_SERIALIZER( PrimitiveSetList, osg::Geometry::PrimitiveSetList ); // _primitives
ADD_VECTOR_SERIALIZER( PrimitiveSetList, osg::Geometry::PrimitiveSetList, osgDB::BaseSerializer::RW_OBJECT, 0 );
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_USER_SERIALIZER( FastPathHint ); // _fastPathHint
{
UPDATE_TO_VERSION_SCOPED( 112 )
REMOVE_SERIALIZER( VertexData );
REMOVE_SERIALIZER( NormalData );
REMOVE_SERIALIZER( ColorData );
REMOVE_SERIALIZER( SecondaryColorData );
REMOVE_SERIALIZER( FogCoordData );
REMOVE_SERIALIZER( TexCoordData );
REMOVE_SERIALIZER( VertexAttribData );
REMOVE_SERIALIZER( FastPathHint );
ADD_OBJECT_SERIALIZER( VertexArray, osg::Array, NULL );
ADD_OBJECT_SERIALIZER( NormalArray, osg::Array, NULL );
ADD_OBJECT_SERIALIZER( ColorArray, osg::Array, NULL );
ADD_OBJECT_SERIALIZER( SecondaryColorArray, osg::Array, NULL );
ADD_OBJECT_SERIALIZER( FogCoordArray, osg::Array, NULL );
ADD_VECTOR_SERIALIZER( TexCoordArrayList, osg::Geometry::ArrayList, osgDB::BaseSerializer::RW_OBJECT, 0 );
ADD_VECTOR_SERIALIZER( VertexAttribArrayList, osg::Geometry::ArrayList, osgDB::BaseSerializer::RW_OBJECT, 0 );
}
#ifdef USE_GEOMETRY_FINALIZER_CALLBACK
wrapper->addFinishedObjectReadCallback( new GeometryFinishedObjectReadCallback() );
#endif
}