the wrappers it contains. The registration creates a prototype
object for all of the wrapped classes. For some of the higher-level
classes this can be a bit heavy.
I noticed a problem with a model which required a single class from
osgSim. When osgdb_serializers_osgsim.so was loaded it registered
wrappers and created prototype objects for all of the osgSim classes,
including osgSim::ScalarBar. The constructor for that class creates
several drawables, and loads arial.ttf using the freetype plugin. I
don't need that, and don't even ship the font or plugin with my
application, resulting in an unexplained warning message loading
the model.
I've modified the ObjectWrapper class to defer the prototype object
creation until if & when actually required."
// 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."
* ZeroConfDevice does now return FILE_NOT_HANDLED instead of FILE_NOT_FOUND
* present3D supports multiple devices per env-var P3D_DEVICE, separate multiple device with a space
I refactored parts the p3d-plugin, the curl-plugin and parts of Registry and ReaderWriter. Currently the p3d-plugin tries to open all remote files with the help of the curl-plugin.
I added a new method to Registry called getReaderWriterForProtocolAndExtension. which will return a ReaderWriter which is capable in handling the remote file for the given protocol and extension. If no readerwriter is found for the given extension, a list is built of all readerwriters supporting the given protocol and this list is checked for support of wildcards (extension = "*"). If anything matches it get returned.
I added this principle also to the Registry, so now it's possible to register a generic ReaderWriter which can handle all filetypes for a given protocol, similar what curl is doing. All you have to do is to load the plugin at startup. The curl-fallback is still in place.
With these changes it is now possible to reference a movie inside a presentation without a server-address, read the presentation (with curl) and stream the movie with the correct plugin (e.g. QTKit)
"
Added template readFile(..) function to make it more convinient to cast to a specific object type.
Added support for osgGA::Device to osgViewer.
Added sdl plugin to provides very basic joystick osgGA::Device integration.
macro, which could set version within brackets and reset it after
that. All related serializers are also modified so that the
backward-compatibility bug reported by Farshid can be fixed.
"
From Robert Osfield, removed the use of osg::Referenced and creating the proxy object on the heap.
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.
"
I think the best way to achieve this is to overwrite the DatabasePager::addDatabaseThread() method within the customized database pager. However this method is not 'virtual' yet, so I propose to make the method 'virtual'."
Here is a quick list of the modified files:
Archive - getDirectoryContents() no longer pure virtual
Archive.cpp - default getDirectoryContents() implementation
unzip.cpp - modified to fix a bug where the same file will not load twice in a row
ZipArchive.h / ZipArchive.cpp - extends osgDB::Archive and provides support for random access loading within a .zip file
ReaderWriterZip.cpp - modified to use the ZipArchive class"
"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.
CID 11844: Uninitialized scalar field (UNINIT_CTOR)
Non-static class member _defaultValue is not initialized in this constructor nor in any functions that it calls.
Index: ../include/osgDB/Serializer
/** Get the file name which represents the archived file.*/
virtual std::string getArchiveFileName() const = 0;
/** return type of file. */
virtual FileType getFileType(const std::string& filename) const = 0;
/** return the contents of a directory.
* returns an empty array on any error.*/
virtual DirectoryContents getDirectoryContents(const std::string& dirName) const = 0;
Added implementations of these new methods into src/osgPlugins/osga/OSGA_Archive.h src/osgPlugins/osga/OSGA_Archive.cpp
external applications can determine if an archive extension is valid.
The second change is a bug fix in Registry::read(const ReadFunctor&)
where if you pass in valid options they get wiped out after the archive
is loaded but before being passed along to the plugin."
Fixes to race in DatabasePager where a parent PagedLOD
of newly loaded subgraph has been expired.
Clean up of visitor naming to make it clearer what role it has.
disable pragmas that turn off specific warnings for MSVC.
Unfortunately it's presence is only checked in osg/Export header,
making other Export headers disable warnings no matter what, which is
kind of incoherent.
My fix adds #include <osg/Config> to every Export header. I've also
unified checking whether to disable warnings to current osg/Export
way:
#if defined(_MSC_VER) && defined(OSG_DISABLE_MSVC_WARNINGS).
Attachment contains all changed Export files in their original locations."
"- In order to build against GLES1 we execute:
$ mkdir build_android_gles1
$ cd build_android_gles1
$ cmake .. -DOSG_BUILD_PLATFORM_ANDROID=ON -DDYNAMIC_OPENTHREADS=OFF
-DDYNAMIC_OPENSCENEGRAPH=OFF -DANDROID_NDK=<path_to_android_ndk>/
-DOSG_GLES1_AVAILABLE=ON -DOSG_GL1_AVAILABLE=OFF
-DOSG_GL2_AVAILABLE=OFF -DOSG_GL_DISPLAYLISTS_AVAILABLE=OFF -DJ=2
-DOSG_CPP_EXCEPTIONS_AVAILABLE=OFF
$ make
If all is correct you will have and static OSG inside:
build_android_gles1/bin/ndk/local/armeabi.
- GLES2 is not tested/proved, but I think it could be possible build
it with the correct cmake flags.
- The flag -DJ=2 is used to pass to the ndk-build the number of
processors to speed up the building.
- make install is not yet supported."
For the following code:
#define MYMACRO(NAME) myOutputStream << #NAME;
MYMACRO(Group)
you would expect that "Group" would be output. However, as there are many overloaded operator<< functions, none of which take a const char* argument, the function that's actually called is operator<<(bool). Hence what actually gets output is "TRUE".
An actual example of this is in serializers\osgAnimation\Animation.cpp, WRITE_CHANNEL_FUNC2.
So the simple solution to this is to add operator<<(const char*), attached.
"
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.
* the glsl plugin now supports processing #includes. The file extension sets the shader type.
* the registry releases gl objects of the shared state manager
"
serialization libraries. My submission mainly includes:
1. Add two new macros USE_DOTOSGWRAPPER_LIBRARY and
USE_SERIALIZER_WRAPPER_LIBRARY. Applications using static OSG must
include corresponding static-link libraries and use these two macros
to predefine native format wrappers. Please see osgstaticviewer and
present3D in the attachment for details.
2. Add a LibraryWrapper.cpp file in each
osgWrappers/deprecated-dotosg/... and osgWrappers/serializers/...
subfolder, which calls all USE_...WRAPPERS macros inside. The
LibraryWrapper file is automatically generated by the
wrapper_includer.cpp (with some slight fixes), which is also attached
for your reference. The deprecated-dotosg/osgAnimation is not included
because it doesn't us REGISTER_DOTOSGWRAPPER to define its wrappers.
3. Modify the ReaderWriterOSG.cpp to prevent calling loadWrappers()
when static build.
4. An uncorrelated fix to Serializer and ObjectWrapper.cpp, which
ensures version variables of serialziers are initialized, and
serializers out-of-version are not written to model files.
"
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.
"
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.
I also fixed a possible bug in osgDB::XmlParser that doesn't handle control characters (like " to ") when reading node attributes, because the writeWrappedString() and readWrappedString() now depend heavily on control characters. An additional improvement is that osgx now supports comments."
osgWidget::Input:
[Functional changes]
- Previously, the field would be filled with spaces up to its max length, and typing would just replace the spaces. Also, there was a _textLength variable that kept track of the real length of text in the field, since the osgText::Text's length just reflected the length of spaces+text entered. This was not great, as you could still select the spaces with the mouse and it just feels hacky. So I changed it to only contain the text entered, no spaces, and _textLength was removed since it's now redundant (the osgText::Text's length is used instead).
- Fixed the selection size which (visually only) showed one more character selected than what was really selected.
- Fixed selection by dragging the mouse, it would sometimes not select the last character of the string.
- Cursor will now accurately reflect whether insert mode is activated (block cursor) or we're in normal mode (line cursor) like in most editors.
- Implemented Ctrl-X (cut)
- Added a new clear() method that allows the field to be emptied correctly. Useful for a command line interface, for example (hint, hint).
- Mouse and keyboard event handler methods would always return false, which meant selecting with the mouse would also rotate the trackball, and typing an 's' would turn on stats.
[Code cleanup]
- Renamed the (local) _selectionMin and _selectionMax variables which are used in a lot of places, as the underscores would lead to think they were members. Either I called them selection{Min|Max} or delete{Min|Max} where it made more sense.
- Fixed some indenting which was at 3 spaces (inconsistently), I'm sure I didn't catch all the lines where this was the case though.
- Put spaces between variable, operator and value where missing, especially in for()s. Again I only did this where I made changes, there are probably others left.
The result is that delete, backspace, Ctrl-X, Ctrl-C, Ctrl-V, and typing behaviour should now be consistent with text editor conventions, whether insert mode is enabled or not. I hope. :-)
Note, there's a nasty const_cast in there. Why isn't osgText::Font::getGlyph() declared const?
Also, as a note, the current implementation of cut, copy and paste (in addition to being Windows only, yuck) gets and puts the data into an std::string, thus if the osgText::String in the field contains unicode characters I think it won't work correctly. Perhaps someone could implement a proper clipboard class that would be cross-platform and support osgText::String (more precisely other languages like Chinese) correctly? Cut, copy and paste are not critical to what I'm doing so I won't invest the time to do that, but I just thought I'd mention it.
"
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.
"
will cause the writing of osg::Switch incorrectly. The original thread
was posted on osg-users. I would like to follow the suggestion of
Brendan and add a std::endl before the END_BRACKET in
ListSerializer::write().
"
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.
"
modifications of the osgShadow header naming styles as well. The
osgDB::Serializer header is also changed to add new Vec2 serializer
macros because of the needs of osgShadow classes. It should compile
fine on both Windows and Linux. But I have only done a few tests to
generate .osgb, .osgt and .osgx formats with these new wrappers."