From a25e14b42f46456215ae27efbde59bce594fda6a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 9 Dec 2003 22:29:56 +0000 Subject: [PATCH] Improvements to the TriStripVisitor such that it now groups 4 point tri strips together as quads. --- src/osgUtil/Optimizer.cpp | 21 +++--- src/osgUtil/TriStripVisitor.cpp | 128 +++++++++++++++++++++++++++----- 2 files changed, 122 insertions(+), 27 deletions(-) diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index b04cbfe9b..650a9975d 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -49,6 +50,8 @@ static bool isNodeEmpty(const osg::Node& node) return true; } +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) { unsigned int options = 0; @@ -59,31 +62,31 @@ void Optimizer::optimize(osg::Node* node) std::string str(env); - if(str.find("!DEFAULT")!=std::string::npos) options ^= DEFAULT_OPTIMIZATIONS; + if(str.find("~DEFAULT")!=std::string::npos) options ^= DEFAULT_OPTIMIZATIONS; else if(str.find("DEFAULT")!=std::string::npos) options |= DEFAULT_OPTIMIZATIONS; - if(str.find("!FLATTEN_STATIC_TRANSFORMS")!=std::string::npos) options ^= FLATTEN_STATIC_TRANSFORMS; + if(str.find("~FLATTEN_STATIC_TRANSFORMS")!=std::string::npos) options ^= FLATTEN_STATIC_TRANSFORMS; else if(str.find("FLATTEN_STATIC_TRANSFORMS")!=std::string::npos) options |= FLATTEN_STATIC_TRANSFORMS; - if(str.find("!REMOVE_REDUNDANT_NODES")!=std::string::npos) options ^= REMOVE_REDUNDANT_NODES; + if(str.find("~REMOVE_REDUNDANT_NODES")!=std::string::npos) options ^= REMOVE_REDUNDANT_NODES; else if(str.find("REMOVE_REDUNDANT_NODES")!=std::string::npos) options |= REMOVE_REDUNDANT_NODES; - if(str.find("!COMBINE_ADJACENT_LODS")!=std::string::npos) options ^= COMBINE_ADJACENT_LODS; + if(str.find("~COMBINE_ADJACENT_LODS")!=std::string::npos) options ^= COMBINE_ADJACENT_LODS; else if(str.find("COMBINE_ADJACENT_LODS")!=std::string::npos) options |= COMBINE_ADJACENT_LODS; - if(str.find("!SHARE_DUPLICATE_STATE")!=std::string::npos) options ^= SHARE_DUPLICATE_STATE; + if(str.find("~SHARE_DUPLICATE_STATE")!=std::string::npos) options ^= SHARE_DUPLICATE_STATE; else if(str.find("SHARE_DUPLICATE_STATE")!=std::string::npos) options |= SHARE_DUPLICATE_STATE; - if(str.find("!MERGE_GEOMETRY")!=std::string::npos) options ^= MERGE_GEOMETRY; + if(str.find("~MERGE_GEOMETRY")!=std::string::npos) options ^= MERGE_GEOMETRY; else if(str.find("MERGE_GEOMETRY")!=std::string::npos) options |= MERGE_GEOMETRY; - if(str.find("!SPATIALIZE_GROUPS")!=std::string::npos) options ^= SPATIALIZE_GROUPS; + if(str.find("~SPATIALIZE_GROUPS")!=std::string::npos) options ^= SPATIALIZE_GROUPS; else if(str.find("SPATIALIZE_GROUPS")!=std::string::npos) options |= SPATIALIZE_GROUPS; - if(str.find("!COPY_SHARED_NODES")!=std::string::npos) options ^= COPY_SHARED_NODES; + if(str.find("~COPY_SHARED_NODES")!=std::string::npos) options ^= COPY_SHARED_NODES; else if(str.find("COPY_SHARED_NODES")!=std::string::npos) options |= COPY_SHARED_NODES; - if(str.find("!TRISTRIP_GEOMETRY")!=std::string::npos) options ^= TRISTRIP_GEOMETRY; + if(str.find("~TRISTRIP_GEOMETRY")!=std::string::npos) options ^= TRISTRIP_GEOMETRY; else if(str.find("TRISTRIP_GEOMETRY")!=std::string::npos) options |= TRISTRIP_GEOMETRY; } diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index 5e041941b..39a70ffe4 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "TriStrip_tri_stripper.h" @@ -681,7 +682,7 @@ void TriStripVisitor::stripify(Geometry& geom) } } - float minimum_ratio_of_indices_to_unique_vertices = 2.0; + float minimum_ratio_of_indices_to_unique_vertices = 1.5; float ratio_of_indices_to_unique_vertices = ((float)taf._in_indices.size()/(float)numUnique); std::cout<<"Number of indices"< QuadMap; + QuadMap quadMap; - for(triangle_stripper::tri_stripper::primitives_vector::iterator pitr=outPrimitives.begin(); + triangle_stripper::tri_stripper::primitives_vector::iterator pitr; + + // pick out quads and place them in the quadMap, and also look for the max + for(pitr=outPrimitives.begin(); pitr!=outPrimitives.end(); ++pitr) { - - unsigned int maxValue = *(std::max_element(pitr->m_Indices.begin(),pitr->m_Indices.end())); - if (maxValue<256) + if (pitr->m_Indices.size()==4) { - osg::DrawElementsUByte* elements = new osg::DrawElementsUByte(pitr->m_Type); - elements->reserve(pitr->m_Indices.size()); - std::copy(pitr->m_Indices.begin(),pitr->m_Indices.end(),std::back_inserter(*elements)); - new_primitives.push_back(elements); + std::swap(pitr->m_Indices[2],pitr->m_Indices[3]); + unsigned int minValue = *(std::max_element(pitr->m_Indices.begin(),pitr->m_Indices.end())); + quadMap.insert(std::pair(minValue,pitr)); } - else if (maxValue<65536) + } + + + // handle the quads + if (!quadMap.empty()) + { + IndexList indices; + indices.reserve(quadMap.size()); + + // adds all the quads into the quad primitive, in ascending order + // and the QuadMap stores the quad's in ascending order. + for(QuadMap::iterator qitr=quadMap.begin(); + qitr!=quadMap.end(); + ++qitr) { - osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(pitr->m_Type); - elements->reserve(pitr->m_Indices.size()); - std::copy(pitr->m_Indices.begin(),pitr->m_Indices.end(),std::back_inserter(*elements)); - new_primitives.push_back(elements); + pitr = qitr->second; + + unsigned int min_pos = 0; + for(i=1;i<4;++i) + { + if (pitr->m_Indices[min_pos]>pitr->m_Indices[i]) + min_pos = i; + } + indices.push_back(pitr->m_Indices[min_pos]); + indices.push_back(pitr->m_Indices[(min_pos+1)%4]); + indices.push_back(pitr->m_Indices[(min_pos+2)%4]); + indices.push_back(pitr->m_Indices[(min_pos+3)%4]); + } + + bool inOrder = true; + unsigned int previousValue = indices.front(); + for(IndexList::iterator qi_itr=indices.begin()+1; + qi_itr!=indices.end() && inOrder; + ++qi_itr) + { + inOrder = (previousValue+1)==*qi_itr; + previousValue = *qi_itr; + } + + if (inOrder) + { + new_primitives.push_back(new osg::DrawArrays(GL_QUADS,indices.front(),indices.size())); } else { - osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(pitr->m_Type); - elements->reserve(pitr->m_Indices.size()); - std::copy(pitr->m_Indices.begin(),pitr->m_Indices.end(),std::back_inserter(*elements)); - new_primitives.push_back(elements); + unsigned int maxValue = *(std::max_element(indices.begin(),indices.end())); + + if (maxValue<256) + { + osg::DrawElementsUByte* elements = new osg::DrawElementsUByte(GL_QUADS); + std::copy(indices.begin(),indices.end(),std::back_inserter(*elements)); + new_primitives.push_back(elements); + } + else if (maxValue<65536) + { + osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(GL_QUADS); + std::copy(indices.begin(),indices.end(),std::back_inserter(*elements)); + new_primitives.push_back(elements); + } + else + { + osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_QUADS); + std::copy(indices.begin(),indices.end(),std::back_inserter(*elements)); + new_primitives.push_back(elements); + } + } + } + + + // handle non quad primitives + for(pitr=outPrimitives.begin(); + pitr!=outPrimitives.end(); + ++pitr) + { + if (pitr->m_Indices.size()!=4) + { + unsigned int maxValue = *(std::max_element(pitr->m_Indices.begin(),pitr->m_Indices.end())); + if (maxValue<256) + { + osg::DrawElementsUByte* elements = new osg::DrawElementsUByte(pitr->m_Type); + elements->reserve(pitr->m_Indices.size()); + std::copy(pitr->m_Indices.begin(),pitr->m_Indices.end(),std::back_inserter(*elements)); + new_primitives.push_back(elements); + } + else if (maxValue<65536) + { + osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(pitr->m_Type); + elements->reserve(pitr->m_Indices.size()); + std::copy(pitr->m_Indices.begin(),pitr->m_Indices.end(),std::back_inserter(*elements)); + new_primitives.push_back(elements); + } + else + { + osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(pitr->m_Type); + elements->reserve(pitr->m_Indices.size()); + std::copy(pitr->m_Indices.begin(),pitr->m_Indices.end(),std::back_inserter(*elements)); + new_primitives.push_back(elements); + } } } + geom.setPrimitiveSetList(new_primitives); #if 0