14 #ifndef OSGUTIL_OPTIMIZER
15 #define OSGUTIL_OPTIMIZER
17 #include <osg/NodeVisitor>
19 #include <osg/Geometry>
20 #include <osg/Transform>
21 #include <osg/Texture2D>
23 #include <osgUtil/Export>
38 osg::NodeVisitor(
osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
39 _optimizer(optimizer),
40 _operationType(operation)
42 setNodeMaskOverride(0xffffffff);
45 inline bool isOperationPermissibleForObject(
const osg::StateSet*
object)
const;
47 inline bool isOperationPermissibleForObject(
const osg::Drawable*
object)
const;
48 inline bool isOperationPermissibleForObject(
const osg::Node*
object)
const;
70 FLATTEN_STATIC_TRANSFORMS = (1 << 0),
71 REMOVE_REDUNDANT_NODES = (1 << 1),
72 REMOVE_LOADED_PROXY_NODES = (1 << 2),
73 COMBINE_ADJACENT_LODS = (1 << 3),
74 SHARE_DUPLICATE_STATE = (1 << 4),
75 MERGE_GEOMETRY = (1 << 5),
76 CHECK_GEOMETRY = (1 << 6),
77 MAKE_FAST_GEOMETRY = (1 << 7),
78 SPATIALIZE_GROUPS = (1 << 8),
79 COPY_SHARED_NODES = (1 << 9),
80 TRISTRIP_GEOMETRY = (1 << 10),
81 TESSELLATE_GEOMETRY = (1 << 11),
82 OPTIMIZE_TEXTURE_SETTINGS = (1 << 12),
83 MERGE_GEODES = (1 << 13),
84 FLATTEN_BILLBOARDS = (1 << 14),
85 TEXTURE_ATLAS_BUILDER = (1 << 15),
86 STATIC_OBJECT_DETECTION = (1 << 16),
87 FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 17),
88 INDEX_MESH = (1 << 18),
89 VERTEX_POSTTRANSFORM = (1 << 19),
90 VERTEX_PRETRANSFORM = (1 << 20),
91 DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
92 REMOVE_REDUNDANT_NODES |
93 REMOVE_LOADED_PROXY_NODES |
94 COMBINE_ADJACENT_LODS |
95 SHARE_DUPLICATE_STATE |
99 OPTIMIZE_TEXTURE_SETTINGS |
100 STATIC_OBJECT_DETECTION,
101 ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS |
102 REMOVE_REDUNDANT_NODES |
103 REMOVE_LOADED_PROXY_NODES |
104 COMBINE_ADJACENT_LODS |
105 SHARE_DUPLICATE_STATE |
113 OPTIMIZE_TEXTURE_SETTINGS |
114 TEXTURE_ATLAS_BUILDER |
115 STATIC_OBJECT_DETECTION
127 virtual void optimize(
osg::Node* node,
unsigned int options);
167 _permissibleOptimizationsMap[object] = options;
172 PermissibleOptimizationsMap::const_iterator itr = _permissibleOptimizationsMap.find(
object);
173 if (itr!=_permissibleOptimizationsMap.end())
return itr->second;
174 else return 0xffffffff;
180 if (_isOperationPermissibleForObjectCallback.valid())
181 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(
this,
object,option);
183 return isOperationPermissibleForObjectImplementation(
object,option);
188 if (_isOperationPermissibleForObjectCallback.valid())
189 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(
this,
object,option);
191 return isOperationPermissibleForObjectImplementation(
object,option);
196 if (_isOperationPermissibleForObjectCallback.valid())
197 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(
this,
object,option);
199 return isOperationPermissibleForObjectImplementation(
object,option);
204 if (_isOperationPermissibleForObjectCallback.valid())
205 return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(
this,
object,option);
207 return isOperationPermissibleForObjectImplementation(
object,option);
212 return (option & getPermissibleOptimizationsForObject(stateset))!=0;
217 return (option & getPermissibleOptimizationsForObject(attribute))!=0;
222 if (option & (REMOVE_REDUNDANT_NODES|MERGE_GEOMETRY))
229 return (option & getPermissibleOptimizationsForObject(drawable))!=0;
234 if (option & (REMOVE_REDUNDANT_NODES|COMBINE_ADJACENT_LODS|FLATTEN_STATIC_TRANSFORMS))
246 return (option & getPermissibleOptimizationsForObject(node))!=0;
278 bool removeTransforms(
osg::Node* nodeWeCannotRemove);
309 virtual void reset();
337 bool removeTransforms(
osg::Node* nodeWeCannotRemove);
360 void removeEmptyNodes();
378 bool isOperationPermissible(
osg::Node& node);
380 void removeRedundantNodes();
397 void removeRedundantNodes();
443 bool combineStaticState,
444 bool combineUnspecifiedState,
454 virtual void reset();
468 return _optimize[variance];
536 _targetMaximumNumberOfVertices(10000) {}
540 _targetMaximumNumberOfVertices = num;
545 return _targetMaximumNumberOfVertices;
553 static bool geometryContainsSharedArrays(
osg::Geometry& geom);
580 bool divide(
unsigned int maxNumTreesPerCell=8);
582 bool divide(
osg::Group* group,
unsigned int maxNumTreesPerCell);
583 bool divide(
osg::Geode* geode,
unsigned int maxNumTreesPerCell);
602 void copySharedNodes();
616 bool changeClientImageStorage,
bool valueClientImageStorage,
617 bool changeAnisotropy,
float valueAnisotropy,
620 _changeAutoUnRef(changeAutoUnRef), _valueAutoUnRef(valueAutoUnRef),
621 _changeClientImageStorage(changeClientImageStorage), _valueClientImageStorage(valueClientImageStorage),
622 _changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy) {}
647 virtual void reset();
671 void setMargin(
int margin);
708 _x(0),_y(0),_atlas(0) {}
711 _x(0),_y(0),_atlas(0),_image(image) {}
714 _x(0),_y(0),_atlas(0),_texture(texture) {
if (texture) _image = texture->
getImage(); }
723 bool suitableForAtlas(
int maximumAtlasWidth,
int maximumAtlasHeight,
int margin);
737 Atlas(
int width,
int height,
int margin):
738 _maximumAtlasWidth(width),
739 _maximumAtlasHeight(height),
745 _indexFirstOfRow(0){}
767 FitsIn doesSourceFit(
Source* source);
768 bool addSource(
Source* source);
769 void clampToNearestPowerOfTwoSize();
788 return src1->_image->t() > src2->_image->t();
791 void completeRow(
unsigned int indexAtlas);
810 virtual void reset();
861 return _optimizer ? _optimizer->isOperationPermissibleForObject(
object,_operationType) :
true;
866 return _optimizer ? _optimizer->isOperationPermissibleForObject(
object,_operationType) :
true;
871 return _optimizer ? _optimizer->isOperationPermissibleForObject(
object,_operationType) :
true;
876 return _optimizer ? _optimizer->isOperationPermissibleForObject(
object,_operationType) :
true;
std::set< osg::Node * > NodeSet
bool isOperationPermissibleForObjectImplementation(const osg::Node *node, unsigned int option) const
bool isOperationPermissibleForObject(const osg::Node *object, unsigned int option) const
Atlas(int width, int height, int margin)
Callback * getUpdateCallback()
bool isOperationPermissibleForObject(const osg::StateSet *object, unsigned int option) const
bool isOperationPermissibleForObjectImplementation(const osg::StateSet *stateset, unsigned int option) const
MergeGeodesVisitor(Optimizer *optimizer=0)
default to traversing all children.
const osg::Image * getSourceImage(unsigned int i)
int getMaximumAtlasHeight() const
StateSetStack _statesetStack
unsigned int getNumDescriptions() const
Callback * getEventCallback()
MergeGeometryVisitor(Optimizer *optimizer=0)
default to traversing all children.
const osg::Texture2D * getSourceTexture(unsigned int i)
osg::ref_ptr< osg::Image > _image
SpatializeGroupsVisitor(Optimizer *optimizer=0)
BaseOptimizerVisitor(Optimizer *optimizer, unsigned int operation)
NodeMask getNodeMask() const
osg::ref_ptr< osg::Texture2D > _texture
NodeList _redundantNodeList
bool _valueClientImageStorage
RemoveEmptyNodesVisitor(Optimizer *optimizer=0)
unsigned int _operationType
bool isOperationPermissibleForObjectImplementation(const osg::StateAttribute *attribute, unsigned int option) const
std::set< osg::Texture2D * > Textures
virtual void apply(osg::Geode &geode)
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::Drawable *drawable, unsigned int option) const
Callback * getCullCallback()
void setIsOperationPermissibleForObjectCallback(IsOperationPermissibleForObjectCallback *callback)
osg::ref_ptr< IsOperationPermissibleForObjectCallback > _isOperationPermissibleForObjectCallback
std::vector< osg::StateSet * > StateSetStack
std::vector< osg::NodePath > NodePathList
std::vector< osg::ref_ptr< Source > > SourceList
unsigned int getTargetMaximumNumberOfVertices() const
CheckGeometryVisitor(Optimizer *optimizer=0)
default to traversing all children.
Source(const osg::Image *image)
void setTargetMaximumNumberOfVertices(unsigned int num)
std::set< osg::Geode * > GeodesToDivideList
std::map< osg::Billboard *, NodePathList > BillboardNodePathMap
std::vector< osg::ref_ptr< Atlas > > AtlasList
StaticObjectDetectionVisitor(Optimizer *optimizer=0)
default to traversing all children.
std::set< osg::Node * > NodeList
bool isOperationPermissibleForObjectImplementation(const osg::Drawable *drawable, unsigned int option) const
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::Node *node, unsigned int option) const
TextureAtlasVisitor(Optimizer *optimizer=0)
default to traversing all children.
GLint GLenum GLsizei width
CopySharedSubgraphsVisitor(Optimizer *optimizer=0)
BillboardNodePathMap _billboards
GeodesToDivideList _geodesToDivideList
virtual void apply(osg::Geode &geode)
int getMaximumAtlasWidth() const
std::map< osg::StateSet *, NodeSet > StateSetMap
SharedNodeList _sharedNodeList
std::set< osg::Group * > GroupList
StateVisitor(bool combineDynamicState, bool combineStaticState, bool combineUnspecifiedState, Optimizer *optimizer=0)
default to traversing all children.
bool optimize(osg::Object::DataVariance variance)
bool isOperationPermissibleForObject(const osg::StateSet *object) const
unsigned int _targetMaximumNumberOfVertices
unsigned int getNumSources() const
CombineLODsVisitor(Optimizer *optimizer=0)
virtual void apply(osg::Billboard &)
virtual void apply(osg::Geode &geode)
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::StateSet *stateset, unsigned int option) const
MakeFastGeometryVisitor(Optimizer *optimizer=0)
default to traversing all children.
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::StateAttribute *attribute, unsigned int option) const
RemoveLoadedProxyNodesVisitor(Optimizer *optimizer=0)
GLint GLenum GLsizei GLsizei height
unsigned int _indexFirstOfRow
Contain the index of the first element of the last row.
RemoveRedundantNodesVisitor(Optimizer *optimizer=0)
std::set< osg::Group * > GroupList
TextureAtlasBuilder & getTextureAtlasBuilder()
PermissibleOptimizationsMap _permissibleOptimizationsMap
TextureVisitor(bool changeAutoUnRef, bool valueAutoUnRef, bool changeClientImageStorage, bool valueClientImageStorage, bool changeAnisotropy, float valueAnisotropy, Optimizer *optimizer=0)
std::set< osg::Node * > NodeList
GroupsToDivideList _groupsToDivideList
NodeList _redundantNodeList
std::map< osg::StateSet *, Drawables > StateSetMap
IsOperationPermissibleForObjectCallback * getIsOperationPermissibleForObjectCallback()
TextureAtlasBuilder _builder
std::set< osg::Group * > GroupsToDivideList
unsigned int getPermissibleOptimizationsForObject(const osg::Object *object) const
Source(const osg::Texture2D *texture)
osg::ref_ptr< const osg::Texture2D > _texture
bool isOperationPermissibleForObject(const osg::Drawable *object, unsigned int option) const
std::map< const osg::Object *, unsigned int > PermissibleOptimizationsMap
std::set< osg::Node * > SharedNodeList
FlattenBillboardVisitor(Optimizer *optimizer=0)
std::set< osg::Node * > NodeList
osg::ref_ptr< const osg::Image > _image
const IsOperationPermissibleForObjectCallback * getIsOperationPermissibleForObjectCallback() const
NodeList _redundantNodeList
TessellateVisitor(Optimizer *optimizer=0)
virtual Referenced * getUserData()
bool isOperationPermissibleForObject(const osg::StateAttribute *object, unsigned int option) const
osg::StateSet * getStateSet()
void setPermissibleOptimizationsForObject(const osg::Object *object, unsigned int options)
std::set< osg::Drawable * > Drawables
Shader generator framework.