diff --git a/CMakeLists.txt b/CMakeLists.txt index cb1bc737e..dd9bfaa9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,8 +48,8 @@ PROJECT(OpenSceneGraph) SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 3) -SET(OPENSCENEGRAPH_PATCH_VERSION 1) -SET(OPENSCENEGRAPH_SOVERSION 111) +SET(OPENSCENEGRAPH_PATCH_VERSION 2) +SET(OPENSCENEGRAPH_SOVERSION 112) # set to 0 when not a release candidate, non zero means that any generated # svn tags will be treated as release candidates of given number diff --git a/include/osg/Geometry b/include/osg/Geometry index 652b57b0c..1020076d3 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -53,44 +53,50 @@ class OSG_EXPORT Geometry : public Drawable const Array* getVertexArray() const { return _vertexArray.get(); } - void setNormalArray(Array* array, osg::Array::Binding binding=osg::Array::BIND_UNDEFINED); + void setNormalArray(Array* array) { setNormalArray(array, osg::Array::BIND_UNDEFINED); } + void setNormalArray(Array* array, osg::Array::Binding binding); Array* getNormalArray() { return _normalArray.get(); } const Array* getNormalArray() const { return _normalArray.get(); } - void setColorArray(Array* array, osg::Array::Binding binding=osg::Array::BIND_UNDEFINED); + void setColorArray(Array* array) { setColorArray(array, osg::Array::BIND_UNDEFINED); } + void setColorArray(Array* array, osg::Array::Binding binding); Array* getColorArray() { return _colorArray.get(); } const Array* getColorArray() const { return _colorArray.get(); } - void setSecondaryColorArray(Array* array, osg::Array::Binding binding=osg::Array::BIND_UNDEFINED); + void setSecondaryColorArray(Array* array) { setSecondaryColorArray(array, osg::Array::BIND_UNDEFINED); } + void setSecondaryColorArray(Array* array, osg::Array::Binding binding); Array* getSecondaryColorArray() { return _secondaryColorArray.get(); } const Array* getSecondaryColorArray() const { return _secondaryColorArray.get(); } - void setFogCoordArray(Array* array, osg::Array::Binding binding=osg::Array::BIND_UNDEFINED); + void setFogCoordArray(Array* array) { setFogCoordArray(array, osg::Array::BIND_UNDEFINED); } + void setFogCoordArray(Array* array, osg::Array::Binding binding); Array* getFogCoordArray() { return _fogCoordArray.get(); } const Array* getFogCoordArray() const { return _fogCoordArray.get(); } - void setTexCoordArray(unsigned int unit,Array* array, osg::Array::Binding binding=osg::Array::BIND_UNDEFINED); + void setTexCoordArray(unsigned int unit, Array* array) { setTexCoordArray(unit, array, osg::Array::BIND_UNDEFINED); } + void setTexCoordArray(unsigned int unit, Array* array, osg::Array::Binding binding); Array* getTexCoordArray(unsigned int unit); const Array* getTexCoordArray(unsigned int unit) const; unsigned int getNumTexCoordArrays() const { return static_cast(_texCoordList.size()); } + void setTexCoordArrayList(const ArrayList& arrrayList); ArrayList& getTexCoordArrayList() { return _texCoordList; } const ArrayList& getTexCoordArrayList() const { return _texCoordList; } - - - void setVertexAttribArray(unsigned int index, Array* array, osg::Array::Binding binding=osg::Array::BIND_UNDEFINED); + void setVertexAttribArray(unsigned int index, Array* array) { setVertexAttribArray(index, array, osg::Array::BIND_UNDEFINED); } + void setVertexAttribArray(unsigned int index, Array* array, osg::Array::Binding binding); Array *getVertexAttribArray(unsigned int index); const Array *getVertexAttribArray(unsigned int index) const; unsigned int getNumVertexAttribArrays() const { return static_cast(_vertexAttribList.size()); } + void setVertexAttribArrayList(const ArrayList& arrayList); ArrayList& getVertexAttribArrayList() { return _vertexAttribList; } const ArrayList& getVertexAttribArrayList() const { return _vertexAttribList; } @@ -175,7 +181,7 @@ class OSG_EXPORT Geometry : public Drawable /** Set up the vertex arrays for the purpose of rendering, called by drawImplemtation() prior to it calling drawPrimitivesImplementation().*/ void drawVertexArraysImplementation(RenderInfo& renderInfo) const; - + /** dispatch the primitives to OpenGL, called by drawImplemtation() after calling drawVertexArraysImplementation().*/ void drawPrimitivesImplementation(RenderInfo& renderInfo) const; diff --git a/include/osg/Version b/include/osg/Version index 3e3b5beac..c16ff4f9f 100644 --- a/include/osg/Version +++ b/include/osg/Version @@ -20,8 +20,8 @@ extern "C" { #define OPENSCENEGRAPH_MAJOR_VERSION 3 #define OPENSCENEGRAPH_MINOR_VERSION 3 -#define OPENSCENEGRAPH_PATCH_VERSION 1 -#define OPENSCENEGRAPH_SOVERSION 111 +#define OPENSCENEGRAPH_PATCH_VERSION 2 +#define OPENSCENEGRAPH_SOVERSION 112 /* Convenience macro that can be used to decide whether a feature is present or not i.e. * #if OSG_MIN_VERSION_REQUIRED(2,9,5) diff --git a/include/osgDB/InputStream b/include/osgDB/InputStream index 2baf2d2e9..a33da0e65 100644 --- a/include/osgDB/InputStream +++ b/include/osgDB/InputStream @@ -137,14 +137,14 @@ public: InputStream& operator>>( osg::BoundingSpheref& bs ); InputStream& operator>>( osg::BoundingSphered& bs ); - InputStream& operator>>( osg::Array*& a ) { a = readArray(); return *this; } InputStream& operator>>( osg::Image*& img ) { img = readImage(); return *this; } - InputStream& operator>>( osg::PrimitiveSet*& p ) { p = readPrimitiveSet(); return *this; } + InputStream& operator>>( osg::Array*& a ) { if (_fileVersion>=112) a = readObjectOfType(); else a = readArray(); return *this; } + InputStream& operator>>( osg::PrimitiveSet*& p ) { if (_fileVersion>=112) p = readObjectOfType(); else p = readPrimitiveSet(); return *this; } InputStream& operator>>( osg::Object*& obj ) { obj = readObject(); return *this; } - InputStream& operator>>( osg::ref_ptr& ptr ) { ptr = readArray(); return *this; } InputStream& operator>>( osg::ref_ptr& ptr ) { ptr = readImage(); return *this; } - InputStream& operator>>( osg::ref_ptr& ptr ) { ptr = readPrimitiveSet(); return *this; } + InputStream& operator>>( osg::ref_ptr& ptr ) { if (_fileVersion>=112) ptr = readObjectOfType(); else ptr = readArray(); return *this; } + InputStream& operator>>( osg::ref_ptr& ptr ) { if (_fileVersion>=112) ptr = readObjectOfType(); else ptr = readPrimitiveSet(); return *this; } template InputStream& operator>>( osg::ref_ptr& ptr ) { ptr = static_cast(readObject()); return *this; } @@ -163,7 +163,19 @@ public: osg::Array* readArray(); osg::PrimitiveSet* readPrimitiveSet(); osg::Image* readImage(bool readFromExternal=true); + + template + T* readObjectOfType() + { + osg::ref_ptr obj = readObject(); + T* ptr = dynamic_cast(obj.get()); + if (ptr) { obj.release(); return ptr; } + else return 0; + } + osg::Object* readObject( osg::Object* existingObj=0 ); + + osg::Object* readObjectFields( const std::string& className, unsigned int id, osg::Object* existingObj=0); /// set an input iterator, used directly when not using InputStream with a traditional file releated stream. diff --git a/include/osgDB/OutputStream b/include/osgDB/OutputStream index c2e120e74..5e9cf1e00 100644 --- a/include/osgDB/OutputStream +++ b/include/osgDB/OutputStream @@ -15,6 +15,7 @@ #ifndef OSGDB_OUTPUTSTREAM #define OSGDB_OUTPUTSTREAM +#include #include #include #include @@ -142,17 +143,16 @@ public: OutputStream& operator<<( const osg::BoundingSpheref& bb ); OutputStream& operator<<( const osg::BoundingSphered& bb ); - OutputStream& operator<<( const osg::Array* a ) { writeArray(a); return *this; } OutputStream& operator<<( const osg::Image* img ) { writeImage(img); return *this; } - OutputStream& operator<<( const osg::PrimitiveSet* p ) { writePrimitiveSet(p); return *this; } + OutputStream& operator<<( const osg::Array* a ) { if (OPENSCENEGRAPH_SOVERSION>=112) writeObject(a); else writeArray(a); return *this; } + OutputStream& operator<<( const osg::PrimitiveSet* p ) { if (OPENSCENEGRAPH_SOVERSION>=112) writeObject(p); else writePrimitiveSet(p); return *this; } OutputStream& operator<<( const osg::Object* obj ) { writeObject(obj); return *this; } - OutputStream& operator<<( const osg::ref_ptr& ptr ) { writeArray(ptr.get()); return *this; } OutputStream& operator<<( const osg::ref_ptr& ptr ) { writeImage(ptr.get()); return *this; } - OutputStream& operator<<( const osg::ref_ptr& ptr ) { writePrimitiveSet(ptr.get()); return *this; } + OutputStream& operator<<( const osg::ref_ptr& ptr ) { if (OPENSCENEGRAPH_SOVERSION>=112) writeObject(ptr.get()); else writeArray(ptr.get()); return *this; } + OutputStream& operator<<( const osg::ref_ptr& ptr ) { if (OPENSCENEGRAPH_SOVERSION>=112) writeObject(ptr.get()); else writePrimitiveSet(ptr.get()); return *this; } - template OutputStream& operator<<( const osg::ref_ptr& ptr ) - { writeObject(ptr.get()); return *this; } + template OutputStream& operator<<( const osg::ref_ptr& ptr ) { writeObject(ptr.get()); return *this; } // Convenient methods for writing void writeWrappedString( const std::string& str ) { _out->writeWrappedString(str); } diff --git a/include/osgDB/PropertyInterface b/include/osgDB/PropertyInterface index d2c7e8441..e275b6dae 100644 --- a/include/osgDB/PropertyInterface +++ b/include/osgDB/PropertyInterface @@ -135,7 +135,6 @@ public: /** create an object of specified type for provided compound class name in the form libraryName::className. */ osg::Object* createObject(const std::string& compoundClassdName) const; - /// template method for getting property data, return true if property available and the type is compatible, otherwise returns false. template bool getProperty(const osg::Object* object, const std::string& propertyName, T& value); @@ -250,7 +249,7 @@ inline bool PropertyInterface::getProperty(const osg::Object* object, const std: if (copyPropertyObjectFromObject(object, propertyName, &value, sizeof(ObjectPtr), getTypeEnum())) return true; else { - OSG_NOTICE<<"PropertyInterface::getProperty("<className()<<") Checking UserDataContainer for object ptr"<getUserDataContainer(); if (udc) { @@ -294,6 +293,7 @@ inline bool PropertyInterface::setProperty(osg::Object* object, const std::strin } } + } #endif diff --git a/include/osgDB/Serializer b/include/osgDB/Serializer index 9e6e9f5ae..73f380ccb 100644 --- a/include/osgDB/Serializer +++ b/include/osgDB/Serializer @@ -135,7 +135,8 @@ public: RW_VEC3B, RW_VEC3UB, RW_VEC3S, RW_VEC3US, RW_VEC3I, RW_VEC3UI, RW_VEC4B, RW_VEC4UB, RW_VEC4S, RW_VEC4US, RW_VEC4I, RW_VEC4UI, RW_BOUNDINGBOXF, RW_BOUNDINGBOXD, - RW_BOUNDINGSPHEREF, RW_BOUNDINGSPHERED + RW_BOUNDINGSPHEREF, RW_BOUNDINGSPHERED, + RW_VECTOR }; BaseSerializer() : _firstVersion(0), _lastVersion(INT_MAX) {} @@ -784,6 +785,345 @@ public: Setter _setter; }; +class VectorBaseSerializer : public BaseSerializer +{ +public: + + VectorBaseSerializer(BaseSerializer::Type elementType):_elementType(elementType) {} + + Type getElementType() const { return _elementType; } + + virtual unsigned int size(const osg::Object& obj) const { return 0; } + virtual void resize(osg::Object& obj, unsigned int numElements) const {} + virtual void reserve(osg::Object& obj, unsigned int numElements) const {} + virtual void clear(osg::Object& obj) const {} + virtual void addElement(osg::Object& obj, void* ptr) const {} + virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const {} + virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const {} + virtual void* getElement(osg::Object& obj, unsigned int index) const { return 0; } + virtual const void* getElement(const osg::Object& obj, unsigned int index) const { return 0; } + +protected: + Type _elementType; +}; + + +template +class VectorSerializer : public VectorBaseSerializer +{ +public: + typedef typename P::value_type ValueType; + typedef typename P::const_iterator ConstIterator; + typedef P& (C::*Getter)(); + typedef const P& (C::*ConstGetter)() const; + typedef void (C::*Setter)( const P& ); + + VectorSerializer( const char* name, ConstGetter cgf, Getter gf, Setter sf, BaseSerializer::Type elementType, unsigned int numElementsOnRow): + VectorBaseSerializer(elementType), + _name(name), + _constgetter(cgf), _getter(gf), _setter(sf), + _numElementsOnRow(numElementsOnRow) {} + + virtual const std::string& getName() const { return _name; } + + virtual unsigned int size(const osg::Object& obj) const + { + const C& object = OBJECT_CAST(obj); + const P& list = (object.*_constgetter)(); + return static_cast(list.size()); + } + virtual void resize(osg::Object& obj, unsigned int numElements) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + list.resize(numElements); + } + virtual void reserve(osg::Object& obj, unsigned int numElements) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + list.reserve(numElements); + } + virtual void clear(osg::Object& obj) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + list.clear(); + } + virtual void addElement(osg::Object& obj, void* ptr) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + list.push_back(*reinterpret_cast(ptr)); + } + virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + if (index>=list.size()) list.resize(index+1); + list.insert(list.begin()+index, *reinterpret_cast(ptr)); + } + virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + if (index>=list.size()) list.resize(index+1); + list[index] = *reinterpret_cast(ptr); + } + virtual void* getElement(osg::Object& obj, unsigned int index) const + { + C& object = OBJECT_CAST(obj); + P& list = (object.*_getter)(); + if (index>=list.size()) return 0; + else return &list[index]; + } + virtual const void* getElement(const osg::Object& obj, unsigned int index) const + { + const C& object = OBJECT_CAST(obj); + const P& list = (object.*_constgetter)(); + if (index>=list.size()) return 0; + else return &list[index]; + } + + virtual bool read( InputStream& is, osg::Object& obj ) + { + C& object = OBJECT_CAST(obj); + unsigned int size = 0; + P list; + if ( is.isBinary() ) + { + is >> size; + for ( unsigned int i=0; i> value; + list.push_back( value ); + } + if ( size>0 ) (object.*_setter)( list ); + } + else if ( is.matchString(_name) ) + { + is >> size; + if ( size>0 ) is >> is.BEGIN_BRACKET; + for ( unsigned int i=0; i> value; + list.push_back( value ); + } + if ( size>0 ) + { + is >> is.END_BRACKET; + (object.*_setter)( list ); + } + } + return true; + } + + virtual bool write( OutputStream& os, const osg::Object& obj ) + { + const C& object = OBJECT_CAST(obj); + const P& list = (object.*_constgetter)(); + unsigned int size = (unsigned int)list.size(); + if ( os.isBinary() ) + { + os << size; + for ( ConstIterator itr=list.begin(); + itr!=list.end(); ++itr ) + { + os << (*itr); + } + } + else if ( size>0 ) + { + os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl; + if (_numElementsOnRow==0) + { + for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) + { + os << (*itr); + } + } + else if (_numElementsOnRow==1) + { + for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) + { + os << (*itr); os << std::endl; + } + } + else + { + unsigned int i = _numElementsOnRow-1; + for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr) + { + os << (*itr); + if (i==0) { os << std::endl; i = _numElementsOnRow-1; } + else --i; + } + if (i!=_numElementsOnRow) os << std::endl; + } + os << os.END_BRACKET << std::endl; + } + return true; + } + +public: + std::string _name; + ConstGetter _constgetter; + Getter _getter; + Setter _setter; + unsigned int _numElementsOnRow; +}; + + +template +class IsAVectorSerializer : public VectorBaseSerializer +{ +public: + typedef typename C::value_type ValueType; + typedef typename C::const_iterator ConstIterator; + + IsAVectorSerializer( const char* name, BaseSerializer::Type elementType, unsigned int numElementsOnRow) : + VectorBaseSerializer(elementType), + _name(name), + _numElementsOnRow(numElementsOnRow) {} + + virtual const std::string& getName() const { return _name; } + + virtual unsigned int size(const osg::Object& obj) const + { + const C& list = OBJECT_CAST(obj); + return static_cast(list.size()); + } + virtual void resize(osg::Object& obj, unsigned int numElements) const + { + C& list = OBJECT_CAST(obj); + list.resize(numElements); + } + virtual void reserve(osg::Object& obj, unsigned int numElements) const + { + C& list = OBJECT_CAST(obj); + list.reserve(numElements); + } + virtual void clear(osg::Object& obj) const + { + C& list = OBJECT_CAST(obj); + list.clear(); + } + virtual void addElement(osg::Object& obj, void* ptr) const + { + C& list = OBJECT_CAST(obj); + list.push_back(*reinterpret_cast(ptr)); + } + virtual void insertElement(osg::Object& obj, unsigned int index, void* ptr) const + { + C& list = OBJECT_CAST(obj); + if (index>=list.size()) list.resize(index+1); + list.insert(list.begin()+index, *reinterpret_cast(ptr)); + } + virtual void setElement(osg::Object& obj, unsigned int index, void* ptr) const + { + C& list = OBJECT_CAST(obj); + if (index>=list.size()) list.resize(index+1); + list[index] = *reinterpret_cast(ptr); + } + virtual void* getElement(osg::Object& obj, unsigned int index) const + { + C& list = OBJECT_CAST(obj); + if (index>=list.size()) return 0; + else return &list[index]; + } + + virtual const void* getElement(const osg::Object& obj, unsigned int index) const + { + const C& list = OBJECT_CAST(obj); + if (index>=list.size()) return 0; + else return &list[index]; + } + + virtual bool read( InputStream& is, osg::Object& obj ) + { + C& list = OBJECT_CAST(obj); + unsigned int size = 0; + if ( is.isBinary() ) + { + is >> size; + for ( unsigned int i=0; i> value; + list.push_back( value ); + } + } + else if ( is.matchString(_name) ) + { + is >> size; + if ( size>0 ) is >> is.BEGIN_BRACKET; + for ( unsigned int i=0; i> value; + list.push_back( value ); + } + if ( size>0 ) + { + is >> is.END_BRACKET; + } + } + return true; + } + + virtual bool write( OutputStream& os, const osg::Object& obj ) + { + const C& list = OBJECT_CAST(obj); + unsigned int size = (unsigned int)list.size(); + if ( os.isBinary() ) + { + os << size; + for ( ConstIterator itr=list.begin(); + itr!=list.end(); ++itr ) + { + os << (*itr); + } + } + else if ( size>0 ) + { + os << os.PROPERTY((_name).c_str()) << size << os.BEGIN_BRACKET << std::endl; + if (_numElementsOnRow==0) + { + for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) + { + os << (*itr); + } + } + else if (_numElementsOnRow==1) + { + for ( ConstIterator itr=list.begin(); itr!=list.end(); ++itr ) + { + os << (*itr); os << std::endl; + } + } + else + { + unsigned int i = _numElementsOnRow-1; + for (ConstIterator itr=list.begin(); itr!=list.end(); ++itr) + { + os << (*itr); + if (i==0) { os << std::endl; i = _numElementsOnRow-1; } + else --i; + } + if (i!=_numElementsOnRow) os << std::endl; + } + os << os.END_BRACKET << std::endl; + } + return true; + } + +public: + std::string _name; + unsigned int _numElementsOnRow; +}; + // ADDING MANIPULATORS #define ADD_SERIALIZER(S) \ wrapper->addSerializer( (S) ) @@ -1062,6 +1402,14 @@ public: wrapper->addSerializer( new osgDB::ListSerializer< MyClass, TYPE >( \ #PROP, &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_LIST ) + +#define ADD_VECTOR_SERIALIZER(PROP, TYPE, ELEMENTTYPE, NUMELEMENTSONROW) \ + wrapper->addSerializer( new osgDB::VectorSerializer< MyClass, TYPE >( \ + #PROP, &MyClass::get##PROP, &MyClass::get##PROP, &MyClass::set##PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR ) + +#define ADD_ISAVECTOR_SERIALIZER(PROP, ELEMENTTYPE, NUMELEMENTSONROW) \ + wrapper->addSerializer( new osgDB::IsAVectorSerializer< MyClass >( #PROP, ELEMENTTYPE, NUMELEMENTSONROW), osgDB::BaseSerializer::RW_VECTOR ) + #define BEGIN_ENUM_SERIALIZER(PROP, DEF) \ { typedef osgDB::EnumSerializer MySerializer; \ osg::ref_ptr serializer = new MySerializer( \ diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index eda8603dd..0253c36d4 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -189,6 +189,22 @@ const Array* Geometry::getTexCoordArray(unsigned int index) const else return 0; } +void Geometry::setTexCoordArrayList(const ArrayList& arrayList) +{ + _texCoordList = arrayList; + + dirtyDisplayList(); + + if (_useVertexBufferObjects) + { + for(ArrayList::iterator itr = _texCoordList.begin(); + itr != _texCoordList.end(); + ++itr) + { + addVertexBufferObjectIfRequired(itr->get()); + } + } +} void Geometry::setVertexAttribArray(unsigned int index, Array* array, osg::Array::Binding binding) { @@ -216,6 +232,23 @@ const Array *Geometry::getVertexAttribArray(unsigned int index) const else return 0; } +void Geometry::setVertexAttribArrayList(const ArrayList& arrayList) +{ + _vertexAttribList = arrayList; + + dirtyDisplayList(); + + if (_useVertexBufferObjects) + { + for(ArrayList::iterator itr = _vertexAttribList.begin(); + itr != _vertexAttribList.end(); + ++itr) + { + addVertexBufferObjectIfRequired(itr->get()); + } + } +} + bool Geometry::addPrimitiveSet(PrimitiveSet* primitiveset) { @@ -712,7 +745,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const // draw the primitives themselves. // drawPrimitivesImplementation(renderInfo); - + // unbind the VBO's if any are used. state.unbindVertexBufferObject(); state.unbindElementBufferObject(); diff --git a/src/osgDB/OutputStream.cpp b/src/osgDB/OutputStream.cpp index bf4ee4e62..7e12105fa 100644 --- a/src/osgDB/OutputStream.cpp +++ b/src/osgDB/OutputStream.cpp @@ -12,7 +12,6 @@ */ // Written by Wang Rui, (C) 2010 -#include #include #include #include diff --git a/src/osgDB/PropertyInterface.cpp b/src/osgDB/PropertyInterface.cpp index 3484126fb..a1e63fcee 100644 --- a/src/osgDB/PropertyInterface.cpp +++ b/src/osgDB/PropertyInterface.cpp @@ -239,6 +239,9 @@ PropertyInterface::PropertyInterface(): TYPENAME(VEC4US) TYPENAME(VEC4I) TYPENAME(VEC4UI) + + TYPENAME(LIST) + TYPENAME(VECTOR) } @@ -371,7 +374,7 @@ bool PropertyInterface::copyPropertyDataToObject(osg::Object* object, const std: } else { - OSG_NOTICE<<"PropertyInterface::copyPropertyDataToObject() Types are not compatible, valueType = "<getCompoundClassName(), methodName); } + } // end of osgDB namespace diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 6c8881dd5..40c3e3ac4 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -18,6 +18,9 @@ using namespace lua; + + + class LuaCallbackObject : public osg::CallbackObject { public: @@ -69,23 +72,24 @@ static int getProperty(lua_State * _lua) const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); int n = lua_gettop(_lua); /* number of arguments */ - if (n==2) + if (n==2 && lua_type(_lua, 1)==LUA_TTABLE) { - if (lua_type(_lua, 1)==LUA_TTABLE && - lua_type(_lua, 2)==LUA_TSTRING) + if (lua_type(_lua, 2)==LUA_TSTRING) { std::string propertyName = lua_tostring(_lua, 2); + osg::Object* object = lse->getObjectFromTable(1); - osg::Object* object = 0; - lua_pushstring(_lua, "object_ptr"); - lua_rawget(_lua, 1); + OSG_NOTICE<<"getProperty()"<className()<<", propertyName="<(reinterpret_cast(lua_touserdata(_lua,-1))); - } + return lse->pushPropertyToStack(object, propertyName); + } + else if (lua_type(_lua, 2)==LUA_TNUMBER) + { + double index = lua_tonumber(_lua, 2); + std::string propertyName = lua_tostring(_lua, 2); + osg::Object* object = lse->getObjectFromTable(1); - lua_pop(_lua,1); + OSG_NOTICE<<"getProperty()"<className()<<", propertyName="<setPropertyFromStack(object, propertyName); + } + else if (lua_type(_lua, 2)==LUA_TNUMBER) + { + double index = lua_tonumber(_lua, 2); + std::string propertyName = lua_tostring(_lua, 2); + osg::Object* object = lse->getObjectFromTable(1); - if (lua_type(_lua, -1)==LUA_TUSERDATA) - { - object = *const_cast(reinterpret_cast(lua_touserdata(_lua,-1))); - } - - lua_pop(_lua,1); + OSG_NOTICE<<"getProperty()"<className()<<", propertyName="<className()<<", propertyName="<getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + OSG_NOTICE<<"Need to implement copying and sizing of the vector type"<className()<<", index="<(lua_topointer(_lua, lua_upvalueindex(1))); + + int n = lua_gettop(_lua); /* number of arguments */ + if (n==3 && lua_type(_lua, 1)==LUA_TTABLE) + { + if (lua_type(_lua, 2)==LUA_TSTRING) + { + std::string propertyName = lua_tostring(_lua, 2); + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + OSG_NOTICE<<"setContainerProperty() object="<className()<<", "<setPropertyFromStack(object, propertyName); + } + else if (lua_type(_lua, 2)==LUA_TNUMBER) + { + double index = lua_tonumber(_lua, 2); + + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + SerializerScratchPad ssp; + lse->popDataFromStack(&ssp, vs->getElementType()); + { + vs->setElement(*object, index, ssp.data); + } + } + return 0; + } + } + + OSG_NOTICE<<"Warning: Lua setContainerProperty() not matched"<(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + lua_pushinteger(lse->getLuaState(), vs->size(*object)); + return 1; + } + + return 0; +} + +static int getContainerClear(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + vs->clear(*object); + return 0; + } + + return 0; +} + +static int getContainerResize(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE || lua_type(_lua, 2)!=LUA_TNUMBER) return 0; + + double numElements = lua_tonumber(lse->getLuaState(),2); + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + vs->resize(*object, static_cast(numElements)); + } + + return 0; +} + +static int getContainerReserve(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE || lua_type(_lua, 2)!=LUA_TNUMBER) return 0; + + double numElements = lua_tonumber(lse->getLuaState(),2); + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + vs->reserve(*object, static_cast(numElements)); + } + + return 0; +} + + +static int getContainerAdd(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::VectorBaseSerializer* vs = dynamic_cast(bs); + if (vs) + { + SerializerScratchPad ssp; + lse->popDataFromStack(&ssp, vs->getElementType()); + { + vs->addElement(*object, ssp.data); + } + } + + return 0; +} + static int callClassMethod(lua_State* _lua) { const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); @@ -362,6 +565,23 @@ void LuaScriptEngine::initialize() lua_pop(_lua,1); } + // Set up the __newindex and __index methods for looking up implementations of Object properties + { + luaL_newmetatable(_lua, "LuaScriptEngine.Container"); + + lua_pushstring(_lua, "__index"); + lua_pushlightuserdata(_lua, this); + lua_pushcclosure(_lua, getContainerProperty, 1); + lua_settable(_lua, -3); + + lua_pushstring(_lua, "__newindex"); + lua_pushlightuserdata(_lua, this); + lua_pushcclosure(_lua, setContainerProperty, 1); + lua_settable(_lua, -3); + + lua_pop(_lua,1); + } + // Set up the __gc methods for looking up implementations of Object pointer to do the unref when the associated Lua object is destroyed. { luaL_newmetatable(_lua, "LuaScriptEngine.UnrefObject"); @@ -621,6 +841,26 @@ int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& } break; } + case(osgDB::BaseSerializer::RW_SHORT): + { + short value; + if (_pi.getProperty(object, propertyName, value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_USHORT): + { + unsigned short value; + if (_pi.getProperty(object, propertyName, value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } case(osgDB::BaseSerializer::RW_INT): { int value; @@ -803,6 +1043,12 @@ int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& } break; } + case(osgDB::BaseSerializer::RW_VECTOR): + { + OSG_NOTICE<<"Have Vector object, need to implement pushVector() "<dataType) + { + case(osgDB::BaseSerializer::RW_BOOL): + { + bool value; + if (ssp->get(value)) + { + lua_pushboolean(_lua, value ? 1 : 0); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_STRING): + { + std::string value; + if (ssp->get(value)) + { + lua_pushstring(_lua, value.c_str()); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_GLENUM): + { + GLenum value; + if (ssp->get(value)) + { + std::string enumString = lookUpGLenumString(value); + lua_pushstring(_lua, enumString.c_str()); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_ENUM): + { + int value; + if (ssp->get(value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_INT): + { + int value; + if (ssp->get(value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_UINT): + { + unsigned int value; + if (ssp->get(value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_SHORT): + { + short value; + if (ssp->get(value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_USHORT): + { + unsigned short value; + if (ssp->get(value)) + { + lua_pushinteger(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_FLOAT): + { + float value; + if (ssp->get(value)) + { + lua_pushnumber(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_DOUBLE): + { + double value; + if (ssp->get(value)) + { + lua_pushnumber(_lua, value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC2F): + { + osg::Vec2f value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC3F): + { + osg::Vec3f value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC4F): + { + osg::Vec4f value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC2D): + { + osg::Vec2d value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC3D): + { + osg::Vec3d value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC4D): + { + osg::Vec4d value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } +#ifdef OSG_USE_FLOAT_MATRIX + case(osgDB::BaseSerializer::RW_MATRIX): +#endif + case(osgDB::BaseSerializer::RW_MATRIXF): + { + osg::Matrixf value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } +#ifndef OSG_USE_FLOAT_MATRIX + case(osgDB::BaseSerializer::RW_MATRIX): +#endif + case(osgDB::BaseSerializer::RW_MATRIXD): + { + osg::Matrixd value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): + { + osg::BoundingBoxf value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): + { + osg::BoundingBoxd value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): + { + osg::BoundingSpheref value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): + { + osg::BoundingSphered value; + if (ssp->get(value)) + { + pushValue(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_IMAGE): + case(osgDB::BaseSerializer::RW_OBJECT): + { + osg::Object* value = 0; + if (ssp->get(value)) + { + pushObject(value); + return 1; + } + break; + } + case(osgDB::BaseSerializer::RW_LIST): + { + break; + } + case(osgDB::BaseSerializer::RW_VECTOR): + { + break; + } + default: + break; + } + + OSG_NOTICE<<"LuaScriptEngine::pushDataToStack() property of type = "<<_pi.getTypeName(ssp->dataType)<<" error, not supported."<set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + else if (lua_isstring(_lua, -1)) + { + const char* enumString = lua_tostring(_lua, -1); + GLenum value = lookUpGLenumValue(enumString); //getValue("GL",enumString); + + OSG_NOTICE<<"Checking enumString="<set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + else if (lua_isstring(_lua, -1)) + { + OSG_NOTICE<<"LuaScriptEngine::popDataFromStack() osgDB::BaseSerializer::RW_ENUM Failed to convert string"<set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_USHORT): + { + if (lua_isnumber(_lua, -1)) + { + ssp->set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_INT): + { + if (lua_isnumber(_lua, -1)) + { + ssp->set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_UINT): + { + if (lua_isnumber(_lua, -1)) + { + ssp->set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_FLOAT): + { + if (lua_isnumber(_lua, -1)) + { + ssp->set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_DOUBLE): + { + if (lua_isnumber(_lua, -1)) + { + ssp->set(static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC2F): + { + osg::Vec2f value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC3F): + { + osg::Vec3f value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC4F): + { + osg::Vec4f value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC2D): + { + osg::Vec2d value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC3D): + { + osg::Vec3d value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_VEC4D): + { + osg::Vec4d value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_QUAT): + { + osg::Quat value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_PLANE): + { + osg::Plane value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } +#ifdef OSG_USE_FLOAT_MATRIX + case(osgDB::BaseSerializer::RW_MATRIX): +#endif + case(osgDB::BaseSerializer::RW_MATRIXF): + { + osg::Matrixd value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } +#ifndef OSG_USE_FLOAT_MATRIX + case(osgDB::BaseSerializer::RW_MATRIX): +#endif + case(osgDB::BaseSerializer::RW_MATRIXD): + { + osg::Matrixd value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGBOXF): + { + osg::BoundingBoxf value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGBOXD): + { + osg::BoundingBoxd value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGSPHEREF): + { + osg::BoundingSpheref value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_BOUNDINGSPHERED): + { + osg::BoundingSphered value; + if (getValue(value)) + { + ssp->set(value); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_LIST): + { + OSG_NOTICE<<"Need to implement RW_LIST support"<(reinterpret_cast(lua_touserdata(_lua,-1))); + lua_pop(_lua, 1); + + if (value) + { + ssp->set(value); + return 0; + } + else + { + OSG_NOTICE<<"Error: lua type '"<set(value); + return 0; + } + else + { + OSG_NOTICE<<"Error: lua type '"<(lua_tonumber(_lua, -1))); + return 0; + } + break; + } + case(osgDB::BaseSerializer::RW_USHORT): + { + if (lua_isnumber(_lua, -1)) + { + _pi.setProperty(object, propertyName, static_cast(lua_tonumber(_lua, -1))); + return 0; + } + break; + } case(osgDB::BaseSerializer::RW_INT): { if (lua_isnumber(_lua, -1)) @@ -1879,6 +2717,48 @@ osg::Object* LuaScriptEngine::popParameterObject() const return object.release(); } +void LuaScriptEngine::pushContainer(osg::Object* object, const std::string& propertyName) const +{ + if (object) + { + lua_newtable(_lua); + + // set up objbect_ptr to handle ref/unref of the object + { + lua_pushstring(_lua, "object_ptr"); + + // create user data for pointer + void* userdata = lua_newuserdata( _lua, sizeof(osg::Object*)); + (*reinterpret_cast(userdata)) = object; + + luaL_getmetatable( _lua, "LuaScriptEngine.UnrefObject"); + lua_setmetatable( _lua, -2 ); + + lua_settable(_lua, -3); + + + // increment the reference count as the lua now will unreference it once it's finished with the userdata for the pointer + object->ref(); + } + + lua_pushstring(_lua, "containerPropertyName"); lua_pushstring(_lua, propertyName.c_str()); lua_settable(_lua, -3); + + assignClosure("size", getContainerSize); + assignClosure("clear", getContainerClear); + assignClosure("resize", getContainerResize); + assignClosure("reserve", getContainerReserve); + assignClosure("add", getContainerAdd); + + luaL_getmetatable(_lua, "LuaScriptEngine.Container"); + lua_setmetatable(_lua, -2); + } + else + { + lua_pushnil(_lua); + } +} + + void LuaScriptEngine::createAndPushObject(const std::string& compoundName) const { osg::ref_ptr object = _pi.createObject(compoundName); @@ -1916,8 +2796,28 @@ void LuaScriptEngine::pushObject(osg::Object* object) const lua_pushstring(_lua, "className"); lua_pushstring(_lua, object->className()); lua_settable(_lua, -3); lua_pushstring(_lua, "compoundClassName"); lua_pushstring(_lua, object->getCompoundClassName().c_str()); lua_settable(_lua, -3); - luaL_getmetatable(_lua, "LuaScriptEngine.Object"); - lua_setmetatable(_lua, -2); + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* vs = _pi.getSerializer(object, "vector", type); + if (vs) + { + OSG_NOTICE<<"pushObject("<className()<<" Have vector"< + bool set(const T& t) + { + if (sizeof(T)<=maxDataSize) + { + *(reinterpret_cast(data)) = t; + dataType = osgDB::getTypeEnum(); + dataSize = sizeof(T); + return true; + } + else + { + dataSize = 0; + dataType = osgDB::BaseSerializer::RW_UNDEFINED; + return false; + } + } + + template + bool get(T& t) const + { + if (sizeof(T)==dataSize && dataType == osgDB::getTypeEnum()) + { + t = *(reinterpret_cast(data)); + return true; + } + else + { + return false; + } + } +}; + + class LuaScriptEngine : public osg::ScriptEngine { public: @@ -47,6 +97,9 @@ class LuaScriptEngine : public osg::ScriptEngine osgDB::PropertyInterface& getPropertyInterface() const { return _pi; } + int pushDataToStack(SerializerScratchPad* ssp) const; + int popDataFromStack(SerializerScratchPad* ssp, osgDB::BaseSerializer::Type type) const; + int pushPropertyToStack(osg::Object* object, const std::string& propertyName) const; int setPropertyFromStack(osg::Object* object, const std::string& propertyName) const; @@ -109,6 +162,7 @@ class LuaScriptEngine : public osg::ScriptEngine bool popParameter(osg::Object* object) const; osg::Object* popParameterObject() const; + void pushContainer(osg::Object* object, const std::string& propertyName) const; void createAndPushObject(const std::string& compoundName) const; void pushObject(osg::Object* object) const; @@ -133,6 +187,24 @@ class LuaScriptEngine : public osg::ScriptEngine else return 0; } + std::string getStringFromTable(int pos, const std::string& field) const + { + std::string result; + if (lua_type(_lua, pos)==LUA_TTABLE) + { + lua_pushstring(_lua, field.c_str()); + lua_rawget(_lua, pos); + + if (lua_type(_lua, -1)==LUA_TSTRING) + { + result = lua_tostring(_lua, -1); + } + + lua_pop(_lua,1); + } + return result; + } + std::string getObjectCompoundClassName(int pos) const { if (lua_type(_lua, pos)==LUA_TTABLE) diff --git a/src/osgWrappers/serializers/osg/Array.cpp b/src/osgWrappers/serializers/osg/Array.cpp index 83920f8c7..d033ac1d5 100644 --- a/src/osgWrappers/serializers/osg/Array.cpp +++ b/src/osgWrappers/serializers/osg/Array.cpp @@ -6,6 +6,7 @@ namespace ArrayWrappers { +#if 0 struct ResizeArray : public osgDB::MethodObject { virtual bool run(void* objectPtr, osg::Parameters& inputParameters, osg::Parameters& outputParameters) const @@ -28,14 +29,14 @@ struct ResizeArray : public osgDB::MethodObject return true; } }; - +#endif REGISTER_OBJECT_WRAPPER( Array, 0, osg::Array, "osg::Object osg::Array" ) { - +#if 0 BEGIN_ENUM_SERIALIZER_NO_SET( Type, ArrayType ); ADD_ENUM_VALUE( ArrayType ); @@ -94,6 +95,8 @@ REGISTER_OBJECT_WRAPPER( Array, ADD_UINT_SERIALIZER_NO_SET( TotalDataSize, 0); ADD_UINT_SERIALIZER_NO_SET( NumElements, 0); + ADD_METHOD_OBJECT( "resizeArray", ResizeArray ); +#endif BEGIN_ENUM_SERIALIZER( Binding, BIND_UNDEFINED ); ADD_ENUM_VALUE( BIND_UNDEFINED ); ADD_ENUM_VALUE( BIND_OFF ); @@ -105,50 +108,54 @@ REGISTER_OBJECT_WRAPPER( Array, ADD_BOOL_SERIALIZER(Normalize, false); ADD_BOOL_SERIALIZER(PreserveDataType, false); - ADD_METHOD_OBJECT( "resizeArray", ResizeArray ); } } -#define ARRAY_WRAPPERS( ARRAY ) \ - namespace Wrappers##ARRAY { REGISTER_OBJECT_WRAPPER( ARRAY, new osg::ARRAY, osg::ARRAY, "osg::Object osg::Array osg::"#ARRAY ) {} } +#define ARRAY_WRAPPERS( ARRAY, ELEMENTTYPE, NUMELEMENTSONROW ) \ + namespace Wrappers##ARRAY { \ + REGISTER_OBJECT_WRAPPER( ARRAY, new osg::ARRAY, osg::ARRAY, "osg::Object osg::Array osg::"#ARRAY) \ + { \ + ADD_ISAVECTOR_SERIALIZER( vector, osgDB::BaseSerializer::ELEMENTTYPE, NUMELEMENTSONROW ); \ + } \ + } -ARRAY_WRAPPERS(FloatArray) -ARRAY_WRAPPERS(Vec2Array) -ARRAY_WRAPPERS(Vec3Array) -ARRAY_WRAPPERS(Vec4Array) +ARRAY_WRAPPERS(FloatArray, RW_FLOAT, 4) +ARRAY_WRAPPERS(Vec2Array, RW_VEC2F, 1) +ARRAY_WRAPPERS(Vec3Array, RW_VEC3F, 1) +ARRAY_WRAPPERS(Vec4Array, RW_VEC4F, 1) -ARRAY_WRAPPERS(DoubleArray) -ARRAY_WRAPPERS(Vec2dArray) -ARRAY_WRAPPERS(Vec3dArray) -ARRAY_WRAPPERS(Vec4dArray) +ARRAY_WRAPPERS(DoubleArray, RW_DOUBLE, 4) +ARRAY_WRAPPERS(Vec2dArray, RW_VEC2D, 1) +ARRAY_WRAPPERS(Vec3dArray, RW_VEC3D, 1) +ARRAY_WRAPPERS(Vec4dArray, RW_VEC4D, 1) -ARRAY_WRAPPERS(ByteArray) -ARRAY_WRAPPERS(Vec2bArray) -ARRAY_WRAPPERS(Vec3bArray) -ARRAY_WRAPPERS(Vec4bArray) +ARRAY_WRAPPERS(ByteArray, RW_CHAR, 4) +ARRAY_WRAPPERS(Vec2bArray, RW_VEC2B, 1) +ARRAY_WRAPPERS(Vec3bArray, RW_VEC3B, 1) +ARRAY_WRAPPERS(Vec4bArray, RW_VEC4B, 1) -ARRAY_WRAPPERS(UByteArray) -ARRAY_WRAPPERS(Vec2ubArray) -ARRAY_WRAPPERS(Vec3ubArray) -ARRAY_WRAPPERS(Vec4ubArray) +ARRAY_WRAPPERS(UByteArray, RW_UCHAR, 4) +ARRAY_WRAPPERS(Vec2ubArray, RW_VEC2UB, 1) +ARRAY_WRAPPERS(Vec3ubArray, RW_VEC3UB, 1) +ARRAY_WRAPPERS(Vec4ubArray, RW_VEC4UB, 1) -ARRAY_WRAPPERS(ShortArray) -ARRAY_WRAPPERS(Vec2sArray) -ARRAY_WRAPPERS(Vec3sArray) -ARRAY_WRAPPERS(Vec4sArray) +ARRAY_WRAPPERS(ShortArray, RW_SHORT, 4) +ARRAY_WRAPPERS(Vec2sArray, RW_VEC2S, 1) +ARRAY_WRAPPERS(Vec3sArray, RW_VEC3S, 1) +ARRAY_WRAPPERS(Vec4sArray, RW_VEC4S, 1) -ARRAY_WRAPPERS(UShortArray) -ARRAY_WRAPPERS(Vec2usArray) -ARRAY_WRAPPERS(Vec3usArray) -ARRAY_WRAPPERS(Vec4usArray) +ARRAY_WRAPPERS(UShortArray, RW_USHORT, 4) +ARRAY_WRAPPERS(Vec2usArray, RW_VEC2US, 1) +ARRAY_WRAPPERS(Vec3usArray, RW_VEC3US, 1) +ARRAY_WRAPPERS(Vec4usArray, RW_VEC4US, 1) -ARRAY_WRAPPERS(IntArray) -ARRAY_WRAPPERS(Vec2iArray) -ARRAY_WRAPPERS(Vec3iArray) -ARRAY_WRAPPERS(Vec4iArray) +ARRAY_WRAPPERS(IntArray, RW_INT, 4) +ARRAY_WRAPPERS(Vec2iArray, RW_VEC2I, 1) +ARRAY_WRAPPERS(Vec3iArray, RW_VEC3I, 1) +ARRAY_WRAPPERS(Vec4iArray, RW_VEC4I, 1) -ARRAY_WRAPPERS(UIntArray) -ARRAY_WRAPPERS(Vec2uiArray) -ARRAY_WRAPPERS(Vec3uiArray) -ARRAY_WRAPPERS(Vec4uiArray) +ARRAY_WRAPPERS(UIntArray, RW_UINT, 4) +ARRAY_WRAPPERS(Vec2uiArray, RW_VEC2UI, 1) +ARRAY_WRAPPERS(Vec3uiArray, RW_VEC3UI, 1) +ARRAY_WRAPPERS(Vec4uiArray, RW_VEC4UI, 1) diff --git a/src/osgWrappers/serializers/osg/Geometry.cpp b/src/osgWrappers/serializers/osg/Geometry.cpp index ac1795077..416d136b0 100644 --- a/src/osgWrappers/serializers/osg/Geometry.cpp +++ b/src/osgWrappers/serializers/osg/Geometry.cpp @@ -146,7 +146,9 @@ REGISTER_OBJECT_WRAPPER( Geometry, osg::Geometry, "osg::Object osg::Drawable osg::Geometry" ) { - ADD_LIST_SERIALIZER( PrimitiveSetList, osg::Geometry::PrimitiveSetList ); // _primitives + //ADD_LIST_SERIALIZER( PrimitiveSetList, osg::Geometry::PrimitiveSetList ); // _primitives + ADD_VECTOR_SERIALIZER( PrimitiveSetList, osg::Geometry::PrimitiveSetList, osgDB::BaseSerializer::RW_OBJECT, 0 ); + ADD_USER_SERIALIZER( VertexData ); // _vertexData ADD_USER_SERIALIZER( NormalData ); // _normalData ADD_USER_SERIALIZER( ColorData ); // _colorData @@ -157,5 +159,27 @@ REGISTER_OBJECT_WRAPPER( Geometry, ADD_USER_SERIALIZER( FastPathHint ); // _fastPathHint + { + UPDATE_TO_VERSION_SCOPED( 112 ) + REMOVE_SERIALIZER( VertexData ); + REMOVE_SERIALIZER( NormalData ); + REMOVE_SERIALIZER( ColorData ); + REMOVE_SERIALIZER( SecondaryColorData ); + REMOVE_SERIALIZER( FogCoordData ); + REMOVE_SERIALIZER( TexCoordData ); + REMOVE_SERIALIZER( VertexAttribData ); + REMOVE_SERIALIZER( FastPathHint ); + + ADD_OBJECT_SERIALIZER( VertexArray, osg::Array, NULL ); + ADD_OBJECT_SERIALIZER( NormalArray, osg::Array, NULL ); + ADD_OBJECT_SERIALIZER( ColorArray, osg::Array, NULL ); + ADD_OBJECT_SERIALIZER( SecondaryColorArray, osg::Array, NULL ); + ADD_OBJECT_SERIALIZER( FogCoordArray, osg::Array, NULL ); + + ADD_VECTOR_SERIALIZER( TexCoordArrayList, osg::Geometry::ArrayList, osgDB::BaseSerializer::RW_OBJECT, 0 ); + ADD_VECTOR_SERIALIZER( VertexAttribArrayList, osg::Geometry::ArrayList, osgDB::BaseSerializer::RW_OBJECT, 0 ); + } + + wrapper->addFinishedObjectReadCallback( new GeometryFinishedObjectReadCallback() ); } diff --git a/src/osgWrappers/serializers/osg/PrimitiveSet.cpp b/src/osgWrappers/serializers/osg/PrimitiveSet.cpp index 40f081f2b..3ab2aeeb9 100644 --- a/src/osgWrappers/serializers/osg/PrimitiveSet.cpp +++ b/src/osgWrappers/serializers/osg/PrimitiveSet.cpp @@ -6,12 +6,54 @@ namespace PrimitiveSetWrapper { +#define CUSTOM_BEGIN_ENUM_SERIALIZER(PROP, DEF) \ +{ typedef osgDB::EnumSerializer MySerializer; \ +osg::ref_ptr serializer = new MySerializer( \ + #PROP, MyClass::DEF, &MyClass::get##PROP, &MyClass::set##PROP) + + + REGISTER_OBJECT_WRAPPER( PrimitiveSet, 0, osg::PrimitiveSet, "osg::Object osg::PrimitiveSet" ) { + ADD_INT_SERIALIZER( NumInstances, 0); + +#if 1 + + { + typedef osgDB::EnumSerializer MySerializer; + + typedef osg::PrimitiveSet::Mode (osg::PrimitiveSet::*Getter)() const; + typedef void (osg::PrimitiveSet::*Setter)( osg::PrimitiveSet::Mode ); + + osg::ref_ptr serializer = new MySerializer( "Mode", osg::PrimitiveSet::POINTS, + reinterpret_cast(&osg::PrimitiveSet::getMode), + reinterpret_cast(&osg::PrimitiveSet::setMode)); + ADD_ENUM_VALUE( POINTS ); + ADD_ENUM_VALUE( LINES ); + ADD_ENUM_VALUE( LINE_STRIP ); + ADD_ENUM_VALUE( LINE_LOOP ); + ADD_ENUM_VALUE( TRIANGLES ); + ADD_ENUM_VALUE( TRIANGLE_STRIP ); + ADD_ENUM_VALUE( TRIANGLE_FAN ); + ADD_ENUM_VALUE( QUADS ); + ADD_ENUM_VALUE( QUAD_STRIP ); + ADD_ENUM_VALUE( POLYGON ); + ADD_ENUM_VALUE( LINES_ADJACENCY ); + ADD_ENUM_VALUE( LINE_STRIP_ADJACENCY ); + ADD_ENUM_VALUE( TRIANGLES_ADJACENCY ); + ADD_ENUM_VALUE( TRIANGLE_STRIP_ADJACENCY ); + ADD_ENUM_VALUE( PATCHES ); + + wrapper->addSerializer(serializer.get(), osgDB::BaseSerializer::RW_ENUM); + } +#else + ADD_GLENUM_SERIALIZER( Mode, GLenum, GL_NONE ); +#endif +#if 0 BEGIN_ENUM_SERIALIZER_NO_SET( Type, PrimitiveType ); ADD_ENUM_VALUE( PrimitiveType ); ADD_ENUM_VALUE( DrawArraysPrimitiveType ); @@ -21,17 +63,14 @@ REGISTER_OBJECT_WRAPPER( PrimitiveSet, ADD_ENUM_VALUE( DrawElementsUIntPrimitiveType ); END_ENUM_SERIALIZER(); - ADD_INT_SERIALIZER( NumInstances, 0); - ADD_GLENUM_SERIALIZER( Mode, GLenum, GL_NONE ); - ADD_UINT_SERIALIZER_NO_SET( TotalDataSize, 0); ADD_UINT_SERIALIZER_NO_SET( NumPrimitives, 0); ADD_UINT_SERIALIZER_NO_SET( NumIndices, 0); - wrapper->addSerializer( new osgDB::PropByValSerializer< osg::PrimitiveSet, bool > ("supportsBufferObject", false, &osg::PrimitiveSet::supportsBufferObject, 0, osgDB::BaseSerializer::RW_BOOL ) ); +#endif } } @@ -49,6 +88,20 @@ REGISTER_OBJECT_WRAPPER( DrawArrays, } +namespace DrawArrayLengthsWrapper { + +REGISTER_OBJECT_WRAPPER( DrawArrayLengths, + new osg::DrawArrayLengths, + osg::DrawArrayLengths, + "osg::Object osg::PrimitiveSet osg::DrawArrayLengths" ) +{ + ADD_GLINT_SERIALIZER( First, 0); + ADD_ISAVECTOR_SERIALIZER( vector, osgDB::BaseSerializer::RW_INT, 4 ); +} + +} + +#if 0 namespace DrawElementsWrapper { struct ResizeDrawElements : public osgDB::MethodObject @@ -74,7 +127,6 @@ struct ResizeDrawElements : public osgDB::MethodObject } }; - REGISTER_OBJECT_WRAPPER( DrawElements, 0, osg::DrawElements, @@ -84,10 +136,16 @@ REGISTER_OBJECT_WRAPPER( DrawElements, } } +#endif -#define DRAW_ELEMENTS_WRAPPER( DRAWELEMENTS ) \ - namespace Wrapper##DRAWELEMENTS { REGISTER_OBJECT_WRAPPER( DRAWELEMENTS, new osg::DRAWELEMENTS, osg::DRAWELEMENTS, "osg::Object osg::PrimitiveSet osg::DrawElements "#DRAWELEMENTS) {} } +#define DRAW_ELEMENTS_WRAPPER( DRAWELEMENTS, ELEMENTTYPE ) \ + namespace Wrapper##DRAWELEMENTS { \ + REGISTER_OBJECT_WRAPPER( DRAWELEMENTS, new osg::DRAWELEMENTS, osg::DRAWELEMENTS, "osg::Object osg::PrimitiveSet osg::"#DRAWELEMENTS) \ + { \ + ADD_ISAVECTOR_SERIALIZER( vector, osgDB::BaseSerializer::ELEMENTTYPE, 4 ); \ + } \ + } -DRAW_ELEMENTS_WRAPPER( DrawElementsUByte ) -DRAW_ELEMENTS_WRAPPER( DrawElementsUShort ) -DRAW_ELEMENTS_WRAPPER( DrawElementsUInt ) +DRAW_ELEMENTS_WRAPPER( DrawElementsUByte, RW_UCHAR ) +DRAW_ELEMENTS_WRAPPER( DrawElementsUShort, RW_USHORT ) +DRAW_ELEMENTS_WRAPPER( DrawElementsUInt, RW_UINT )