[osg-users] osgDB - Serialize osg::Object subclass to human readable "osg" format

15 views
Skip to first unread message

peter klosowski

unread,
Mar 17, 2013, 4:45:42 PM3/17/13
to OpenSceneGraph Users
Hi,

I have created a new class derived from osg::Object. I would like to add the ability to serialize the class to the human readable "osg" format. Currently, serialization only works for "osgb".

Here is a simplified version of my code:

// In "MyObject", I have:

namespace osgMyLibrary {

class MyObject: public osg::Object
{
public:
MyObject(): _symbol("") {}
MyObject(MyObject const& other, osg::CopyOp const& = osg::CopyOp::SHALLOW_COPY): _symbol(other._symbol) {}

std::string const& getSymbol() const { return _symbol; }
void setSymbol(std::string const& symbol) { _symbol = symbol; }

META_Object(osgMyLibrary, MyObject);

protected:
// Use reference counting.
virtual ~MyObject(); 

private:
std::string _symbol;
};

}

// In "MyObject.cpp", I have:

REGISTER_OBJECT_WRAPPER(MyObject, new osgMyLibrary::MyObject, osgMyLibrary::MyObject, "osg::Object osgMyLibrary::MyObject")
{
ADD_STRING_SERIALIZER(Symbol, "#1");
}

// In "main.cpp", I have:

osg::ref_ptr<osgMyLibrary::MyObject> test = new osgMyLibrary::MyObject();
std::ostringstream sstream;
osgDB::ReaderWriter::WriteResult wr = osgDB::Registry::instance()->getReaderWriterForExtension("osg")->writeObject(*test, sstream, 0);
std::cout << sstream.str() << std::endl;

However, nothing is written to the console. If I change the extension to "osgb", I can see the object, but it is obviously using the binary format. What do I need to change in order to get human readable serialization?

Cheers,
Peter

Robert Osfield

unread,
Mar 17, 2013, 6:12:50 PM3/17/13
to OpenSceneGraph Users

Try using the .osgt extension rather than .osg.

_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

peter klosowski

unread,
Mar 17, 2013, 6:58:09 PM3/17/13
to OpenSceneGraph Users
Oddly enough, "osgt" also gives me the binary format, even when serializing objects from the core library, e.g.:

osg::ref_ptr<osg::Node> test = new osg::Node;
std::ostringstream sstream;
osgDB::ReaderWriter::WriteResult wr = osgDB::Registry::instance()->getReaderWriterForExtension("osgt")->writeObject(*test, sstream, 0);
std::cout << sstream.str() << std::endl;

Results in output:

í♫ælEE¹→♥   _       ☺   0          osg::Node☺       ☻         ☺

However, e.g.:

osg::ref_ptr<osg::Node> test = new osg::Node;
std::ostringstream sstream;
osgDB::ReaderWriter::WriteResult wr = osgDB::Registry::instance()->getReaderWriterForExtension("osg")->writeObject(*test, sstream, 0);
std::cout << sstream.str() << std::endl;

Results in output:

Node {
  nodeMask 0xffffffff
  cullingActive TRUE
}

Which is what I want, but for my custom object. With that, I get equivalent results in the first case and nothing in the second.

(I am using OpenSceneGraph 3.1.4, if that matters.)

Cheers,
Peter

Robert Osfield

unread,
Mar 18, 2013, 6:05:10 AM3/18/13
to OpenSceneGraph Users
Hi Peter,

Looking at the plugin implementation it'll be the fact that the same
ReaderWriter is used for all of the .osgt, .osgb and .osgx formats, if
you use a readObject()/writeObject() with a filename the plugin will
automatically set the type of file, but if you use a
std::istream/ostream then it'll look to the Option string to see what
type to read. To select .osgt ascii add an "Ascii" entry into the
osgDB::Option::OptionString.

The code in src/osgPlugin/osg/ReaderWriterOSG2.cpp that does the
automatically assignment from the extension to the OptionsString is in
prepareReading and prepareWriting method and looks like:

if ( ext=="osgt" ) local_opt->setOptionString(
local_opt->getOptionString() + " Ascii" );
else if ( ext=="osgx" ) local_opt->setOptionString(
local_opt->getOptionString() + " XML" );

So adding this in yourself will be the thing to do.

Robert.

peter klosowski

unread,
Mar 18, 2013, 8:16:17 AM3/18/13
to OpenSceneGraph Users
Ah yes, that did the trick. Thank you very much!

Here's the code in case anybody else needs it:

osg::ref_ptr<osgMyLibrary::MyObject> test = new osgMyLibrary::MyObject;

std::ostringstream sstream;
osg::ref_ptr<osgDB::Options> options = new osgDB::Options("Ascii");
osgDB::ReaderWriter::WriteResult wr = osgDB::Registry::instance()->getReaderWriterForExtension("osgt")->writeObject(*test, sstream, options);
std::cout << sstream.str() << std::endl;

So am I understanding correctly that "osg" and "osgt" are actually different formats (and custom serialization automatically works with "osgt", but not "osg")?

Cheers,
Peter

Robert Osfield

unread,
Mar 18, 2013, 9:01:10 AM3/18/13
to OpenSceneGraph Users
Hi Peter.

> So am I understanding correctly that "osg" and "osgt" are actually different
> formats (and custom serialization automatically works with "osgt", but not
> "osg")?

The .osg format is the old deprecated ascii format, that is still
supported for backwards compatibility. The .ive binary format is also
deprecated but still supported. These two formats are hand written
and independent from one another so require tool lots of hand written
wrappers, and .ive is user extensible.

The new .osgb, .osgt and .osgx file formats are a family of formats
that are all leverage the new object serializers that are user
extensible and resilient to versioning. Once you implement your
serializers you get automatic support for all these formats. The
serializers are also much easier to write than either then .osg or
.ive wrappers. So all round goodness :-)

Robert.

peter klosowski

unread,
Mar 18, 2013, 9:28:29 AM3/18/13
to OpenSceneGraph Users
Makes sense and sounds excellent. Thanks again for clearing this up!

Cheers,
Peter
Reply all
Reply to author
Forward
0 new messages