1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12*/ 13 14#ifndef OSGUTIL_MESHOPTIMIZERS 15#define OSGUTIL_MESHOPTIMIZERS 1 16 17#include <set> 18#include <vector> 19 20#include <osg/Geode> 21#include <osg/Geometry> 22#include <osg/NodeVisitor> 23 24#include <osgUtil/Optimizer> 25 26namespace osgUtil 27{ 28// Helper that collects all the unique Geometry objects in a subgraph. 29class OSGUTIL_EXPORT GeometryCollector : public BaseOptimizerVisitor 30{ 31public: 32 GeometryCollector(Optimizer* optimizer, 33 Optimizer::OptimizationOptions options) 34 : BaseOptimizerVisitor(optimizer, options) {} 35 void reset(); 36 void apply(osg::Geode& geode); 37 typedef std::set<osg::Geometry*> GeometryList; 38 GeometryList& getGeometryList() { return _geometryList; }; 39protected: 40 GeometryList _geometryList; 41}; 42 43// Convert geometry that uses DrawArrays to DrawElements i.e., 44// construct a real mesh. This removes duplicate vertices. 45class OSGUTIL_EXPORT IndexMeshVisitor : public GeometryCollector 46{ 47public: 48 IndexMeshVisitor(Optimizer* optimizer = 0) 49 : GeometryCollector(optimizer, Optimizer::INDEX_MESH) 50 { 51 } 52 void makeMesh(osg::Geometry& geom); 53 void makeMesh(); 54}; 55 56// Optimize the triangle order in a mesh for best use of the GPU's 57// post-transform cache. This uses Tom Forsyth's algorithm described 58// at http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html 59class OSGUTIL_EXPORT VertexCacheVisitor : public GeometryCollector 60{ 61public: 62 VertexCacheVisitor(Optimizer* optimizer = 0) 63 : GeometryCollector(optimizer, Optimizer::VERTEX_POSTTRANSFORM) 64 { 65 } 66 67 void optimizeVertices(osg::Geometry& geom); 68 void optimizeVertices(); 69private: 70 void doVertexOptimization(osg::Geometry& geom, 71 std::vector<unsigned>& vertDrawList); 72}; 73 74// Gather statistics on post-transform cache misses for geometry 75class OSGUTIL_EXPORT VertexCacheMissVisitor : public osg::NodeVisitor 76{ 77public: 78 VertexCacheMissVisitor(unsigned cacheSize = 16); 79 void reset(); 80 virtual void apply(osg::Geode& geode); 81 void doGeometry(osg::Geometry& geom); 82 unsigned misses; 83 unsigned triangles; 84protected: 85 const unsigned _cacheSize; 86}; 87 88// Optimize the use of the GPU pre-transform cache by arranging vertex 89// attributes in the order they are used. 90class OSGUTIL_EXPORT VertexAccessOrderVisitor : public GeometryCollector 91{ 92 struct OrderByPrimitiveMode 93 { 94 inline bool operator() (const osg::ref_ptr<osg::PrimitiveSet>& prim1, const osg::ref_ptr<osg::PrimitiveSet>& prim2) 95 { 96 if(prim1 && prim2) { 97 return prim1->getMode() > prim2->getMode(); 98 } 99 else if(prim1) { 100 return true; 101 } 102 return false; 103 } 104 } order_by_primitive_mode; 105 106public: 107 VertexAccessOrderVisitor(Optimizer* optimizer = 0) 108 : GeometryCollector(optimizer, Optimizer::VERTEX_PRETRANSFORM) 109 { 110 } 111 void optimizeOrder(); 112 void optimizeOrder(osg::Geometry& geom); 113}; 114 115class OSGUTIL_EXPORT SharedArrayOptimizer 116{ 117public: 118 void findDuplicatedUVs(const osg::Geometry& geometry); 119 void deduplicateUVs(osg::Geometry& geometry); 120protected: 121 std::map<unsigned int, unsigned int> _deduplicateUvs; 122}; // SharedArrayOptimizer 123 124} 125#endif 126