From Marco, updates to osgDB and .osg plugin to better handle reading of
objects of specified types.
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
namespace osgDB {
|
||||
|
||||
struct basic_type_wrapper;
|
||||
|
||||
/** Class for managing the reading of ASCII .osg files.*/
|
||||
class OSGDB_EXPORT Input : public FieldReaderIterator
|
||||
{
|
||||
@@ -35,6 +37,7 @@ class OSGDB_EXPORT Input : public FieldReaderIterator
|
||||
virtual ~Input();
|
||||
|
||||
virtual osg::Object* readObjectOfType(const osg::Object& compObj);
|
||||
virtual osg::Object* readObjectOfType(const basic_type_wrapper &btw);
|
||||
|
||||
virtual osg::Object* readObject();
|
||||
virtual osg::Image* readImage();
|
||||
|
||||
@@ -29,6 +29,24 @@
|
||||
|
||||
namespace osgDB {
|
||||
|
||||
/** basic structure for custom runtime inheritance checking */
|
||||
struct basic_type_wrapper {
|
||||
virtual bool matches(const osg::Object *proto) const = 0;
|
||||
};
|
||||
|
||||
/** a class template that checks inheritance between a given
|
||||
Object's class and a class defined at compile time through
|
||||
the template parameter T.
|
||||
This is used in conjunction with readObjectOfType() to
|
||||
specify an abstract class as reference type.
|
||||
**/
|
||||
template<class T>
|
||||
struct type_wrapper: basic_type_wrapper {
|
||||
bool matches(const osg::Object *proto) const
|
||||
{
|
||||
return dynamic_cast<const T*>(proto) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** list of directories to search through which searching for files. */
|
||||
typedef std::deque<std::string> FilePathList;
|
||||
@@ -84,7 +102,8 @@ class OSGDB_EXPORT Registry : public osg::Referenced
|
||||
/** get a reader writer which handles specified extension.*/
|
||||
ReaderWriter* getReaderWriterForExtension(const std::string& ext);
|
||||
|
||||
osg::Object* readObjectOfType(const osg::Object& compObj,Input& fr);
|
||||
osg::Object* readObjectOfType(const osg::Object& compObj,Input& fr);
|
||||
osg::Object* readObjectOfType(const basic_type_wrapper &btw, Input& fr);
|
||||
|
||||
osg::Object* readObject(Input& fr);
|
||||
osg::Image* readImage(Input& fr);
|
||||
|
||||
@@ -47,6 +47,11 @@ osg::Object* Input::readObjectOfType(const osg::Object& compObj)
|
||||
return Registry::instance()->readObjectOfType(compObj,*this);
|
||||
}
|
||||
|
||||
osg::Object* Input::readObjectOfType(const basic_type_wrapper &btw)
|
||||
{
|
||||
return Registry::instance()->readObjectOfType(btw,*this);
|
||||
}
|
||||
|
||||
osg::Object* Input::readObject()
|
||||
{
|
||||
return Registry::instance()->readObject(*this);
|
||||
|
||||
@@ -566,6 +566,20 @@ ReaderWriter* Registry::getReaderWriterForExtension(const std::string& ext)
|
||||
|
||||
|
||||
osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr)
|
||||
{
|
||||
struct concrete_wrapper: basic_type_wrapper {
|
||||
concrete_wrapper(const osg::Object *myobj) : myobj_(myobj) {}
|
||||
bool matches(const osg::Object *proto) const
|
||||
{
|
||||
return myobj_->isSameKindAs(proto);
|
||||
}
|
||||
const osg::Object *myobj_;
|
||||
};
|
||||
|
||||
return readObjectOfType(concrete_wrapper(&compObj), fr);
|
||||
}
|
||||
|
||||
osg::Object* Registry::readObjectOfType(const basic_type_wrapper &btw,Input& fr)
|
||||
{
|
||||
const char *str = fr[0].getStr();
|
||||
if (str==NULL) return NULL;
|
||||
@@ -575,7 +589,7 @@ osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr)
|
||||
if (fr[1].isString())
|
||||
{
|
||||
Object* obj = fr.getObjectForUniqueID(fr[1].getStr());
|
||||
if (obj && compObj.isSameKindAs(obj))
|
||||
if (obj && btw.matches(obj))
|
||||
{
|
||||
fr+=2;
|
||||
return obj;
|
||||
@@ -602,11 +616,11 @@ osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr)
|
||||
|
||||
// first try the standard nodekit library.
|
||||
std::string nodeKitLibraryName = createLibraryNameForNodeKit(libraryName);
|
||||
if (loadLibrary(nodeKitLibraryName)) return readObjectOfType(compObj,fr);
|
||||
if (loadLibrary(nodeKitLibraryName)) return readObjectOfType(btw,fr);
|
||||
|
||||
// otherwise try the osgdb_ plugin library.
|
||||
std::string pluginLibraryName = createLibraryNameForExtension(libraryName);
|
||||
if (loadLibrary(pluginLibraryName)) return readObjectOfType(compObj,fr);
|
||||
if (loadLibrary(pluginLibraryName)) return readObjectOfType(btw,fr);
|
||||
}
|
||||
}
|
||||
else if (fr[1].isOpenBracket())
|
||||
@@ -620,7 +634,7 @@ osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!compObj.isSameKindAs(proto))
|
||||
if (!btw.matches(proto))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -672,6 +686,7 @@ osg::Object* Registry::readObjectOfType(const osg::Object& compObj,Input& fr)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// read object from input iterator.
|
||||
//
|
||||
|
||||
@@ -100,7 +100,8 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
|
||||
if (vertices->size()>=targetNumVertices)
|
||||
{
|
||||
// finishing setting up the current geometry and add it to the geode.
|
||||
geometry->setUseDisplayList(false);
|
||||
geometry->setUseDisplayList(true);
|
||||
geometry->setUseVertexBufferObjects(true);
|
||||
geometry->setVertexArray(vertices);
|
||||
geometry->setNormalArray(normals);
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
@@ -133,7 +134,8 @@ class ReaderWriter3DC : public osgDB::ReaderWriter
|
||||
}
|
||||
|
||||
|
||||
geometry->setUseDisplayList(false);
|
||||
geometry->setUseDisplayList(true);
|
||||
geometry->setUseVertexBufferObjects(true);
|
||||
geometry->setVertexArray(vertices);
|
||||
geometry->setNormalArray(normals);
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
|
||||
@@ -35,15 +35,11 @@ bool Drawable_readLocalData(Object& obj, Input& fr)
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
ref_ptr<Object> readObject = fr.readObject();
|
||||
if (readObject.valid())
|
||||
{
|
||||
osg::Shape* shape = dynamic_cast<osg::Shape*>(readObject.get());
|
||||
if (shape) drawable.setShape(shape);
|
||||
else notify(WARN)<<"Warning:: "<<readObject->className()<<" loaded but cannot not be attached to Drawable."<<std::endl;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
Shape* shape = static_cast<Shape *>(fr.readObjectOfType(type_wrapper<Shape>()));
|
||||
if (shape) {
|
||||
drawable.setShape(shape);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("supportsDisplayList"))
|
||||
{
|
||||
|
||||
@@ -502,11 +502,10 @@ bool CompositeShape_readLocalData(Object& obj, Input& fr)
|
||||
}
|
||||
}
|
||||
|
||||
while((readObject=fr.readObject()).valid())
|
||||
while((readObject=fr.readObjectOfType(type_wrapper<osg::Shape>())).valid())
|
||||
{
|
||||
osg::Shape* shape = dynamic_cast<osg::Shape*>(readObject.get());
|
||||
if (shape) composite.addChild(shape);
|
||||
else notify(WARN)<<"Warning:: "<<readObject->className()<<" loaded but cannot not be attached to Drawable."<<std::endl;
|
||||
osg::Shape* shape = static_cast<osg::Shape*>(readObject.get());
|
||||
composite.addChild(shape);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,13 +42,10 @@ bool ShapeDrawable_readLocalData(Object& obj, Input& fr)
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
ref_ptr<Object> readObject = fr.readObject();
|
||||
ref_ptr<Object> readObject = fr.readObjectOfType(type_wrapper<TessellationHints>());
|
||||
if (readObject.valid()) {
|
||||
TessellationHints* hints = dynamic_cast<TessellationHints*>(readObject.get());
|
||||
if (hints)
|
||||
geom.setTessellationHints(hints);
|
||||
else
|
||||
notify(WARN) << "Warning: " << readObject->className() << " loaded but cannot be attached to ShapeDrawable.\n";
|
||||
TessellationHints* hints = static_cast<TessellationHints*>(readObject.get());
|
||||
geom.setTessellationHints(hints);
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,23 +25,19 @@ bool ModularEmitter_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
osgParticle::ModularEmitter &myobj = static_cast<osgParticle::ModularEmitter &>(obj);
|
||||
bool itAdvanced = false;
|
||||
|
||||
// we cannot use readObjectOfType() because the Coutner, Placer and Shooter classes are
|
||||
// abstract and we can't create instances to use as prototypes.
|
||||
// So, we call readObject() and then dynamic cast to the desired class.
|
||||
|
||||
osgParticle::Counter *counter = dynamic_cast<osgParticle::Counter *>(fr.readObject());
|
||||
osgParticle::Counter *counter = static_cast<osgParticle::Counter *>(fr.readObjectOfType(osgDB::type_wrapper<osgParticle::Counter>()));
|
||||
if (counter) {
|
||||
myobj.setCounter(counter);
|
||||
itAdvanced = true;
|
||||
}
|
||||
|
||||
osgParticle::Placer *placer = dynamic_cast<osgParticle::Placer *>(fr.readObject());
|
||||
osgParticle::Placer *placer = static_cast<osgParticle::Placer *>(fr.readObjectOfType(osgDB::type_wrapper<osgParticle::Placer>()));
|
||||
if (placer) {
|
||||
myobj.setPlacer(placer);
|
||||
itAdvanced = true;
|
||||
}
|
||||
|
||||
osgParticle::Shooter *shooter = dynamic_cast<osgParticle::Shooter *>(fr.readObject());
|
||||
osgParticle::Shooter *shooter = static_cast<osgParticle::Shooter *>(fr.readObjectOfType(osgDB::type_wrapper<osgParticle::Shooter>()));
|
||||
if (shooter) {
|
||||
myobj.setShooter(shooter);
|
||||
itAdvanced = true;
|
||||
|
||||
@@ -25,7 +25,7 @@ bool ModularProgram_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
osgParticle::ModularProgram &myobj = static_cast<osgParticle::ModularProgram &>(obj);
|
||||
bool itAdvanced = false;
|
||||
|
||||
osgParticle::Operator *op = dynamic_cast<osgParticle::Operator *>(fr.readObject());
|
||||
osgParticle::Operator *op = static_cast<osgParticle::Operator *>(fr.readObjectOfType(osgDB::type_wrapper<osgParticle::Operator>()));
|
||||
if (op) {
|
||||
myobj.addOperator(op);
|
||||
itAdvanced = true;
|
||||
|
||||
Reference in New Issue
Block a user