diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index cafdb0bbc..735b19281 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -188,6 +188,8 @@ class OSGUTIL_EXPORT Optimizer static bool mergeGeode(osg::Geode& geode); + static bool geometryContainsSharedArrays(osg::Geometry& geom); + static bool mergeGeometry(osg::Geometry& lhs,osg::Geometry& rhs); static bool mergePrimitive(osg::DrawArrays& lhs,osg::DrawArrays& rhs); diff --git a/src/osgPlugins/osg/Geometry.cpp b/src/osgPlugins/osg/Geometry.cpp index 3fc21f144..f9e4c1769 100644 --- a/src/osgPlugins/osg/Geometry.cpp +++ b/src/osgPlugins/osg/Geometry.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -63,50 +64,65 @@ bool Geometry_readLocalData(Object& obj, Input& fr) } - if (fr.matchSequence("VertexArray %i {")) + if (fr[0].matchWord("VertexArray")) { - - 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) + if (fr.matchSequence("VertexArray %i {")) { - Vec3 v; - if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) + + 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) { - fr += 3; - vertices->push_back(v); - } - else - { - ++fr; + 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; } - - geom.setVertexArray(vertices); - - iteratorAdvanced = true; - ++fr; - - } - - if (fr.matchSequence("VertexIndices %w %i {")) + + if (fr[0].matchWord("VertexIndices")) { ++fr; + IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setVertexIndices(indices); - iteratorAdvanced = true; } + + iteratorAdvanced = true; } @@ -118,46 +134,61 @@ bool Geometry_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } - if (fr.matchSequence("NormalArray %i {")) + if (fr[0].matchWord("NormalArray")) { - 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) + if (fr.matchSequence("NormalArray %i {")) { - Vec3 v; - if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y()) && fr[2].getFloat(v.z())) + // 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) { - fr += 3; - normals->push_back(v); - } - else - { - ++fr; + 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; } - - geom.setNormalArray(normals); - - iteratorAdvanced = true; - ++fr; } - if (fr.matchSequence("NormalIndices %w %i {")) + if (fr[0].matchWord("NormalIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setNormalIndices(indices); - iteratorAdvanced = true; } + iteratorAdvanced = true; } Geometry::AttributeBinding colorBinding=Geometry::BIND_OFF; @@ -168,26 +199,26 @@ bool Geometry_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } - if (fr.matchSequence("ColorArray %w %i {")) + if (fr[0].matchWord("ColorArray")) { ++fr; Array* colors = Array_readLocalData(fr); if (colors) { geom.setColorArray(colors); - iteratorAdvanced = true; } + iteratorAdvanced = true; } - if (fr.matchSequence("ColorIndices %w %i {")) + if (fr[0].matchWord("ColorIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setColorIndices(indices); - iteratorAdvanced = true; } + iteratorAdvanced = true; } @@ -199,26 +230,26 @@ bool Geometry_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } - if (fr.matchSequence("SecondaryColorArray %w %i {")) + if (fr[0].matchWord("SecondaryColorArray")) { ++fr; Array* colors = Array_readLocalData(fr); if (colors) { geom.setSecondaryColorArray(colors); - iteratorAdvanced = true; } + iteratorAdvanced = true; } - if (fr.matchSequence("SecondaryColorIndices %w %i {")) + if (fr[0].matchWord("SecondaryColorIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setSecondaryColorIndices(indices); - iteratorAdvanced = true; } + iteratorAdvanced = true; } @@ -230,30 +261,30 @@ bool Geometry_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } - if (fr.matchSequence("FogCoordArray %w %i {")) + if (fr[0].matchWord("FogCoordArray")) { ++fr; Array* fogcoords = Array_readLocalData(fr); if (fogcoords) { geom.setFogCoordArray(fogcoords); - iteratorAdvanced = true; } + iteratorAdvanced = true; } - if (fr.matchSequence("FogCoordIndices %w %i {")) + if (fr[0].matchWord("FogCoordIndices")) { ++fr; IndexArray* indices = dynamic_cast(Array_readLocalData(fr)); if (indices) { geom.setFogCoordIndices(indices); - iteratorAdvanced = true; } + iteratorAdvanced = true; } - if (fr.matchSequence("TexCoordArray %i %w %i {")) + if (fr.matchSequence("TexCoordArray %i")) { int unit=0; fr[1].getInt(unit); @@ -263,12 +294,12 @@ bool Geometry_readLocalData(Object& obj, Input& fr) if (texcoords) { geom.setTexCoordArray(unit,texcoords); - iteratorAdvanced = true; } + iteratorAdvanced = true; } - if (fr.matchSequence("TexCoordIndices %i %w %i {")) + if (fr.matchSequence("TexCoordIndices %i")) { int unit=0; fr[1].getInt(unit); @@ -278,8 +309,8 @@ bool Geometry_readLocalData(Object& obj, Input& fr) if (indices) { geom.setTexCoordIndices(unit,indices); - iteratorAdvanced = true; } + iteratorAdvanced = true; } return iteratorAdvanced; @@ -288,6 +319,30 @@ bool Geometry_readLocalData(Object& obj, Input& fr) 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."<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): @@ -886,10 +968,12 @@ bool Geometry_writeLocalData(const Object& obj, Output& fw) if (geom.getVertexArray()) { - const Vec3Array& vertices = *geom.getVertexArray(); - fw.indent()<<"VertexArray "<computeCorrectBindingsAndArraySizes(); - geometryDuplicateMap[geom].push_back(geom); + if (!geometryContainsSharedArrays(*geom)) + { + geometryDuplicateMap[geom].push_back(geom); + } } } @@ -1295,8 +1298,36 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) return false; } +bool Optimizer::MergeGeometryVisitor::geometryContainsSharedArrays(osg::Geometry& geom) +{ + if (geom.getVertexArray() && geom.getVertexArray()->referenceCount()>1) return true; + if (geom.getNormalArray() && geom.getNormalArray()->referenceCount()>1) return true; + if (geom.getColorArray() && geom.getColorArray()->referenceCount()>1) return true; + if (geom.getSecondaryColorArray() && geom.getSecondaryColorArray()->referenceCount()>1) return true; + if (geom.getFogCoordArray() && geom.getFogCoordArray()->referenceCount()>1) return true; + + + for(unsigned int unit=0;unitreferenceCount()>1) return true; + } + + // shift the indices of the incomming primitives to account for the pre exisiting geometry. + for(osg::Geometry::PrimitiveSetList::iterator primItr=geom.getPrimitiveSetList().begin(); + primItr!=geom.getPrimitiveSetList().end(); + ++primItr) + { + if ((*primItr)->referenceCount()>1) return true; + } + + + return false; +} + bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geometry& rhs) { + unsigned int base = 0; if (lhs.getVertexArray() && rhs.getVertexArray()) {