#include #include #include #include #include using namespace osg; using namespace osgDB; // forward declare functions to use later. bool Geometry_readLocalData(Object& obj, Input& fr); bool Geometry_writeLocalData(const Object& obj, Output& fw); bool Geometry_matchBindingTypeStr(const char* str,Geometry::AttributeBinding& mode); const char* Geometry_getBindingTypeStr(Geometry::AttributeBinding mode); bool Geometry_matchPrimitiveModeStr(const char* str,GLenum& mode); const char* Geometry_getPrimitiveModeStr(GLenum mode); Array* Array_readLocalData(Input& fr); bool Primitive_readLocalData(Input& fr,osg::Geometry& geom); //register the read and write functions with the osgDB::Registry. RegisterDotOsgWrapperProxy g_GeometryFuncProxy ( new osg::Geometry, "Geometry", "Object Drawable Geometry", &Geometry_readLocalData, &Geometry_writeLocalData, DotOsgWrapper::READ_AND_WRITE ); bool Geometry_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; Geometry& geom = static_cast(obj); if (fr.matchSequence("Primitives %i {") || fr.matchSequence("PrimitiveSets %i {") ) { int entry = fr[1].getNoNestedBrackets(); int capacity; fr[1].getInt(capacity); Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList(); if (capacity>0) primitives.reserve(capacity); fr += 3; while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { if (!Primitive_readLocalData(fr,geom)) fr.advanceOverCurrentFieldOrBlock(); } ++fr; iteratorAdvanced = true; } if (fr[0].matchWord("VertexArray")) { if (fr.matchSequence("VertexArray %i {")) { int entry = fr[0].getNoNestedBrackets(); int capacity; fr[1].getInt(capacity); Vec3Array* vertices = new Vec3Array; vertices->reserve(capacity); fr += 3; while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec3 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) { fr += 3; vertices->push_back(v); } else { ++fr; } } geom.setVertexArray(vertices); iteratorAdvanced = true; ++fr; } else { // post 0.9.3 releases. ++fr; Vec3Array* vertices = dynamic_cast(Array_readLocalData(fr)); if (vertices) { geom.setVertexArray(vertices); } iteratorAdvanced = true; } } if (fr[0].matchWord("VertexIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setVertexIndices(indices); } iteratorAdvanced = true; } Geometry::AttributeBinding normalBinding=Geometry::BIND_OFF; if (fr[0].matchWord("NormalBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),normalBinding)) { geom.setNormalBinding(normalBinding); fr+=2; iteratorAdvanced = true; } if (fr[0].matchWord("NormalArray")) { if (fr.matchSequence("NormalArray %i {")) { // pre 0.9.3 releases.. int entry = fr[0].getNoNestedBrackets(); int capacity; fr[1].getInt(capacity); Vec3Array* normals = new Vec3Array; normals->reserve(capacity); fr += 3; while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec3 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) { fr += 3; normals->push_back(v); } else { ++fr; } } geom.setNormalArray(normals); iteratorAdvanced = true; ++fr; } else { // post 0.9.3 releases. ++fr; Vec3Array* normals = dynamic_cast(Array_readLocalData(fr)); if (normals) { geom.setNormalArray(normals); } iteratorAdvanced = true; } } if (fr[0].matchWord("NormalIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setNormalIndices(indices); } iteratorAdvanced = true; } Geometry::AttributeBinding colorBinding=Geometry::BIND_OFF; if (fr[0].matchWord("ColorBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),colorBinding)) { geom.setColorBinding(colorBinding); fr+=2; iteratorAdvanced = true; } if (fr[0].matchWord("ColorArray")) { ++fr; Array* colors = Array_readLocalData(fr); if (colors) { geom.setColorArray(colors); } iteratorAdvanced = true; } if (fr[0].matchWord("ColorIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setColorIndices(indices); } iteratorAdvanced = true; } Geometry::AttributeBinding secondaryColorBinding=Geometry::BIND_OFF; if (fr[0].matchWord("SecondaryColorBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),secondaryColorBinding)) { geom.setSecondaryColorBinding(secondaryColorBinding); fr+=2; iteratorAdvanced = true; } if (fr[0].matchWord("SecondaryColorArray")) { ++fr; Array* colors = Array_readLocalData(fr); if (colors) { geom.setSecondaryColorArray(colors); } iteratorAdvanced = true; } if (fr[0].matchWord("SecondaryColorIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setSecondaryColorIndices(indices); } iteratorAdvanced = true; } Geometry::AttributeBinding fogCoordBinding=Geometry::BIND_OFF; if (fr[0].matchWord("FogCoordBinding") && Geometry_matchBindingTypeStr(fr[1].getStr(),fogCoordBinding)) { geom.setFogCoordBinding(fogCoordBinding); fr+=2; iteratorAdvanced = true; } if (fr[0].matchWord("FogCoordArray")) { ++fr; Array* fogcoords = Array_readLocalData(fr); if (fogcoords) { geom.setFogCoordArray(fogcoords); } iteratorAdvanced = true; } if (fr[0].matchWord("FogCoordIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setFogCoordIndices(indices); } iteratorAdvanced = true; } if (fr.matchSequence("TexCoordArray %i")) { int unit=0; fr[1].getInt(unit); fr+=2; Array* texcoords = Array_readLocalData(fr); if (texcoords) { geom.setTexCoordArray(unit,texcoords); } iteratorAdvanced = true; } if (fr.matchSequence("TexCoordIndices %i")) { int unit=0; fr[1].getInt(unit); fr+=2; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setTexCoordIndices(unit,indices); } iteratorAdvanced = true; } return iteratorAdvanced; } Array* Array_readLocalData(Input& fr) { if (fr[0].matchWord("Use")) { if (fr[1].isString()) { Object* obj = fr.getObjectForUniqueID(fr[1].getStr()); if (obj) { fr+=2; return dynamic_cast(obj); } } osg::notify(osg::WARN)<<"Warning: invalid uniqueID found in file."<reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int int_value; if (fr[0].getInt(int_value)) { ++fr; array->push_back(int_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"ShortArray")==0) { ShortArray* array = new ShortArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int int_value; if (fr[0].getInt(int_value)) { ++fr; array->push_back(int_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"IntArray")==0) { IntArray* array = new IntArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { int int_value; if (fr[0].getInt(int_value)) { ++fr; array->push_back(int_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UByteArray")==0) { UByteArray* array = new UByteArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int uint_value; if (fr[0].getUInt(uint_value)) { ++fr; array->push_back(uint_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UShortArray")==0) { UShortArray* array = new UShortArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int uint_value; if (fr[0].getUInt(uint_value)) { ++fr; array->push_back(uint_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UIntArray")==0) { UIntArray* array = new UIntArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int uint_value; if (fr[0].getUInt(uint_value)) { ++fr; array->push_back(uint_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"UByte4Array")==0) { UByte4Array* array = new UByte4Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int r,g,b,a; if (fr[0].getUInt(r) && fr[1].getUInt(g) && fr[2].getUInt(b) && fr[3].getUInt(a)) { ++fr; array->push_back(osg::UByte4(r,g,b,a)); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"FloatArray")==0) { FloatArray* array = new FloatArray; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { float float_value; if (fr[0].getFloat(float_value)) { ++fr; array->push_back(float_value); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec2Array")==0) { Vec2Array* array = new Vec2Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec2 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())) { fr += 2; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec3Array")==0) { Vec3Array* array = new Vec3Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec3 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) { fr += 3; array->push_back(v); } else ++fr; } ++fr; return_array = array; } else if (strcmp(arrayName,"Vec4Array")==0) { Vec4Array* array = new Vec4Array; array->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { Vec4 v; if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z()) && fr[3].getFloat(v.w())) { fr += 4; array->push_back(v); } else ++fr; } ++fr; return_array = array; } if (return_array) { if (!uniqueID.empty()) fr.regisiterUniqueIDForObject(uniqueID.c_str(),return_array); } return return_array; } bool Array_writeLocalData(const Array& array,Output& fw) { if (array.referenceCount()>1) { std::string uniqueID; if (fw.getUniqueIDForObject(&array,uniqueID)) { fw << "Use " << uniqueID << std::endl; return true; } else { std::string uniqueID; fw.createUniqueIDForObject(&array,uniqueID); fw.registerUniqueIDForObject(&array,uniqueID); fw << "UniqueID " << uniqueID << " "; } } switch(array.getType()) { case(Array::ByteArrayType): { const ByteArray& carray = static_cast(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<(array); fw<setMode(mode); prim->setFirst(first); prim->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int i; if (fr[0].getUInt(i)) { prim->push_back(i); ++fr; } } ++fr; geom.addPrimitiveSet(prim); iteratorAdvanced = true; } else if (fr.matchSequence("DrawElementsUByte %w %i {")) { int entry = fr[1].getNoNestedBrackets(); GLenum mode; Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode); int capacity; fr[2].getInt(capacity); fr += 4; DrawElementsUByte* prim = new DrawElementsUByte; prim->setMode(mode); prim->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int i; if (fr[0].getUInt(i)) { prim->push_back(i); ++fr; } } ++fr; geom.addPrimitiveSet(prim); iteratorAdvanced = true; } else if (fr.matchSequence("DrawElementsUShort %w %i {")) { int entry = fr[1].getNoNestedBrackets(); GLenum mode; Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode); int capacity; fr[2].getInt(capacity); fr += 4; DrawElementsUShort* prim = new DrawElementsUShort; prim->setMode(mode); prim->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int i; if (fr[0].getUInt(i)) { prim->push_back(i); ++fr; } } ++fr; geom.addPrimitiveSet(prim); iteratorAdvanced = true; } else if (fr.matchSequence("DrawElementsUInt %w %i {")) { int entry = fr[1].getNoNestedBrackets(); GLenum mode; Geometry_matchPrimitiveModeStr(fr[1].getStr(),mode); int capacity; fr[2].getInt(capacity); fr += 4; DrawElementsUInt* prim = new DrawElementsUInt; prim->setMode(mode); prim->reserve(capacity); while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) { unsigned int i; if (fr[0].getUInt(i)) { prim->push_back(i); ++fr; } } ++fr; geom.addPrimitiveSet(prim); iteratorAdvanced = true; } return iteratorAdvanced; } bool Primitive_writeLocalData(const PrimitiveSet& prim,Output& fw) { switch(prim.getType()) { case(PrimitiveSet::DrawArraysPrimitiveType): { const DrawArrays& cprim = static_cast(prim); fw<(prim); fw<(prim); fw<(prim); fw<(prim); fw<(obj); const Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList(); if (!primitives.empty()) { fw.indent() << "PrimitiveSets "<