Hi Robert,
Sorry for my very slow response because of some personal issues. I found
that new Geometry serializers can't work with old .osgb files. The modified
FastPathHint serializer doesn't correctly read from the stream and
thus jumbles following inputs. The file attached can be placed in
osgWrappers/serializers/osg to fix that problem.
Cheers,
Wang Rui
#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 );
lookup->add("BIND_PER_PRIMITIVE",3); //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 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, (array!=0) ? static_cast<osg::Geometry::AttributeBinding>(array->getBinding()) : osg::Geometry::BIND_OFF); 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::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_USER_SERIALIZER( FastPathHint ); // _fastPathHint
wrapper->addFinishedObjectReadCallback( new GeometryFinishedObjectReadCallback() );
}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org