From 6df7dbf626be7a1dc113a7fd85dff8a0e21898b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 4 Oct 2010 15:23:19 +0000 Subject: [PATCH] Improved the handling of matrices in serialization so that it's more reliable, change was to use doubles for reading and writing matrices regardless of type of Matrix being serialized. Change does break backwards compatibility though, so code path supporting original format has been left in for the time being. However, this code is not reliable enough and is over complicated compared to the simplified handling. Once the new code has been bedded down for a while I'll remove this code block. --- include/osgDB/DataTypes | 12 +++++- include/osgDB/InputStream | 2 - include/osgDB/Serializer | 7 ++++ src/osgDB/InputStream.cpp | 86 +++++++++++++++++++++++++++++++++++--- src/osgDB/OutputStream.cpp | 34 +++++++++++++-- 5 files changed, 128 insertions(+), 13 deletions(-) diff --git a/include/osgDB/DataTypes b/include/osgDB/DataTypes index 7397fa495..8014c244e 100644 --- a/include/osgDB/DataTypes +++ b/include/osgDB/DataTypes @@ -84,8 +84,9 @@ struct ObjectGLenum #define GLENUM(value) osgDB::ObjectGLenum(value) #define DEF_GLENUM(var) osgDB::ObjectGLenum var; -struct ObjectProperty +class ObjectProperty { +public: ObjectProperty( const char* name, int value=0, bool useMap=false ) : _name(name), _value(value), _mapProperty(useMap) {} @@ -101,6 +102,9 @@ struct ObjectProperty std::string _name; int _value; bool _mapProperty; + +protected: + ObjectProperty():_value(0),_mapProperty(false) {} }; static ObjectProperty defaultProp(""); @@ -109,8 +113,9 @@ static ObjectProperty defaultProp(""); #define DEF_PROPERTY(name, var) osgDB::ObjectProperty var(name); #define DEF_MAPPEE(pairName, var) osgDB::ObjectProperty var(#pairName, 0, true); -struct ObjectMark +class ObjectMark { +public: ObjectMark( const char* name, int delta=0 ) : _name(name), _indentDelta(delta) {} @@ -119,6 +124,9 @@ struct ObjectMark std::string _name; int _indentDelta; + +protected: + ObjectMark():_indentDelta(0) {} }; static ObjectMark BEGIN_BRACKET("{", +INDENT_VALUE); static ObjectMark END_BRACKET ("}", -INDENT_VALUE); diff --git a/include/osgDB/InputStream b/include/osgDB/InputStream index 749c98473..6736fe809 100644 --- a/include/osgDB/InputStream +++ b/include/osgDB/InputStream @@ -69,7 +69,6 @@ public: virtual ~InputStream(); bool isBinary() const { return _in->isBinary(); } - bool getUseFloatMatrix() const { return _useFloatMatrix; } const osgDB::Options* getOptions() const { return _options.get(); } // Serialization related functions @@ -161,7 +160,6 @@ protected: IdentifierMap _identifierMap; int _byteSwap; - bool _useFloatMatrix; bool _useSchemaData; bool _forceReadingImage; std::vector _fields; diff --git a/include/osgDB/Serializer b/include/osgDB/Serializer index f58f0cb49..bf28e6796 100644 --- a/include/osgDB/Serializer +++ b/include/osgDB/Serializer @@ -336,14 +336,17 @@ public: virtual bool write( OutputStream& os, const osg::Object& obj ) { + const C& object = OBJECT_CAST(obj); const osg::Matrix& value = (object.*_getter)(); if ( os.isBinary() ) { + OSG_NOTICE<<"MatrixSerializer::write() binary"<> BEGIN_BRACKET; + ObjectProperty property(""); + *this >> property >> BEGIN_BRACKET; + + if (property._name == "Matrixf") + { + // stream has same type as what we want to read so read directly + for ( int r=0; r<4; ++r ) + { + *this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3); + } + } + else if (property._name == "Matrixd") + { + // stream has different type than what we want to read so read stream into + // a temporary and then copy across to the final matrix + double value; + for ( int r=0; r<4; ++r ) + { + for ( int c=0; c<4; ++c) + { + *this >> value; + mat(r,c) = static_cast(value); + } + } + } + + *this >> END_BRACKET; + return *this; +} + +InputStream& InputStream::operator>>( osg::Matrixd& mat ) +{ + ObjectProperty property(""); + *this >> property >> BEGIN_BRACKET; + + if (property._name == "Matrixf") + { + // stream has different type than what we want to read so read stream into + // a temporary and then copy across to the final matrix + float value; + for ( int r=0; r<4; ++r ) + { + for ( int c=0; c<4; ++c) + { + *this >> value; + mat(r,c) = static_cast(value); + } + } + } + else if (property._name == "Matrixd") + { + // stream has same type as what we want to read so read directly + 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; +} +#else +InputStream& InputStream::operator>>( osg::Matrixf& mat ) +{ + *this >> BEGIN_BRACKET; + + // stream has different type than what we want to read so read stream into + // a temporary and then copy across to the final matrix + double value; for ( int r=0; r<4; ++r ) { - *this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3); + for ( int c=0; c<4; ++c) + { + *this >> value; + mat(r,c) = static_cast(value); + } } + *this >> END_BRACKET; return *this; } InputStream& InputStream::operator>>( osg::Matrixd& mat ) { - *this >> PROPERTY("Matrixd") >> BEGIN_BRACKET; + *this >> 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; } +#endif osg::Array* InputStream::readArray() { @@ -642,7 +719,6 @@ InputStream::ReadType InputStream::start( InputIterator* inIterator ) type = static_cast(typeValue); unsigned int attributes; *this >> attributes; - if ( attributes&0x1 ) _useFloatMatrix = false; if ( attributes&0x2 ) _useSchemaData = true; } if ( !isBinary() ) diff --git a/src/osgDB/OutputStream.cpp b/src/osgDB/OutputStream.cpp index 7d15c4276..2db0cd2a1 100644 --- a/src/osgDB/OutputStream.cpp +++ b/src/osgDB/OutputStream.cpp @@ -112,9 +112,11 @@ OutputStream& OutputStream::operator<<( const osg::Quat& q ) OutputStream& OutputStream::operator<<( const osg::Plane& p ) { *this << (double)p[0] << (double)p[1] << (double)p[2] << (double)p[3]; return *this; } + +#if 0 OutputStream& OutputStream::operator<<( const osg::Matrixf& mat ) { - *this << PROPERTY("Matrixf") << BEGIN_BRACKET << std::endl; + *this << PROPERTY("Matrixf")<