123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSGUTIL_MESHOPTIMIZERS
- #define OSGUTIL_MESHOPTIMIZERS 1
- #include <set>
- #include <vector>
- #include <osg/Geode>
- #include <osg/Geometry>
- #include <osg/NodeVisitor>
- #include <osgUtil/Optimizer>
- namespace osgUtil
- {
- // Helper that collects all the unique Geometry objects in a subgraph.
- class OSGUTIL_EXPORT GeometryCollector : public BaseOptimizerVisitor
- {
- public:
- GeometryCollector(Optimizer* optimizer,
- Optimizer::OptimizationOptions options)
- : BaseOptimizerVisitor(optimizer, options) {}
- void reset();
- void apply(osg::Geometry& geom);
- typedef std::set<osg::Geometry*> GeometryList;
- GeometryList& getGeometryList() { return _geometryList; };
- protected:
- GeometryList _geometryList;
- };
- // Convert geometry that uses DrawArrays to DrawElements i.e.,
- // construct a real mesh. This removes duplicate vertices.
- class OSGUTIL_EXPORT IndexMeshVisitor : public GeometryCollector
- {
- public:
- IndexMeshVisitor(Optimizer* optimizer = 0)
- : GeometryCollector(optimizer, Optimizer::INDEX_MESH), _generateNewIndicesOnAllGeometries(false)
- {
- }
- inline void setGenerateNewIndicesOnAllGeometries(bool b) { _generateNewIndicesOnAllGeometries = b; }
- inline bool getGenerateNewIndicesOnAllGeometries() const { return _generateNewIndicesOnAllGeometries; }
- void makeMesh(osg::Geometry& geom);
- void makeMesh();
- protected:
- bool _generateNewIndicesOnAllGeometries;
- };
- // Optimize the triangle order in a mesh for best use of the GPU's
- // post-transform cache. This uses Tom Forsyth's algorithm described
- // at http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html
- class OSGUTIL_EXPORT VertexCacheVisitor : public GeometryCollector
- {
- public:
- VertexCacheVisitor(Optimizer* optimizer = 0)
- : GeometryCollector(optimizer, Optimizer::VERTEX_POSTTRANSFORM)
- {
- }
- void optimizeVertices(osg::Geometry& geom);
- void optimizeVertices();
- private:
- void doVertexOptimization(osg::Geometry& geom,
- std::vector<unsigned>& vertDrawList);
- };
- // Gather statistics on post-transform cache misses for geometry
- class OSGUTIL_EXPORT VertexCacheMissVisitor : public osg::NodeVisitor
- {
- public:
- VertexCacheMissVisitor(unsigned cacheSize = 16);
- void reset();
- virtual void apply(osg::Geometry& geom);
- void doGeometry(osg::Geometry& geom);
- unsigned misses;
- unsigned triangles;
- protected:
- const unsigned _cacheSize;
- };
- // Optimize the use of the GPU pre-transform cache by arranging vertex
- // attributes in the order they are used.
- class OSGUTIL_EXPORT VertexAccessOrderVisitor : public GeometryCollector
- {
- struct OrderByPrimitiveMode
- {
- inline bool operator() (const osg::ref_ptr<osg::PrimitiveSet>& prim1, const osg::ref_ptr<osg::PrimitiveSet>& prim2)
- {
- if(prim1 && prim2) {
- return prim1->getMode() > prim2->getMode();
- }
- else if(prim1) {
- return true;
- }
- return false;
- }
- } order_by_primitive_mode;
- public:
- VertexAccessOrderVisitor(Optimizer* optimizer = 0)
- : GeometryCollector(optimizer, Optimizer::VERTEX_PRETRANSFORM)
- {
- }
- void optimizeOrder();
- void optimizeOrder(osg::Geometry& geom);
- };
- class OSGUTIL_EXPORT SharedArrayOptimizer
- {
- public:
- void findDuplicatedUVs(const osg::Geometry& geometry);
- void deduplicateUVs(osg::Geometry& geometry);
- protected:
- std::map<unsigned int, unsigned int> _deduplicateUvs;
- }; // SharedArrayOptimizer
- inline void optimizeMesh(osg::Node* node)
- {
- IndexMeshVisitor imv;
- node->accept(imv);
- imv.makeMesh();
- VertexCacheVisitor vcv;
- node->accept(vcv);
- vcv.optimizeVertices();
- VertexAccessOrderVisitor vaov;
- node->accept(vaov);
- vaov.optimizeOrder();
- }
- }
- #endif
|