Adds an indexMesh option to disable mesh reindexation
This mainly breaks gles/osgjs when stripifying a MorphGeometry. It also usually doesn't make sense to reindex an already indexed mesh.
This commit is contained in:
parent
7c0c98b504
commit
da47f8a156
@ -37,7 +37,8 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor
|
|||||||
_cacheSize( 16 ),
|
_cacheSize( 16 ),
|
||||||
_minStripSize( 2 ),
|
_minStripSize( 2 ),
|
||||||
_generateFourPointPrimitivesQuads ( false ),
|
_generateFourPointPrimitivesQuads ( false ),
|
||||||
_mergeTriangleStrips( false )
|
_mergeTriangleStrips( false ),
|
||||||
|
_indexMesh( true )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** Convert mesh primitives in Geometry into Tri Strips.
|
/** Convert mesh primitives in Geometry into Tri Strips.
|
||||||
@ -74,6 +75,15 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor
|
|||||||
return _minStripSize;
|
return _minStripSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setIndexMesh( bool allow )
|
||||||
|
{
|
||||||
|
_indexMesh = allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool getIndexMesh() const
|
||||||
|
{
|
||||||
|
return _indexMesh;
|
||||||
|
}
|
||||||
|
|
||||||
void setGenerateFourPointPrimitivesQuads(bool flag) { _generateFourPointPrimitivesQuads = flag; }
|
void setGenerateFourPointPrimitivesQuads(bool flag) { _generateFourPointPrimitivesQuads = flag; }
|
||||||
bool getGenerateFourPointPrimitivesQuads() const { return _generateFourPointPrimitivesQuads; }
|
bool getGenerateFourPointPrimitivesQuads() const { return _generateFourPointPrimitivesQuads; }
|
||||||
@ -90,6 +100,7 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor
|
|||||||
GeometryList _geometryList;
|
GeometryList _geometryList;
|
||||||
bool _generateFourPointPrimitivesQuads;
|
bool _generateFourPointPrimitivesQuads;
|
||||||
bool _mergeTriangleStrips;
|
bool _mergeTriangleStrips;
|
||||||
|
bool _indexMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,146 @@ protected:
|
|||||||
RemapArray& operator = (const RemapArray&) { return *this; }
|
RemapArray& operator = (const RemapArray&) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void indexGeometry(osg::Geometry& geom, IndexList& mapping) {
|
||||||
|
// check for the existence of surface primitives
|
||||||
|
unsigned int numSurfacePrimitives = 0;
|
||||||
|
unsigned int numNonSurfacePrimitives = 0;
|
||||||
|
Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList();
|
||||||
|
for(Geometry::PrimitiveSetList::iterator itr=primitives.begin();
|
||||||
|
itr!=primitives.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
switch((*itr)->getMode())
|
||||||
|
{
|
||||||
|
case(PrimitiveSet::TRIANGLES):
|
||||||
|
case(PrimitiveSet::TRIANGLE_STRIP):
|
||||||
|
case(PrimitiveSet::TRIANGLE_FAN):
|
||||||
|
case(PrimitiveSet::QUADS):
|
||||||
|
case(PrimitiveSet::QUAD_STRIP):
|
||||||
|
case(PrimitiveSet::POLYGON):
|
||||||
|
++numSurfacePrimitives;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
++numNonSurfacePrimitives;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nothitng to tri strip leave.
|
||||||
|
if (!numSurfacePrimitives) return;
|
||||||
|
|
||||||
|
// compute duplicate vertices
|
||||||
|
|
||||||
|
unsigned int numVertices = geom.getVertexArray()->getNumElements();
|
||||||
|
IndexList vindices(numVertices);
|
||||||
|
unsigned int i,j;
|
||||||
|
for(i=0;i<numVertices;++i)
|
||||||
|
{
|
||||||
|
vindices[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexAttribComparitor arrayComparitor(geom);
|
||||||
|
std::sort(vindices.begin(),vindices.end(),arrayComparitor);
|
||||||
|
|
||||||
|
unsigned int lastUnique = 0;
|
||||||
|
unsigned int numUnique = 1;
|
||||||
|
unsigned int numDuplicate = 0;
|
||||||
|
for(i=1;i<numVertices;++i)
|
||||||
|
{
|
||||||
|
if (arrayComparitor.compare(vindices[lastUnique],vindices[i])==0)
|
||||||
|
{
|
||||||
|
++numDuplicate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastUnique = i;
|
||||||
|
++numUnique;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexList remapDuplicatesToOrignals(numVertices);
|
||||||
|
lastUnique = 0;
|
||||||
|
for(i=1;i<numVertices;++i)
|
||||||
|
{
|
||||||
|
if (arrayComparitor.compare(vindices[lastUnique],vindices[i])!=0)
|
||||||
|
{
|
||||||
|
// found a new vertex entry, so previous run of duplicates needs
|
||||||
|
// to be put together.
|
||||||
|
unsigned int min_index = vindices[lastUnique];
|
||||||
|
for(j=lastUnique+1;j<i;++j)
|
||||||
|
{
|
||||||
|
min_index = osg::minimum(min_index,vindices[j]);
|
||||||
|
}
|
||||||
|
for(j=lastUnique;j<i;++j)
|
||||||
|
{
|
||||||
|
remapDuplicatesToOrignals[vindices[j]]=min_index;
|
||||||
|
}
|
||||||
|
lastUnique = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
unsigned int min_index = vindices[lastUnique];
|
||||||
|
for(j=lastUnique+1;j<i;++j)
|
||||||
|
{
|
||||||
|
min_index = osg::minimum(min_index,vindices[j]);
|
||||||
|
}
|
||||||
|
for(j=lastUnique;j<i;++j)
|
||||||
|
{
|
||||||
|
remapDuplicatesToOrignals[vindices[j]]=min_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// copy the arrays.
|
||||||
|
IndexList finalMapping(numVertices);
|
||||||
|
IndexList copyMapping;
|
||||||
|
copyMapping.reserve(numUnique);
|
||||||
|
unsigned int currentIndex=0;
|
||||||
|
for(i=0;i<numVertices;++i)
|
||||||
|
{
|
||||||
|
if (remapDuplicatesToOrignals[i]==i)
|
||||||
|
{
|
||||||
|
finalMapping[i] = currentIndex;
|
||||||
|
copyMapping.push_back(i);
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i=0;i<numVertices;++i)
|
||||||
|
{
|
||||||
|
if (remapDuplicatesToOrignals[i]!=i)
|
||||||
|
{
|
||||||
|
finalMapping[i] = finalMapping[remapDuplicatesToOrignals[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float minimum_ratio_of_indices_to_unique_vertices = 1;
|
||||||
|
unsigned int nbPrimitiveIndices = 0;
|
||||||
|
for(unsigned int k = 0 ; k < geom.getNumPrimitiveSets() ; ++ k) {
|
||||||
|
osg::PrimitiveSet* primitive = geom.getPrimitiveSet(k);
|
||||||
|
if(primitive) {
|
||||||
|
nbPrimitiveIndices += primitive->getNumIndices();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float ratio_of_indices_to_unique_vertices = ((float)nbPrimitiveIndices/(float)numUnique);
|
||||||
|
|
||||||
|
if(!finalMapping.empty() &&
|
||||||
|
ratio_of_indices_to_unique_vertices >= minimum_ratio_of_indices_to_unique_vertices) {
|
||||||
|
|
||||||
|
OSG_INFO << "TriStripVisitor::stripify(Geometry&): Number of indices" << nbPrimitiveIndices
|
||||||
|
<< " numUnique" << numUnique << std::endl;
|
||||||
|
OSG_INFO << "TriStripVisitor::stripify(Geometry&): ratio indices/numUnique"
|
||||||
|
<< ratio_of_indices_to_unique_vertices << std::endl;
|
||||||
|
|
||||||
|
// remap any shared vertex attributes
|
||||||
|
RemapArray ra(copyMapping);
|
||||||
|
arrayComparitor.accept(ra);
|
||||||
|
finalMapping.swap(mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct MyTriangleOperator
|
struct MyTriangleOperator
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -227,129 +367,20 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
// no point tri stripping if we don't have enough vertices.
|
// no point tri stripping if we don't have enough vertices.
|
||||||
if (!geom.getVertexArray() || geom.getVertexArray()->getNumElements()<3) return;
|
if (!geom.getVertexArray() || geom.getVertexArray()->getNumElements()<3) return;
|
||||||
|
|
||||||
// check for the existence of surface primitives
|
IndexList mapping;
|
||||||
unsigned int numSurfacePrimitives = 0;
|
if(_indexMesh) {
|
||||||
unsigned int numNonSurfacePrimitives = 0;
|
indexGeometry(geom, mapping);
|
||||||
Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList();
|
if(mapping.empty()) {
|
||||||
for(Geometry::PrimitiveSetList::iterator itr=primitives.begin();
|
return;
|
||||||
itr!=primitives.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
switch((*itr)->getMode())
|
|
||||||
{
|
|
||||||
case(PrimitiveSet::TRIANGLES):
|
|
||||||
case(PrimitiveSet::TRIANGLE_STRIP):
|
|
||||||
case(PrimitiveSet::TRIANGLE_FAN):
|
|
||||||
case(PrimitiveSet::QUADS):
|
|
||||||
case(PrimitiveSet::QUAD_STRIP):
|
|
||||||
case(PrimitiveSet::POLYGON):
|
|
||||||
++numSurfacePrimitives;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
++numNonSurfacePrimitives;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothitng to tri strip leave.
|
|
||||||
if (!numSurfacePrimitives) return;
|
|
||||||
|
|
||||||
// compute duplicate vertices
|
|
||||||
|
|
||||||
unsigned int numVertices = geom.getVertexArray()->getNumElements();
|
|
||||||
IndexList vindices(numVertices);
|
|
||||||
unsigned int i,j;
|
|
||||||
for(i=0;i<numVertices;++i)
|
|
||||||
{
|
|
||||||
vindices[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexAttribComparitor arrayComparitor(geom);
|
|
||||||
std::sort(vindices.begin(), vindices.end(), arrayComparitor);
|
|
||||||
|
|
||||||
unsigned int lastUnique = 0;
|
|
||||||
unsigned int numUnique = 1;
|
|
||||||
unsigned int numDuplicate = 0;
|
|
||||||
for(i=1;i<numVertices;++i)
|
|
||||||
{
|
|
||||||
if (arrayComparitor.compare(vindices[lastUnique], vindices[i])==0)
|
|
||||||
{
|
|
||||||
//std::cout<<" found duplicate "<<indices[lastUnique]<<" and "<<indices[i]<<std::endl;
|
|
||||||
++numDuplicate;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//std::cout<<" unique "<<indices[i]<<std::endl;
|
|
||||||
lastUnique = i;
|
|
||||||
++numUnique;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
// std::cout<<" Number of duplicates "<<numDuplicate<<std::endl;
|
|
||||||
// std::cout<<" Number of unique "<<numUnique<<std::endl;
|
|
||||||
// std::cout<<" Total number of vertices required "<<numUnique<<" vs original "<<numVertices<<std::endl;
|
|
||||||
// std::cout<<" % size "<<(float)numUnique/(float)numVertices*100.0f<<std::endl;
|
|
||||||
|
|
||||||
IndexList remapDuplicatesToOrignals(numVertices);
|
|
||||||
lastUnique = 0;
|
|
||||||
for(i=1;i<numVertices;++i)
|
|
||||||
{
|
|
||||||
if (arrayComparitor.compare(vindices[lastUnique], vindices[i])!=0)
|
|
||||||
{
|
|
||||||
// found a new vertex entry, so previous run of duplicates needs
|
|
||||||
// to be put together.
|
|
||||||
unsigned int min_index = vindices[lastUnique];
|
|
||||||
for(j=lastUnique+1;j<i;++j)
|
|
||||||
{
|
|
||||||
min_index = osg::minimum(min_index, vindices[j]);
|
|
||||||
}
|
|
||||||
for(j=lastUnique;j<i;++j)
|
|
||||||
{
|
|
||||||
remapDuplicatesToOrignals[vindices[j]]=min_index;
|
|
||||||
}
|
|
||||||
lastUnique = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
unsigned int min_index = vindices[lastUnique];
|
|
||||||
for(j=lastUnique+1;j<i;++j)
|
|
||||||
{
|
|
||||||
min_index = osg::minimum(min_index, vindices[j]);
|
|
||||||
}
|
|
||||||
for(j=lastUnique;j<i;++j)
|
|
||||||
{
|
|
||||||
remapDuplicatesToOrignals[vindices[j]]=min_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// copy the arrays.
|
|
||||||
IndexList finalMapping(numVertices);
|
|
||||||
IndexList copyMapping;
|
|
||||||
copyMapping.reserve(numUnique);
|
|
||||||
unsigned int currentIndex=0;
|
|
||||||
for(i=0;i<numVertices;++i)
|
|
||||||
{
|
|
||||||
if (remapDuplicatesToOrignals[i]==i)
|
|
||||||
{
|
|
||||||
finalMapping[i] = currentIndex;
|
|
||||||
copyMapping.push_back(i);
|
|
||||||
currentIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0;i<numVertices;++i)
|
|
||||||
{
|
|
||||||
if (remapDuplicatesToOrignals[i]!=i)
|
|
||||||
{
|
|
||||||
finalMapping[i] = finalMapping[remapDuplicatesToOrignals[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MyTriangleIndexFunctor taf;
|
MyTriangleIndexFunctor taf;
|
||||||
taf._remapIndices.swap(finalMapping);
|
if(!mapping.empty()) {
|
||||||
|
taf._remapIndices.swap(mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList();
|
||||||
Geometry::PrimitiveSetList new_primitives;
|
Geometry::PrimitiveSetList new_primitives;
|
||||||
new_primitives.reserve(primitives.size());
|
new_primitives.reserve(primitives.size());
|
||||||
|
|
||||||
@ -370,18 +401,11 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
default:
|
default:
|
||||||
new_primitives.push_back(*itr);
|
new_primitives.push_back(*itr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float minimum_ratio_of_indices_to_unique_vertices = 1;
|
|
||||||
float ratio_of_indices_to_unique_vertices = ((float)taf._in_indices.size()/(float)numUnique);
|
|
||||||
|
|
||||||
OSG_INFO<<"TriStripVisitor::stripify(Geometry&): Number of indices"<<taf._in_indices.size()<<" numUnique"<< numUnique << std::endl;
|
|
||||||
OSG_INFO<<"TriStripVisitor::stripify(Geometry&): ratio indices/numUnique"<< ratio_of_indices_to_unique_vertices << std::endl;
|
|
||||||
|
|
||||||
// only tri strip if there is point in doing so.
|
// only tri strip if there is point in doing so.
|
||||||
if (!taf._in_indices.empty() && ratio_of_indices_to_unique_vertices>=minimum_ratio_of_indices_to_unique_vertices)
|
if (!taf._in_indices.empty())
|
||||||
{
|
{
|
||||||
OSG_INFO<<"TriStripVisitor::stripify(Geometry&): doing tri strip"<< std::endl;
|
OSG_INFO<<"TriStripVisitor::stripify(Geometry&): doing tri strip"<< std::endl;
|
||||||
|
|
||||||
@ -393,13 +417,9 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
if (*itr>in_numVertices) in_numVertices=*itr;
|
if (*itr>in_numVertices) in_numVertices=*itr;
|
||||||
}
|
}
|
||||||
// the largest indice is in_numVertices, but indices start at 0
|
// the largest indice is in_numVertices, but indices start at 0
|
||||||
// so increment to give to the corrent number of verticies.
|
// so increment to give to the corrent number of vertices.
|
||||||
++in_numVertices;
|
++in_numVertices;
|
||||||
|
|
||||||
// remap any shared vertex attributes
|
|
||||||
RemapArray ra(copyMapping);
|
|
||||||
arrayComparitor.accept(ra);
|
|
||||||
|
|
||||||
triangle_stripper::tri_stripper stripifier(taf._in_indices);
|
triangle_stripper::tri_stripper stripifier(taf._in_indices);
|
||||||
stripifier.SetCacheSize(_cacheSize);
|
stripifier.SetCacheSize(_cacheSize);
|
||||||
stripifier.SetMinStripSize(_minStripSize);
|
stripifier.SetMinStripSize(_minStripSize);
|
||||||
@ -450,7 +470,7 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
pitr = qitr->second;
|
pitr = qitr->second;
|
||||||
|
|
||||||
unsigned int min_pos = 0;
|
unsigned int min_pos = 0;
|
||||||
for(i=1;i<4;++i)
|
for(unsigned int i = 1 ; i < 4 ; ++ i)
|
||||||
{
|
{
|
||||||
if (pitr->Indices[min_pos]>pitr->Indices[i])
|
if (pitr->Indices[min_pos]>pitr->Indices[i])
|
||||||
min_pos = i;
|
min_pos = i;
|
||||||
|
Loading…
Reference in New Issue
Block a user