diff --git a/include/osgUtil/Optimizer b/include/osgUtil/Optimizer index fdf74cbd6..ab904104d 100644 --- a/include/osgUtil/Optimizer +++ b/include/osgUtil/Optimizer @@ -35,6 +35,7 @@ class OSGUTIL_EXPORT Optimizer public: Optimizer() {} + virtual ~Optimizer() {} enum OptimizationOptions { @@ -64,6 +65,9 @@ class OSGUTIL_EXPORT Optimizer TRISTRIP_GEOMETRY }; + /** reset internal data to initial state - the getPrimissableOptionsMap is cleared.*/ + void reset(); + /** traverse the node and its subgraph with a series of optimization * visitors, specificied by the OptizationOptions.*/ void optimize(osg::Node* node); @@ -73,6 +77,35 @@ class OSGUTIL_EXPORT Optimizer virtual void optimize(osg::Node* node, unsigned int options); + inline void setPermissableOptionsForObject(const osg::Object* object, unsigned int options) + { + _permissableOptionsMap[object] = options; + } + + inline unsigned int getPermissableOptionsForObject(const osg::Object* object) const + { + PermissableOptionsMap::const_iterator itr = _permissableOptionsMap.find(object); + if (itr!=_permissableOptionsMap.end()) return itr->second; + else return 0xffffffff; + } + + inline bool isOperationPermissableForObject(const osg::Object* object,unsigned int option) const + { + return (option & getPermissableOptionsForObject(object))!=0; + } + + typedef std::map PermissableOptionsMap; + + PermissableOptionsMap& getPrimissableOptionsMap() { return _permissableOptionsMap; } + const PermissableOptionsMap& getPrimissableOptionsMap() const { return _permissableOptionsMap; } + + + protected: + + PermissableOptionsMap _permissableOptionsMap; + + + public: /** Flatten Static Trasform nodes by applying their transform to the @@ -84,8 +117,9 @@ class OSGUTIL_EXPORT Optimizer - FlattenStaticTransformsVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + FlattenStaticTransformsVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Geode& geode); virtual void apply(osg::Billboard& geode); @@ -93,6 +127,11 @@ class OSGUTIL_EXPORT Optimizer bool removeTransforms(osg::Node* nodeWeCannotRemove); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,FLATTEN_STATIC_TRANSFORMS) : true; + } + protected: @@ -100,7 +139,8 @@ class OSGUTIL_EXPORT Optimizer typedef std::set DrawableSet; typedef std::set BillboardSet; typedef std::set TransformSet; - + + Optimizer* _optimizer; TransformStack _transformStack; DrawableSet _drawableSet; BillboardSet _billboardSet; @@ -113,16 +153,23 @@ class OSGUTIL_EXPORT Optimizer { public: - CombineStaticTransformsVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + CombineStaticTransformsVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::MatrixTransform& transform); bool removeTransforms(osg::Node* nodeWeCannotRemove); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,FLATTEN_STATIC_TRANSFORMS) : true; + } + protected: typedef std::set TransformSet; + Optimizer* _optimizer; TransformSet _transformSet; }; @@ -135,13 +182,21 @@ class OSGUTIL_EXPORT Optimizer typedef std::set NodeList; NodeList _redundantNodeList; - RemoveEmptyNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} - + RemoveEmptyNodesVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} + virtual void apply(osg::Geode& geode); virtual void apply(osg::Group& group); void removeEmptyNodes(); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,REMOVE_REDUNDANT_NODES) : true; + } + + Optimizer* _optimizer; }; /** Remove rendundant nodes, such as groups with one single child.*/ @@ -152,13 +207,21 @@ class OSGUTIL_EXPORT Optimizer typedef std::set NodeList; NodeList _redundantNodeList; - RemoveRedundantNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + RemoveRedundantNodesVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Group& group); virtual void apply(osg::Transform& transform); void removeRedundantNodes(); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,REMOVE_REDUNDANT_NODES) : true; + } + + Optimizer* _optimizer; }; /** Optimize the LOD groups, by combining adjacent LOD's which have @@ -170,12 +233,20 @@ class OSGUTIL_EXPORT Optimizer typedef std::set GroupList; GroupList _groupList; - CombineLODsVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + CombineLODsVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::LOD& lod); void combineLODs(); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,COMBINE_ADJACENT_LODS) : true; + } + + Optimizer* _optimizer; }; /** Optimize State in the scene graph by removing duplicate state, @@ -186,7 +257,9 @@ class OSGUTIL_EXPORT Optimizer public: /// default to traversing all children. - StateVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} + StateVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} /** empty visitor, make it ready for next traversal.*/ virtual void reset(); @@ -197,6 +270,11 @@ class OSGUTIL_EXPORT Optimizer void optimize(); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,SHARE_DUPLICATE_STATE) : true; + } + protected: void addStateSet(osg::StateSet* stateset,osg::Object* obj); @@ -204,6 +282,7 @@ class OSGUTIL_EXPORT Optimizer typedef std::set ObjectSet; typedef std::map StateSetMap; + Optimizer* _optimizer; StateSetMap _statesets; }; @@ -213,11 +292,20 @@ class OSGUTIL_EXPORT Optimizer public: /// default to traversing all children. - CheckGeometryVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} + CheckGeometryVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Geode& geode) { checkGeode(geode); } - static void checkGeode(osg::Geode& geode); + void checkGeode(osg::Geode& geode); + + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,CHECK_GEOMETRY) : true; + } + + Optimizer* _optimizer; }; @@ -226,12 +314,14 @@ class OSGUTIL_EXPORT Optimizer public: /// default to traversing all children. - MergeGeometryVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} + MergeGeometryVisitor(Optimizer* optimizer=0) : + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Geode& geode) { mergeGeode(geode); } virtual void apply(osg::Billboard&) { /* don't do anything*/ } - static bool mergeGeode(osg::Geode& geode); + bool mergeGeode(osg::Geode& geode); static bool geometryContainsSharedArrays(osg::Geometry& geom); @@ -243,6 +333,12 @@ class OSGUTIL_EXPORT Optimizer static bool mergePrimitive(osg::DrawElementsUShort& lhs,osg::DrawElementsUShort& rhs); static bool mergePrimitive(osg::DrawElementsUInt& lhs,osg::DrawElementsUInt& rhs); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,MERGE_GEOMETRY) : true; + } + + Optimizer* _optimizer; }; /** Spatialize scene into a balanced quad/oct tree.*/ @@ -250,7 +346,9 @@ class OSGUTIL_EXPORT Optimizer { public: - SpatializeGroupsVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + SpatializeGroupsVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Group& group); @@ -261,6 +359,13 @@ class OSGUTIL_EXPORT Optimizer typedef std::set GroupsToDivideList; GroupsToDivideList _groupsToDivideList; + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,SPATIALIZE_GROUPS) : true; + } + + Optimizer* _optimizer; + }; /** Copy any shared subgraphs, enabling flattening of static transforms.*/ @@ -268,7 +373,9 @@ class OSGUTIL_EXPORT Optimizer { public: - CopySharedSubgraphsVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + CopySharedSubgraphsVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Node& node); @@ -276,6 +383,13 @@ class OSGUTIL_EXPORT Optimizer typedef std::set SharedNodeList; SharedNodeList _sharedNodeList; + + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,COPY_SHARED_NODES) : true; + } + + Optimizer* _optimizer; }; }; diff --git a/include/osgUtil/TriStripVisitor b/include/osgUtil/TriStripVisitor index 079251809..97a354bcd 100644 --- a/include/osgUtil/TriStripVisitor +++ b/include/osgUtil/TriStripVisitor @@ -18,7 +18,7 @@ #include #include -#include +#include #include @@ -32,7 +32,7 @@ class OSGUTIL_EXPORT TriStripVisitor : public osg::NodeVisitor public: /// default to traversing all children. - TriStripVisitor() : + TriStripVisitor(Optimizer* optimizer=0) : osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN ), _cacheSize( 16 ), _minStripSize( 2 ) @@ -80,10 +80,16 @@ class OSGUTIL_EXPORT TriStripVisitor : public osg::NodeVisitor return _minStripSize; } + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,osgUtil::Optimizer::TRISTRIP_GEOMETRY) : true; + } + private: typedef std::set GeometryList; + Optimizer* _optimizer; unsigned int _cacheSize; unsigned int _minStripSize; GeometryList _geometryList; diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 650a9975d..04401e6b5 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -50,6 +50,11 @@ static bool isNodeEmpty(const osg::Node& node) return true; } +void Optimizer::reset() +{ + _permissableOptionsMap.clear(); +} + static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \" []\"","DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY"); void Optimizer::optimize(osg::Node* node) @@ -105,7 +110,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing COMBINE_ADJACENT_LODS"<accept(clv); clv.combineLODs(); } @@ -114,7 +119,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing SHARE_DUPLICATE_STATE"<accept(osv); osv.optimize(); } @@ -123,7 +128,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing COPY_SHARED_NODES"<accept(cssv); cssv.copySharedNodes(); } @@ -137,14 +142,14 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) do { osg::notify(osg::DEBUG_INFO) << "** RemoveStaticTransformsVisitor *** Pass "<accept(fstv); result = fstv.removeTransforms(node); ++i; } while (result); // no combine any adjacent static transforms. - CombineStaticTransformsVisitor cstv; + CombineStaticTransformsVisitor cstv(this); node->accept(cstv); cstv.removeTransforms(node); @@ -155,11 +160,11 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing REMOVE_REDUNDANT_NODES"<accept(renv); renv.removeEmptyNodes(); - RemoveRedundantNodesVisitor rrnv; + RemoveRedundantNodesVisitor rrnv(this); node->accept(rrnv); rrnv.removeRedundantNodes(); @@ -169,7 +174,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing SPATIALIZE_GROUPS"<accept(sv); sv.divide(); } @@ -178,7 +183,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing CHECK_GEOMETRY"<accept(mgv); } @@ -186,19 +191,24 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) { osg::notify(osg::INFO)<<"Optimizer::optimize() doing TRISTRIP_GEOMETRY"<accept(tsv); tsv.stripify(); } if (options & MERGE_GEOMETRY) { +#if 0 +// temporary compile out while debugging it. osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEOMETRY"<accept(mgv); +#endif } + + } @@ -236,23 +246,48 @@ void Optimizer::StateVisitor::addStateSet(osg::StateSet* stateset,osg::Object* o void Optimizer::StateVisitor::apply(osg::Node& node) { + osg::StateSet* ss = node.getStateSet(); - if (ss && ss->getDataVariance()==osg::Object::STATIC) addStateSet(ss,&node); + if (ss && ss->getDataVariance()==osg::Object::STATIC) + { + if (isOperationPermissableForObject(&node) && + isOperationPermissableForObject(ss)) + { + addStateSet(ss,&node); + } + } traverse(node); } void Optimizer::StateVisitor::apply(osg::Geode& geode) { + if (!isOperationPermissableForObject(&geode)) return; + osg::StateSet* ss = geode.getStateSet(); - if (ss && ss->getDataVariance()==osg::Object::STATIC) addStateSet(ss,&geode); + + + if (ss && ss->getDataVariance()==osg::Object::STATIC) + { + if (isOperationPermissableForObject(ss)) + { + addStateSet(ss,&geode); + } + } for(unsigned int i=0;igetStateSet(); - if (ss && ss->getDataVariance()==osg::Object::STATIC) addStateSet(ss,drawable); + if (ss && ss->getDataVariance()==osg::Object::STATIC) + { + if (isOperationPermissableForObject(drawable) && + isOperationPermissableForObject(ss)) + { + addStateSet(ss,drawable); + } + } } } } @@ -426,9 +461,9 @@ class CollectLowestTransformsVisitor : public osg::NodeVisitor public: - CollectLowestTransformsVisitor(): - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {} - + CollectLowestTransformsVisitor(Optimizer* optimizer=0): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _optimizer(optimizer) {} virtual void apply(osg::Node& node) { @@ -497,6 +532,11 @@ class CollectLowestTransformsVisitor : public osg::NodeVisitor void disableTransform(osg::Transform* transform); bool removeTransforms(osg::Node* nodeWeCannotRemove); + inline bool isOperationPermissableForObject(const osg::Object* object) const + { + return _optimizer ? _optimizer->isOperationPermissableForObject(object,Optimizer::FLATTEN_STATIC_TRANSFORMS) : true; + } + protected: struct TransformStruct @@ -579,6 +619,7 @@ class CollectLowestTransformsVisitor : public osg::NodeVisitor void doTransform(osg::Object* obj,osg::Matrix& matrix); + Optimizer* _optimizer; TransformMap _transformMap; ObjectMap _objectMap; ObjectList _currentObjectList; @@ -715,20 +756,21 @@ void CollectLowestTransformsVisitor::setUpMaps() // them that can't be applied, and then disable all objects which have // disabled transforms associated, recursing until all disabled // associativity. + // and disable all objects that the operation is not permisable for) for(oitr=_objectMap.begin(); oitr!=_objectMap.end(); ++oitr) { + osg::Object* object = oitr->first; ObjectStruct& os = oitr->second; if (os._canBeApplied) { - if (os._moreThanOneMatrixRequired) + if (os._moreThanOneMatrixRequired || isOperationPermissableForObject(object)) { disableObject(oitr); } } } - } bool CollectLowestTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRemove) @@ -847,7 +889,7 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Transform& transform) bool Optimizer::FlattenStaticTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRemove) { - CollectLowestTransformsVisitor cltv; + CollectLowestTransformsVisitor cltv(_optimizer); for(DrawableSet::iterator ditr=_drawableSet.begin(); ditr!=_drawableSet.end(); @@ -1016,7 +1058,7 @@ void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Group& group) { if (group.getNumParents()>0 && group.getNumChildren()<=1) { - if (isNodeEmpty(group)) + if (isNodeEmpty(group) && isOperationPermissableForObject(&group)) { _redundantNodeList.insert(&group); } @@ -1028,7 +1070,9 @@ void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Group& group) void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Transform& transform) { - if (transform.getNumParents()>0 && transform.getDataVariance()==osg::Object::STATIC) + if (transform.getNumParents()>0 && + transform.getDataVariance()==osg::Object::STATIC && + isOperationPermissableForObject(&transform)) { static osg::Matrix identity; osg::Matrix matrix; @@ -1087,7 +1131,10 @@ void Optimizer::CombineLODsVisitor::apply(osg::LOD& lod) { if (typeid(*lod.getParent(i))==typeid(osg::Group)) { - _groupList.insert(lod.getParent(i)); + if (isOperationPermissableForObject(&lod)) + { + _groupList.insert(lod.getParent(i)); + } } } traverse(lod); @@ -1234,6 +1281,17 @@ struct LessGeometry else if (lhs->getTexCoordIndices(i)) return false; } + for(unsigned int i=0;igetNumVertexAttribArrays();++i) + { + if (rhs->getVertexAttribArray(i)) + { + if (!lhs->getVertexAttribArray(i)) return true; + } + else if (lhs->getVertexAttribArray(i)) return false; + + if (rhs->getVertexAttribIndices(i)) { if (!lhs->getVertexAttribIndices(i)) return true; } + else if (lhs->getVertexAttribIndices(i)) return false; + } if (lhs->getNormalBinding()==osg::Geometry::BIND_OVERALL) @@ -1296,18 +1354,25 @@ struct LessGeometryPrimitiveType void Optimizer::CheckGeometryVisitor::checkGeode(osg::Geode& geode) { - for(unsigned int i=0;iasGeometry(); - if (geom) + for(unsigned int i=0;icomputeCorrectBindingsAndArraySizes(); + osg::Geometry* geom = geode.getDrawable(i)->asGeometry(); + if (geom && isOperationPermissableForObject(geom)) + { + geom->computeCorrectBindingsAndArraySizes(); + } } } } bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) { + if (!isOperationPermissableForObject(&geode)) return false; + +#if 1 + if (geode.getNumDrawables()>=2) { @@ -1331,6 +1396,7 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) } } + // don't merge geometry if its above a maximum number of vertices. unsigned int _maximumNumber = 10000; @@ -1378,6 +1444,8 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode) } } + +#endif // convert all polygon primitives which has 3 indices into TRIANGLES, 4 indices into QUADS. unsigned int i; for(i=0;igetNumElements(); + merger.merge(lhs.getVertexIndices(),rhs.getVertexIndices()); + + } + else if (rhs.getVertexIndices()) + { + base = 0; + lhs.setVertexIndices(rhs.getVertexIndices()); + } + + if (lhs.getNormalArray() && rhs.getNormalArray() && lhs.getNormalBinding()!=osg::Geometry::BIND_OVERALL) { merger.merge(lhs.getNormalArray(),rhs.getNormalArray()); @@ -1586,6 +1669,16 @@ bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geom lhs.setNormalArray(rhs.getNormalArray()); } + if (lhs.getNormalIndices() && rhs.getNormalIndices() && lhs.getNormalBinding()!=osg::Geometry::BIND_OVERALL) + { + merger.merge(lhs.getNormalIndices(),rhs.getNormalIndices()); + } + else if (rhs.getNormalIndices()) + { + lhs.setNormalIndices(rhs.getNormalIndices()); + } + + if (lhs.getColorArray() && rhs.getColorArray() && lhs.getColorBinding()!=osg::Geometry::BIND_OVERALL) { merger.merge(lhs.getColorArray(),rhs.getColorArray()); @@ -1595,36 +1688,148 @@ bool Optimizer::MergeGeometryVisitor::mergeGeometry(osg::Geometry& lhs,osg::Geom lhs.setColorArray(rhs.getColorArray()); } + if (lhs.getColorIndices() && rhs.getColorIndices() && lhs.getColorBinding()!=osg::Geometry::BIND_OVERALL) + { + merger.merge(lhs.getColorIndices(),rhs.getColorIndices()); + } + else if (rhs.getColorIndices()) + { + lhs.setColorIndices(rhs.getColorIndices()); + } + if (lhs.getSecondaryColorArray() && rhs.getSecondaryColorArray() && lhs.getSecondaryColorBinding()!=osg::Geometry::BIND_OVERALL) { merger.merge(lhs.getSecondaryColorArray(),rhs.getSecondaryColorArray()); } - else if (rhs.getColorArray()) + else if (rhs.getSecondaryColorArray()) { lhs.setSecondaryColorArray(rhs.getSecondaryColorArray()); } + if (lhs.getSecondaryColorIndices() && rhs.getSecondaryColorIndices() && lhs.getSecondaryColorBinding()!=osg::Geometry::BIND_OVERALL) + { + merger.merge(lhs.getSecondaryColorIndices(),rhs.getSecondaryColorIndices()); + } + else if (rhs.getSecondaryColorIndices()) + { + lhs.setSecondaryColorIndices(rhs.getSecondaryColorIndices()); + } + if (lhs.getFogCoordArray() && rhs.getFogCoordArray() && lhs.getFogCoordBinding()!=osg::Geometry::BIND_OVERALL) { merger.merge(lhs.getFogCoordArray(),rhs.getFogCoordArray()); } - else if (rhs.getColorArray()) + else if (rhs.getFogCoordArray()) { lhs.setFogCoordArray(rhs.getFogCoordArray()); } + if (lhs.getFogCoordIndices() && rhs.getFogCoordIndices() && lhs.getFogCoordBinding()!=osg::Geometry::BIND_OVERALL) + { + merger.merge(lhs.getFogCoordIndices(),rhs.getFogCoordIndices()); + } + else if (rhs.getFogCoordIndices()) + { + lhs.setFogCoordIndices(rhs.getFogCoordIndices()); + } + + for(unsigned int unit=0;unitget(); - primitive->offsetIndices(base); + switch(primitive->getType()) + { + case(osg::PrimitiveSet::DrawElementsUBytePrimitiveType): + { + osg::DrawElementsUByte* primitiveUByte = static_cast(primitive); + unsigned int currentMaximum = 0; + for(osg::DrawElementsUByte::iterator eitr=primitiveUByte->begin(); + eitr!=primitiveUByte->end(); + ++eitr) + { + currentMaximum = osg::maximum(currentMaximum,(unsigned int)*eitr); + } + if ((base+currentMaximum)>=65536) + { + // must promote to a DrawElementsUInt + osg::DrawElementsUInt* new_primitive = new osg::DrawElementsUInt(); + std::copy(primitiveUByte->begin(),primitiveUByte->end(),std::back_inserter(*new_primitive)); + new_primitive->offsetIndices(base); + (*primItr) = new_primitive; + std::cout<<"Remapping to a UInt "<<(*primItr)->className()<=0) + { + // must promote to a DrawElementsUShort + osg::DrawElementsUShort* new_primitive = new osg::DrawElementsUShort(); + std::copy(primitiveUByte->begin(),primitiveUByte->end(),std::back_inserter(*new_primitive)); + new_primitive->offsetIndices(base); + (*primItr) = new_primitive; + std::cout<<"Remapped to a UShort"<<(*primItr)->className()<offsetIndices(base); + } + } + break; + + case(osg::PrimitiveSet::DrawElementsUShortPrimitiveType): + { + osg::DrawElementsUShort* primitiveUShort = static_cast(primitive); + unsigned int currentMaximum = 0; + for(osg::DrawElementsUShort::iterator eitr=primitiveUShort->begin(); + eitr!=primitiveUShort->end(); + ++eitr) + { + currentMaximum = osg::maximum(currentMaximum,(unsigned int)*eitr); + } + if ((base+currentMaximum)>=65536) + { + // must promote to a DrawElementsUInt + osg::DrawElementsUInt* new_primitive = new osg::DrawElementsUInt(); + std::copy(primitiveUShort->begin(),primitiveUShort->end(),std::back_inserter(*new_primitive)); + new_primitive->offsetIndices(base); + (*primItr) = new_primitive; + } + else + { + primitive->offsetIndices(base); + } + } + break; + + case(osg::PrimitiveSet::DrawArraysPrimitiveType): + case(osg::PrimitiveSet::DrawArrayLengthsPrimitiveType): + case(osg::PrimitiveSet::DrawElementsUIntPrimitiveType): + default: + primitive->offsetIndices(base); + break; + } + + } lhs.getPrimitiveSetList().insert(lhs.getPrimitiveSetList().end(), @@ -1686,7 +1891,10 @@ void Optimizer::SpatializeGroupsVisitor::apply(osg::Group& group) { if (typeid(group)==typeid(osg::Group) || group.asTransform()) { - _groupsToDivideList.insert(&group); + if (isOperationPermissableForObject(&group)) + { + _groupsToDivideList.insert(&group); + } } traverse(group); } @@ -1872,7 +2080,7 @@ bool Optimizer::SpatializeGroupsVisitor::divide(osg::Group* group, unsigned int void Optimizer::CopySharedSubgraphsVisitor::apply(osg::Node& node) { - if (node.getNumParents()>1) + if (node.getNumParents()>1 && !isOperationPermissableForObject(&node)) { _sharedNodeList.insert(&node); } diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index ac8cddcf3..6ac51857f 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -527,7 +527,7 @@ void TriStripVisitor::stripify(Geometry& geom) if (geom.suitableForOptimization()) { // removing coord indices - std::cout<<"Removing attribute indices"<=minimum_ratio_of_indices_to_unique_vertices) { - std::cout<<" doing tri strip"<< std::endl; + osg::notify(osg::INFO)<<"TriStripVisitor::stripify(Geometry&): doing tri strip"<< std::endl; unsigned int in_numVertices = 0; for(triangle_stripper::tri_stripper::indices::iterator itr=taf._in_indices.begin(); @@ -872,7 +872,7 @@ void TriStripVisitor::stripify(Geometry& geom) } else { - std::cout<<" not doing tri strip *****************"<< std::endl; + osg::notify(osg::INFO)<<"TriStripVisitor::stripify(Geometry&): not doing tri strip *****************"<< std::endl; } }