From Time Moore, "This submission implements 3 optimizations for meshes. INDEX_MESH turns DrawArrays style geometry into DrawElements, uniquifying the vertices in the process. This is useful for certain loaders, like ac3d, which just spit out DrawArrays. VERTEX_POSTTRANSFORM and VERTEX_PRETRANSFORM optimize mesh triangle and vertex order for the caches on a modern GPU, using Tom Forsyth's algorithm. I describe this and the big difference it makes (38% improvement on a very large mesh) in my blog,

http://shiny-dynamics.blogspot.com/2010/03/vertex-cache-optimization-for-osg.html."
This commit is contained in:
Robert Osfield
2010-03-11 18:15:20 +00:00
parent 4dcf21d707
commit 7a44b43474
5 changed files with 1289 additions and 1 deletions

View File

@@ -24,6 +24,7 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/IntersectVisitor
${HEADER_PATH}/IncrementalCompileOperation
${HEADER_PATH}/LineSegmentIntersector
${HEADER_PATH}/MeshOptimizers
${HEADER_PATH}/OperationArrayFunctor
${HEADER_PATH}/Optimizer
${HEADER_PATH}/PlaneIntersector
@@ -67,6 +68,7 @@ ADD_LIBRARY(${LIB_NAME}
IntersectVisitor.cpp
IncrementalCompileOperation.cpp
LineSegmentIntersector.cpp
MeshOptimizers.cpp
Optimizer.cpp
PlaneIntersector.cpp
PolytopeIntersector.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -39,6 +39,7 @@
#include <osgUtil/TriStripVisitor>
#include <osgUtil/Tessellator>
#include <osgUtil/Statistics>
#include <osgUtil/MeshOptimizers>
#include <typeinfo>
#include <algorithm>
@@ -54,7 +55,7 @@ void Optimizer::reset()
{
}
static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \"<type> [<type>]\"","OFF | DEFAULT | FLATTEN_STATIC_TRANSFORMS | FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | MERGE_GEODES | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS | REMOVE_LOADED_PROXY_NODES | TESSELLATE_GEOMETRY | CHECK_GEOMETRY | FLATTEN_BILLBOARDS | TEXTURE_ATLAS_BUILDER | STATIC_OBJECT_DETECTION");
static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \"<type> [<type>]\"","OFF | DEFAULT | FLATTEN_STATIC_TRANSFORMS | FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | MERGE_GEODES | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS | REMOVE_LOADED_PROXY_NODES | TESSELLATE_GEOMETRY | CHECK_GEOMETRY | FLATTEN_BILLBOARDS | TEXTURE_ATLAS_BUILDER | STATIC_OBJECT_DETECTION | INDEX_MESH | VERTEX_POSTTRANSFORM | VERTEX_PRETRANSFORM");
void Optimizer::optimize(osg::Node* node)
{
@@ -125,6 +126,15 @@ void Optimizer::optimize(osg::Node* node)
if(str.find("~STATIC_OBJECT_DETECTION")!=std::string::npos) options ^= STATIC_OBJECT_DETECTION;
else if(str.find("STATIC_OBJECT_DETECTION")!=std::string::npos) options |= STATIC_OBJECT_DETECTION;
if(str.find("~INDEX_MESH")!=std::string::npos) options ^= INDEX_MESH;
else if(str.find("INDEX_MESH")!=std::string::npos) options |= INDEX_MESH;
if(str.find("~VERTEX_POSTTRANSFORM")!=std::string::npos) options ^= VERTEX_POSTTRANSFORM;
else if(str.find("VERTEX_POSTTRANSFORM")!=std::string::npos) options |= VERTEX_POSTTRANSFORM;
if(str.find("~VERTEX_PRETRANSFORM")!=std::string::npos) options ^= VERTEX_PRETRANSFORM;
else if(str.find("VERTEX_PRETRANSFORM")!=std::string::npos) options |= VERTEX_PRETRANSFORM;
}
else
{
@@ -347,6 +357,30 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
sv.divide();
}
if (options & INDEX_MESH)
{
OSG_NOTIFY(osg::INFO)<<"Optimizer::optimize() doing INDEX_MESH"<<std::endl;
IndexMeshVisitor imv(this);
node->accept(imv);
imv.makeMesh();
}
if (options & VERTEX_POSTTRANSFORM)
{
OSG_NOTIFY(osg::INFO)<<"Optimizer::optimize() doing VERTEX_POSTTRANSFORM"<<std::endl;
VertexCacheVisitor vcv;
node->accept(vcv);
vcv.optimizeVertices();
}
if (options & VERTEX_PRETRANSFORM)
{
OSG_NOTIFY(osg::INFO)<<"Optimizer::optimize() doing VERTEX_PRETRANSFORM"<<std::endl;
VertexAccessOrderVisitor vaov;
node->accept(vaov);
vaov.optimizeOrder();
}
if (osg::getNotifyLevel()>=osg::INFO)
{
stats.reset();