Commit Graph

28 Commits

Author SHA1 Message Date
Robert Osfield
dd996a3289 Introduced CMake option OSG_PROVIDE_READFILE option that defaults to ON, but when switched to OFF disables the building of the osgDB::read*File() methods,
forcing users to use osgDB::readRef*File() methods.  The later is preferable as it closes a potential threading bug when using paging databases in conjunction
with the osgDB::Registry Object Cache.  This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only
a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another
thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero.  Using osgDB::readREf*File() makes sure the a ref_ptr<> is
passed back and the referenceCount never goes to zero.

To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File()
usage.  The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of
templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group:

    bool addChild(Node* child); // old method which can only be used with a Node*

    tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method

These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache
and multi-threaded loaded more robust.



git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15164 16af8721-9629-0410-8352-f15c8da7e697
2015-10-22 13:42:19 +00:00
Robert Osfield
7f592b7ad5 Added handling of the reading of field properties to a dummy object for cached images to avoid threading issues associated with reusing and modifying an active object.
git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14469 16af8721-9629-0410-8352-f15c8da7e697
2014-11-05 16:08:42 +00:00
Robert Osfield
4ef5d9eb5f Added Vector serialization and support in lua plugin top enable script users to set/get vector properties such as osg::Array, osg::PrimitiveSet and children lists. 2014-02-24 10:19:48 +00:00
Robert Osfield
31e98b51df Added support for serailizing and scripting BoundingBox and BoundingSphere objects 2014-02-10 16:44:13 +00:00
Robert Osfield
4fd6566e00 From David Callu, serializer support for new Vec* and Vec*Array classes 2013-06-28 08:57:42 +00:00
Robert Osfield
48020eed9e Introduced typedef's to make the code more readble and maintanable 2013-06-24 09:02:32 +00:00
Robert Osfield
4044fd5a74 From Wang Rui, "The file attached includes two new features for the serialization IO functionality. First, custom serializer version control should work now, just by defining a new REGISTER_CUSTOM_OBJECT_WRAPPER macro. For example:
// A custom class
namespace CustomDomain {

class MyGroup : public osg::Group
{
public:
    META_Node( CustomDomain, MyGroup );

    void setMyName( const std::string& n );
    const std::string& getMyName() const;

    void setMyID( int id );
    int getMyID() const;

    ...
};

}

// The serialization wrapper using a custom domain name
REGISTER_CUSTOM_OBJECT_WRAPPER( MyDomain,
                                CustomDomain_MyGroup,
                                new CustomDomain::MyGroup,
                                CustomDomain::MyGroup,
                                "osg::Object osg::Node osg::Group CustomDomain::MyGroup" )
{
    ADD_STRING_SERIALIZER( MyName, std::string() );
    {
        UPDATE_TO_VERSION_SCOPED( 1 );  // Updated for a new domain version
        ADD_INT_SERIALIZER( MyID, 0 );
    }
}

Save the class instance as follows:
osgDB::writeNodeFile( *myGroup, "serializer_test.osgt", new osgDB::Options("CustomDomains=MyDomain:1") );

The output file will include the domain version definition and all the class data, and can be read back. We can also force setting the domain version by the CustomDomains option while reading the saved files. If we save the class instance without any options, MyID will be ignored because the default domain version is 0.

This may help third-party libraries like osgEarth to maintain their own serializers without regarding to the OSG soversion changes.

Another feature added is a more robust binary format, which in fact adds a size-offset at each block's beginning. When there are problems or unsupported data types while reading, we can now directly jump to the block end indicated by the offset value. So a .osgb file will automatically ignore bad data and read remains as normal (at present it will fail at all). This feature will not break the backward compatibility, and can be disabled by setting "RobustBinaryFormat=false" while writing out.

Hope these changes can work smoothly with present and future community projects. Maybe we should also consider have an osgserializer example to test and demonstrate all things we can do now."
2013-06-24 08:48:55 +00:00
Robert Osfield
ae2b6669ea Added Vec*b, Vec4ub, Vec*s, Vec*i, Vec*ui serializers 2013-06-03 13:13:18 +00:00
Robert Osfield
5e315d5fab From Wang Rui, "I'd like to submit the changes that will put ObjectProperty and ObjectMark variables into the InputStream/OutputStream class instead of static ones. This should avoid the threading problem and won't repeatedly reallocate memory for the properties. Some of the wrappers will be slightly modified to use the property variable stored in the InputStream/OutputStream as well." 2012-04-05 13:53:47 +00:00
Robert Osfield
14a563dc9f Ran script to remove trailing spaces and tabs 2012-03-21 17:36:20 +00:00
Robert Osfield
9c5774defb Improved the handling of endian swap of osg::Array 2012-02-29 10:22:56 +00:00
Robert Osfield
e8ac276451 Added s/getByteSwap to teh InputStreamOperator base class and use of this method in the InputStream::start(InputStreamOperator*) method to ensure the bytes are swapped consistently. 2012-02-24 21:07:02 +00:00
Robert Osfield
caceb94db8 From Miha Ravsel, "While trying to create my custom serializer class, i created some dummy data which accidentally popped-up bug in InputStream readObjectFields function.
Bug description:
 Let's say we have class A
namespace Bug
{
class A : public osg::Object
{
public:
  //...
  typedef std::vector<osg::ref_ptr<A> > AList;

protected:
  AList _alist;
  //...
}
}

REGISTER_OBJECT_WRAPPER( A,
                        new Bug::A,
                        Bug::A,
                        "osg::Object Bug::A" )
{
       ADD_LIST_SERIALIZER(A,Bug::A::AList);
}


Bug:
We create say 3 instances of class A: A1,A2,A3 and then we add A2 and A3 and A1 as child instances of A1 so we get next structure:
A1
 |- A2,A3,A1

we call osgDB::writeObjectFile(A1,"/data/a.osgt") -> saved correctly( third element in list is saved as unique id that references parentClass

now we call
A1 = osgDB::readObjectFile("/data/a.osgt");

Everything is deserialized correctely except last element in list which should be same instance as parent A1.

The attached code resolves this issue by passing UniqueID in readObjectFields method and saving object in _identifierMap as soon as we have valid object instance so we can make reference to parent object from any child instance.
"
2012-02-22 10:46:35 +00:00
Robert Osfield
de040e44a0 From Rafa Gata, I've been playing around with serializers in order to use it as a
"generic" property mechanism for osg::Object.

The main problem I have found is that InputStream and OutputStream
only takes the stream when you call start method, and in that case it
attaches to the stream buffer some stuff, useful for files but not for
runtime/gui usage. I have added a simple setInputIterator and
setOutputIterator to the classes so now you can easily serialize
values without version and other stuff.

Writing matrix:
osgDB::OutputStream os(0);
std::stringstream sstream;
os.setOutputIterator(new AsciiOutputIterator(&sstream));
os << matrix;
std::string value = sstream.str();

Reading matrix:
osgDB::InputStream is(0);
std::stringstream sstream(value);
is.setInputIterator(new AsciiInputIterator(&sstream));
osg::Matrixf mat2;
is >> mat2;

From Robert Osfield, added doxygen comments to clarify the role of the methods.
2011-05-16 08:50:59 +00:00
Robert Osfield
b0dd272186 From Brad Christiansen, "Attached is a fix which implements the lazy loading of optional layers (if requested) in the new osgb/osgt formats." 2011-01-14 11:00:11 +00:00
Robert Osfield
f61a6aa4e7 Refactored the way that the DatabasePager passes the Terrain decorator node onto the TerrainTile.
The DatabasePager now passes the Terrain pointer into the ReaderWriter's via osgDB::Options object,
rather than pushing a NodePath containing the Terrain onto NodeVisitor.  This
change means that the DatabasePager nolonger needs to observer the whole NodePath and
will be lighter and quicker for it.

The change also means that ReadFileCallback can now run custom NodeVisitor's on the scene graph without
having to worry about TerrainTile's constructing scene graphs prior to the Terrain being assigned.

Also changed is the NodeVisitor::DatabaseRequestHandler which now requires a NodePath to the node that you wish
to add to rather than just the pointer to the node you wish to add to.  This is more robust when handling scenes
with multiple parental paths, whereas previously errors could have occurred due to the default of picking the first
available parental path.  This change means that subclasses of DatabasePager will need to be updated to use this new
function entry point.
2011-01-12 19:29:24 +00:00
Robert Osfield
b8a94a6d4e From Wang Rui, "I'd like to submit my latest modification of the serialization IO
functionalities. It includes two main parts: a version checking macro
for handling backward-compatiblity since 3.0, and enhencement of
current schema mechanism. I also change the option handling process to
use getPluginStringData(), and add new USE_SERIALIZER_WRAPPER macro in
the Registry header to allow for static-link usage as well.

The enhencement of schema machanism just tells the type of each
serializer while outputting them, such as:
osg::Group = Children:1

The meaning of the number can be found in the osgDB/Serializer header,
BaseSerializer::Type enum. It may help 3rdparty utilities understand
the structure of the wrapper and do some reflection work in the
future.

The new macro UPDATE_TO_VERSION can help indicate the InputStream (no
affect on the writer) that a serializer is added/removed since certain
OSG version. An example wrapper file is also attached. The
Geode_modified.cpp is based on the serializers/osg/Geode.cpp file
(hey, don't merge it :-), but assumes that a new user serializer
'Test' is added since version 65 (that is, the OSG_SOVERSION):

REGISTER_OBJECT_WRAPPER( Geode, ... )
{
   ADD_USER_SERIALIZER( Drawables );  // origin ones

   UPDATE_TO_VERSION( 65 )
   {
       ADD_USER_SERIALIZER( Test );  // a serializer added from version 65
   }
}

All kinds of ADD_... macros following UPDATE_TO_VERSION will
automatically apply the updated version. The braces here are only for
typesetting!
While reading an osgt/osgb/osgx file, OSG will now check if the file
version (recorded as the writer's soversion, instead of previous
meaningless "#Version 2") is equal or greater than Test's version, and
try reading it, or just ignore it if file version is lesser.

And we also have the REMOVE_SERIALIZER macro will mark a named
serializer as removed in some version, with which all files generated
by further versions will just ignore it:

UPDATE_TO_VERSION( 70 )
{
   REMOVE_SERIALIZER( Test );
}

This means that from version 70, the serializer Test is removed (but
not actually erased from the list) and should not be read anymore. If
the read file version is less than 70 (and equal or greater than 65),
Test will still be handled when reading; otherwise it will be ignored
to keep compatiblity on different OSG versions.
"
2010-11-09 12:41:55 +00:00
Robert Osfield
6df7dbf626 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.
2010-10-04 15:23:19 +00:00
Robert Osfield
d9a133476a Refactored the handling of readImage/writeImage/readObject/writeObject to avoid double setting of unique ID's, fixing the problem in reading/writing files with images 2010-09-23 16:12:05 +00:00
Robert Osfield
0c84f2deff From Cedric Pinson, "Here a fix about a leak in InputStream::decompress
I changed
       _in->setStream( new std::stringstream(data) );
to
       _dataDecompress = new std::stringstream(data);
       _in->setStream( _dataDecompress );

Then when the destructor is of InputStream is called I delete the
dataDecompress stringstream.
"
2010-06-15 10:02:34 +00:00
Robert Osfield
42527fe859 From Wang Rui, "I'd like to submit my inbuilt schema data support of
the OutputStream/InputStream implementations, which was just finished
last weekend with a few tests on Windows and Ubuntu. Hope it could
work and get more feedbacks soon.

I've added a new option "SchemaData" to the osg2 plugin. Developers
may test the new feature with the command line:

# osgconv cow.osg cow.osgb -O SchemaData

It will record all serializer properties used in the scene graph, at
the beginning of the generated file. And when osgviewer and user
applications is going to read the osgb file, the inbuilt data will be
automatically read and applied first, to keep backwards compatibility
partly. This will not affect osgb files generated with older versions.
"
2010-05-12 20:02:31 +00:00
Robert Osfield
e082b01f26 From Wang Rui, "I've initially added the XML support of the new native osg format,
using osgDB::XmlParser. The extension for XML-formatted scenes is
.osgx, corresponding to .osgb for binary and .osgt for ascii. It could
either be rendered in osgviewer or edited by common web browsers and
xml editors because of a range of changes to fit the XML syntax. For
example, the recorded class names are slight modified, from
'osg::Geode' to 'osg--Geode'.

To quickly get an XML file:
# ./osgconv cow.osg cow.osgx

The StreamOperator header, InputStreram and OutputStream classes are
modified to be more portable for triple ascii/binary/XML formats. I
also fixed a bug in readImage()/writeImage() to share image objects if
needed.

The ReaderWriterOSG2 class now supports all three formats and
reading/writing scene objects (not nodes or images), thanks to
Torben's advice before.
"
2010-03-10 13:48:41 +00:00
Robert Osfield
605ad76691 From Wang Rui, "Attached is the osgTerrain wrappers, based on the latest SVN version
of OSG. I modified the osgDB::InputStream and OutputStream and the
PagedLOD wrapper as well. Now all seems to work fine with paged
scenes. I've tested with the puget terrain data and the osgdem
application from VPB:
# osgdem --xx 10 --yy 10 -t ps_texture_4k.tif --xx 10 --yy 10 -d
ps_height_4k.tif -l 8 -v 0.1 -o puget.osgb

As the ive plugin does, The PagedLOD wrapper now automatically add the
latest file path to PagedLODs' databasePath member, to help them find
correct child positions. I also changed the image storage strategy of
the OutputStream class, to store them inline by default. The osgt
extension should also work, in case the image files are also written
to the disk.
"
2010-02-25 17:53:51 +00:00
Robert Osfield
5b1ca779e4 Added OutputStream::writeSize and InputStream::readSize methods to help out with ensure that 32bit and 64bit builds all
use the same 32bit type for sizes.
2010-02-10 17:03:09 +00:00
Robert Osfield
0a9263d50e From Wang Rui, "Changes:
1. Rewrite the reading/writing exception handlers to work like the ive
plugin exceptions.
2. Write a header writing/checking function in ReaderWriterOSG2.cpp,
which may help decide if the stream is ascii or binary. The
readInputIterator() function will return null pointer if the input
file is nither osgb nor osgt format, which indicates that the old .osg
format could be used here, in case we've merged the two plugins
together.
3. Add a new ForceReadingImage option in the InputStream, which will
allocate an empty image object with the filename if specifed external
image file is missed. It may be useful for format converting in some
cases.
4. Add new osgParticle wrappers, as well as some modification to the
osgParticle headers, for instance, change isEnabled() to getEnabled().
5. Some fixes to the osg serialization wrappers."
2010-01-27 17:09:05 +00:00
Robert Osfield
a520e8b6bd From Wang Rui, refactored the InputStream/OutputStream operations so that the binar/ascii foramts are implemented via subclasses. 2010-01-25 11:03:21 +00:00
Robert Osfield
f1bd2eaf04 From Wang Rui, added exports for windows build 2010-01-21 09:25:45 +00:00
Robert Osfield
219696f1ee From Wang Rui, new native binary/ascii format infrastructure and wrappers.
From Robert Osfield, refactor of Wang Rui's original osg2 into 3 parts - parts placed into osgDB, the ReaderWriter placed into src/osg/Plugin/osg and wrappers into src/osgWrappers/serializers/osg
2010-01-20 20:13:33 +00:00