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.
This commit is contained in:
Robert Osfield 2010-10-04 15:23:19 +00:00
parent e6559af283
commit 6df7dbf626
5 changed files with 128 additions and 13 deletions

View File

@ -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);

View File

@ -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<std::string> _fields;

View File

@ -336,14 +336,17 @@ public:
virtual bool write( OutputStream& os, const osg::Object& obj )
{
const C& object = OBJECT_CAST<const C&>(obj);
const osg::Matrix& value = (object.*_getter)();
if ( os.isBinary() )
{
OSG_NOTICE<<"MatrixSerializer::write() binary"<<std::endl;
os << value;
}
else if ( ParentType::_defaultValue!=value )
{
OSG_NOTICE<<"MatrixSerializer::write() ascii, ParentType::_name="<<ParentType::_name<<std::endl;
os << PROPERTY((ParentType::_name).c_str()) << value << std::endl;
}
return true;
@ -352,6 +355,9 @@ public:
protected:
void readMatrixImplementation( InputStream& is, osg::Matrix& matrix )
{
#if 1
is >> matrix;
#else
if ( is.getUseFloatMatrix() )
{
osg::Matrixf realValue; is >> realValue;
@ -362,6 +368,7 @@ protected:
osg::Matrixd realValue; is >> realValue;
matrix = realValue;
}
#endif
}
public:

View File

@ -24,7 +24,7 @@ using namespace osgDB;
static std::string s_lastSchema;
InputStream::InputStream( const osgDB::Options* options )
: _byteSwap(0), _useFloatMatrix(true), _useSchemaData(false), _forceReadingImage(false), _dataDecompress(0)
: _byteSwap(0), _useSchemaData(false), _forceReadingImage(false), _dataDecompress(0)
{
if ( !options ) return;
_options = options;
@ -141,27 +141,104 @@ InputStream& InputStream::operator>>( osg::Plane& p )
p.set( p0, p1, p2, p3 ); return *this;
}
#if 0
InputStream& InputStream::operator>>( osg::Matrixf& mat )
{
*this >> PROPERTY("Matrixf") >> 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<float>(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<float>(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<float>(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<ReadType>(typeValue);
unsigned int attributes; *this >> attributes;
if ( attributes&0x1 ) _useFloatMatrix = false;
if ( attributes&0x2 ) _useSchemaData = true;
}
if ( !isBinary() )

View File

@ -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")<<BEGIN_BRACKET << std::endl;
for ( int r=0; r<4; ++r )
{
*this << mat(r, 0) << mat(r, 1)
@ -126,7 +128,7 @@ OutputStream& OutputStream::operator<<( const osg::Matrixf& mat )
OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
{
*this << PROPERTY("Matrixd") << BEGIN_BRACKET << std::endl;
*this << PROPERTY("Matrixd")<<BEGIN_BRACKET << std::endl;
for ( int r=0; r<4; ++r )
{
*this << mat(r, 0) << mat(r, 1)
@ -135,6 +137,31 @@ OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
*this << END_BRACKET << std::endl;
return *this;
}
#else
OutputStream& OutputStream::operator<<( const osg::Matrixf& mat )
{
*this << BEGIN_BRACKET << std::endl;
for ( int r=0; r<4; ++r )
{
*this << (double)mat(r, 0) << (double)mat(r, 1)
<< (double)mat(r, 2) << (double)mat(r, 3) << std::endl;
}
*this << END_BRACKET << std::endl;
return *this;
}
OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
{
*this << 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;
}
#endif
void OutputStream::writeArray( const osg::Array* a )
{
@ -503,8 +530,7 @@ void OutputStream::start( OutputIterator* outIterator, OutputStream::WriteType t
bool useCompressSource = false;
unsigned int attributes = 0;
if ( sizeof(osg::Matrix::value_type)!=FLOAT_SIZE )
attributes |= 0x1; // Record matrix value type of current built OSG
if ( _useSchemaData )
{
attributes |= 0x2; // Record if we use inbuilt schema data or not