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,46 +187,8 @@ protected:
|
|||||||
RemapArray& operator = (const RemapArray&) { return *this; }
|
RemapArray& operator = (const RemapArray&) { return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MyTriangleOperator
|
|
||||||
{
|
|
||||||
|
|
||||||
IndexList _remapIndices;
|
|
||||||
triangle_stripper::indices _in_indices;
|
|
||||||
|
|
||||||
inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3)
|
|
||||||
{
|
|
||||||
if (_remapIndices.empty())
|
|
||||||
{
|
|
||||||
_in_indices.push_back(p1);
|
|
||||||
_in_indices.push_back(p2);
|
|
||||||
_in_indices.push_back(p3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_in_indices.push_back(_remapIndices[p1]);
|
|
||||||
_in_indices.push_back(_remapIndices[p2]);
|
|
||||||
_in_indices.push_back(_remapIndices[p3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
typedef osg::TriangleIndexFunctor<MyTriangleOperator> MyTriangleIndexFunctor;
|
|
||||||
|
|
||||||
void TriStripVisitor::stripify(Geometry& geom)
|
|
||||||
{
|
|
||||||
if (geom.containsDeprecatedData()) geom.fixDeprecatedData();
|
|
||||||
|
|
||||||
if (osg::getBinding(geom.getNormalArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
|
||||||
|
|
||||||
if (osg::getBinding(geom.getColorArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
|
||||||
|
|
||||||
if (osg::getBinding(geom.getSecondaryColorArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
|
||||||
|
|
||||||
if (osg::getBinding(geom.getFogCoordArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
|
||||||
|
|
||||||
// no point tri stripping if we don't have enough vertices.
|
|
||||||
if (!geom.getVertexArray() || geom.getVertexArray()->getNumElements()<3) return;
|
|
||||||
|
|
||||||
|
void indexGeometry(osg::Geometry& geom, IndexList& mapping) {
|
||||||
// check for the existence of surface primitives
|
// check for the existence of surface primitives
|
||||||
unsigned int numSurfacePrimitives = 0;
|
unsigned int numSurfacePrimitives = 0;
|
||||||
unsigned int numNonSurfacePrimitives = 0;
|
unsigned int numNonSurfacePrimitives = 0;
|
||||||
@ -248,7 +210,6 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
default:
|
default:
|
||||||
++numNonSurfacePrimitives;
|
++numNonSurfacePrimitives;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,21 +236,15 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
{
|
{
|
||||||
if (arrayComparitor.compare(vindices[lastUnique],vindices[i])==0)
|
if (arrayComparitor.compare(vindices[lastUnique],vindices[i])==0)
|
||||||
{
|
{
|
||||||
//std::cout<<" found duplicate "<<indices[lastUnique]<<" and "<<indices[i]<<std::endl;
|
|
||||||
++numDuplicate;
|
++numDuplicate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//std::cout<<" unique "<<indices[i]<<std::endl;
|
|
||||||
lastUnique = i;
|
lastUnique = i;
|
||||||
++numUnique;
|
++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);
|
IndexList remapDuplicatesToOrignals(numVertices);
|
||||||
lastUnique = 0;
|
lastUnique = 0;
|
||||||
@ -346,10 +301,86 @@ void TriStripVisitor::stripify(Geometry& geom)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
|
||||||
|
IndexList _remapIndices;
|
||||||
|
triangle_stripper::indices _in_indices;
|
||||||
|
|
||||||
|
inline void operator()(unsigned int p1, unsigned int p2, unsigned int p3)
|
||||||
|
{
|
||||||
|
if (_remapIndices.empty())
|
||||||
|
{
|
||||||
|
_in_indices.push_back(p1);
|
||||||
|
_in_indices.push_back(p2);
|
||||||
|
_in_indices.push_back(p3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_in_indices.push_back(_remapIndices[p1]);
|
||||||
|
_in_indices.push_back(_remapIndices[p2]);
|
||||||
|
_in_indices.push_back(_remapIndices[p3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
typedef osg::TriangleIndexFunctor<MyTriangleOperator> MyTriangleIndexFunctor;
|
||||||
|
|
||||||
|
void TriStripVisitor::stripify(Geometry& geom)
|
||||||
|
{
|
||||||
|
if (geom.containsDeprecatedData()) geom.fixDeprecatedData();
|
||||||
|
|
||||||
|
if (osg::getBinding(geom.getNormalArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
||||||
|
|
||||||
|
if (osg::getBinding(geom.getColorArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
||||||
|
|
||||||
|
if (osg::getBinding(geom.getSecondaryColorArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
||||||
|
|
||||||
|
if (osg::getBinding(geom.getFogCoordArray())==osg::Array::BIND_PER_PRIMITIVE_SET) return;
|
||||||
|
|
||||||
|
// no point tri stripping if we don't have enough vertices.
|
||||||
|
if (!geom.getVertexArray() || geom.getVertexArray()->getNumElements()<3) return;
|
||||||
|
|
||||||
|
IndexList mapping;
|
||||||
|
if(_indexMesh) {
|
||||||
|
indexGeometry(geom, mapping);
|
||||||
|
if(mapping.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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