OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
optimizer.hpp
Go to the documentation of this file.
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 /* Modified for OpenMW */
15 
16 #ifndef OPENMW_OSGUTIL_OPTIMIZER
17 #define OPENMW_OSGUTIL_OPTIMIZER
18 
19 #include <osg/NodeVisitor>
20 #include <osg/Matrix>
21 #include <osg/Geometry>
22 #include <osg/Transform>
23 #include <osg/Texture2D>
24 
25 //#include <osgUtil/Export>
26 
27 #include <set>
28 
29 //namespace osgUtil {
30 namespace SceneUtil {
31 
32 // forward declare
33 class Optimizer;
34 
36 class BaseOptimizerVisitor : public osg::NodeVisitor
37 {
38  public:
39 
40  BaseOptimizerVisitor(Optimizer* optimizer, unsigned int operation):
41  osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
42  _optimizer(optimizer),
43  _operationType(operation)
44  {
45  setNodeMaskOverride(0xffffffff);
46  }
47 
48  inline bool isOperationPermissibleForObject(const osg::StateSet* object) const;
49  inline bool isOperationPermissibleForObject(const osg::StateAttribute* object) const;
50  inline bool isOperationPermissibleForObject(const osg::Drawable* object) const;
51  inline bool isOperationPermissibleForObject(const osg::Node* object) const;
52 
53  protected:
54 
56  unsigned int _operationType;
57 };
58 
63 class Optimizer
64 {
65 
66  public:
67 
68  Optimizer() {}
69  virtual ~Optimizer() {}
70 
72  {
78  MERGE_GEOMETRY = (1 << 5),
79  CHECK_GEOMETRY = (1 << 6), // deprecated, currently no-op
80  MAKE_FAST_GEOMETRY = (1 << 7),
81  SPATIALIZE_GROUPS = (1 << 8),
82  COPY_SHARED_NODES = (1 << 9),
83  TRISTRIP_GEOMETRY = (1 << 10),
84  TESSELLATE_GEOMETRY = (1 << 11),
86  MERGE_GEODES = (1 << 13),
87  FLATTEN_BILLBOARDS = (1 << 14),
88  TEXTURE_ATLAS_BUILDER = (1 << 15),
91  INDEX_MESH = (1 << 18),
92  VERTEX_POSTTRANSFORM = (1 << 19),
93  VERTEX_PRETRANSFORM = (1 << 20),
109  MERGE_GEODES |
119  };
120 
122  void reset();
123 
126  virtual void optimize(osg::Node* node, unsigned int options);
127 
128 
130  struct IsOperationPermissibleForObjectCallback : public osg::Referenced
131  {
132  virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::StateSet* stateset,unsigned int option) const
133  {
134  return optimizer->isOperationPermissibleForObjectImplementation(stateset,option);
135  }
136 
137  virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::StateAttribute* attribute,unsigned int option) const
138  {
139  return optimizer->isOperationPermissibleForObjectImplementation(attribute,option);
140  }
141 
142  virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::Drawable* drawable,unsigned int option) const
143  {
144  return optimizer->isOperationPermissibleForObjectImplementation(drawable,option);
145  }
146 
147  virtual bool isOperationPermissibleForObjectImplementation(const Optimizer* optimizer, const osg::Node* node,unsigned int option) const
148  {
149  return optimizer->isOperationPermissibleForObjectImplementation(node,option);
150  }
151 
152  };
153 
156 
159 
162 
163 
164  inline void setPermissibleOptimizationsForObject(const osg::Object* object, unsigned int options)
165  {
166  _permissibleOptimizationsMap[object] = options;
167  }
168 
169  inline unsigned int getPermissibleOptimizationsForObject(const osg::Object* object) const
170  {
171  PermissibleOptimizationsMap::const_iterator itr = _permissibleOptimizationsMap.find(object);
172  if (itr!=_permissibleOptimizationsMap.end()) return itr->second;
173  else return 0xffffffff;
174  }
175 
176 
177  inline bool isOperationPermissibleForObject(const osg::StateSet* object, unsigned int option) const
178  {
180  return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option);
181  else
182  return isOperationPermissibleForObjectImplementation(object,option);
183  }
184 
185  inline bool isOperationPermissibleForObject(const osg::StateAttribute* object, unsigned int option) const
186  {
188  return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option);
189  else
190  return isOperationPermissibleForObjectImplementation(object,option);
191  }
192 
193  inline bool isOperationPermissibleForObject(const osg::Drawable* object, unsigned int option) const
194  {
196  return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option);
197  else
198  return isOperationPermissibleForObjectImplementation(object,option);
199  }
200 
201  inline bool isOperationPermissibleForObject(const osg::Node* object, unsigned int option) const
202  {
204  return _isOperationPermissibleForObjectCallback->isOperationPermissibleForObjectImplementation(this,object,option);
205  else
206  return isOperationPermissibleForObjectImplementation(object,option);
207  }
208 
209  bool isOperationPermissibleForObjectImplementation(const osg::StateSet* stateset, unsigned int option) const
210  {
211  return (option & getPermissibleOptimizationsForObject(stateset))!=0;
212  }
213 
214  bool isOperationPermissibleForObjectImplementation(const osg::StateAttribute* attribute, unsigned int option) const
215  {
216  return (option & getPermissibleOptimizationsForObject(attribute))!=0;
217  }
218 
219  bool isOperationPermissibleForObjectImplementation(const osg::Drawable* drawable, unsigned int option) const
220  {
221  if (option & (REMOVE_REDUNDANT_NODES|MERGE_GEOMETRY))
222  {
223  if (drawable->getUserData()) return false;
224  if (drawable->getUpdateCallback()) return false;
225  if (drawable->getEventCallback()) return false;
226  if (drawable->getCullCallback()) return false;
227  }
228  return (option & getPermissibleOptimizationsForObject(drawable))!=0;
229  }
230 
231  bool isOperationPermissibleForObjectImplementation(const osg::Node* node, unsigned int option) const
232  {
234  {
235  if (node->getUserData()) return false;
236  if (node->getUpdateCallback()) return false;
237  if (node->getEventCallback()) return false;
238  if (node->getCullCallback()) return false;
239  if (node->getNumDescriptions()>0) return false;
240  if (node->getStateSet()) return false;
241  if (node->getNodeMask()!=0xffffffff) return false;
242  // if (!node->getName().empty()) return false;
243  }
244 
245  return (option & getPermissibleOptimizationsForObject(node))!=0;
246  }
247 
248  protected:
249 
250  osg::ref_ptr<IsOperationPermissibleForObjectCallback> _isOperationPermissibleForObjectCallback;
251 
252  typedef std::map<const osg::Object*,unsigned int> PermissibleOptimizationsMap;
253  PermissibleOptimizationsMap _permissibleOptimizationsMap;
254 
255  public:
256 
264  {
265  public:
266 
269 
270  virtual void apply(osg::Node& geode);
271  virtual void apply(osg::Drawable& drawable);
272  virtual void apply(osg::Billboard& geode);
273  virtual void apply(osg::Transform& transform);
274 
275  bool removeTransforms(osg::Node* nodeWeCannotRemove);
276 
277  protected:
278 
279  typedef std::vector<osg::Transform*> TransformStack;
280  typedef std::set<osg::Drawable*> DrawableSet;
281  typedef std::set<osg::Billboard*> BillboardSet;
282  typedef std::set<osg::Node* > NodeSet;
283  typedef std::set<osg::Transform*> TransformSet;
284 
290  };
291 
292 
295  {
296  public:
297 
300 
301  virtual void apply(osg::MatrixTransform& transform);
302 
303  bool removeTransforms(osg::Node* nodeWeCannotRemove);
304 
305  protected:
306 
307  typedef std::set<osg::MatrixTransform*> TransformSet;
309  };
310 
313  {
314  public:
315 
316 
317  typedef std::set<osg::Node*> NodeList;
319 
322 
323  virtual void apply(osg::Group& group);
324 
325  void removeEmptyNodes();
326 
327  };
328 
331  {
332  public:
333 
334  typedef std::set<osg::Node*> NodeList;
336 
339 
340  virtual void apply(osg::Group& group);
341  virtual void apply(osg::Transform& transform);
342  virtual void apply(osg::LOD& lod);
343 
344  bool isOperationPermissible(osg::Node& node);
345 
346  void removeRedundantNodes();
347 
348  };
349 
352  {
353  public:
356  {
357  }
358 
359  bool isOperationPermissible(osg::Group& node);
360 
361  virtual void apply(osg::Group& group);
362  virtual void apply(osg::LOD& lod);
363  };
364 
366  {
367  public:
368 
373 
375  {
377  }
378 
379  unsigned int getTargetMaximumNumberOfVertices() const
380  {
382  }
383 
384  void pushStateSet(osg::StateSet* stateSet);
385  void popStateSet();
386  void checkAllowedToMerge();
387 
388  virtual void apply(osg::Group& group);
389  virtual void apply(osg::Billboard&) { /* don't do anything*/ }
390 
391  bool mergeGroup(osg::Group& group);
392 
393  static bool geometryContainsSharedArrays(osg::Geometry& geom);
394 
395  static bool mergeGeometry(osg::Geometry& lhs,osg::Geometry& rhs);
396 
397  static bool mergePrimitive(osg::DrawArrays& lhs,osg::DrawArrays& rhs);
398  static bool mergePrimitive(osg::DrawArrayLengths& lhs,osg::DrawArrayLengths& rhs);
399  static bool mergePrimitive(osg::DrawElementsUByte& lhs,osg::DrawElementsUByte& rhs);
400  static bool mergePrimitive(osg::DrawElementsUShort& lhs,osg::DrawElementsUShort& rhs);
401  static bool mergePrimitive(osg::DrawElementsUInt& lhs,osg::DrawElementsUInt& rhs);
402 
403  protected:
404 
406  std::vector<osg::StateSet*> _stateSetStack;
408  };
409 
410 };
411 
412 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::StateSet* object) const
413 {
414  return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true;
415 }
416 
417 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::StateAttribute* object) const
418 {
419  return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true;
420 }
421 
422 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::Drawable* object) const
423 {
424  return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true;
425 }
426 
427 inline bool BaseOptimizerVisitor::isOperationPermissibleForObject(const osg::Node* object) const
428 {
429  return _optimizer ? _optimizer->isOperationPermissibleForObject(object,_operationType) : true;
430 }
431 
432 }
433 
434 #endif
virtual void apply(osg::MatrixTransform &transform)
Definition: optimizer.cpp:672
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::StateSet *stateset, unsigned int option) const
Definition: optimizer.hpp:132
NodeList _redundantNodeList
Definition: optimizer.hpp:318
BillboardSet _billboardSet
Definition: optimizer.hpp:288
static bool geometryContainsSharedArrays(osg::Geometry &geom)
Definition: optimizer.cpp:1532
std::set< osg::Transform * > TransformSet
Definition: optimizer.hpp:283
std::set< osg::Drawable * > DrawableSet
Definition: optimizer.hpp:280
PermissibleOptimizationsMap _permissibleOptimizationsMap
Definition: optimizer.hpp:253
DrawableSet _drawableSet
Definition: optimizer.hpp:287
Definition: optimizer.hpp:351
bool isOperationPermissibleForObject(const osg::Drawable *object, unsigned int option) const
Definition: optimizer.hpp:193
unsigned int _targetMaximumNumberOfVertices
Definition: optimizer.hpp:405
const IsOperationPermissibleForObjectCallback * getIsOperationPermissibleForObjectCallback() const
Definition: optimizer.hpp:161
NodeSet _excludedNodeSet
Definition: optimizer.hpp:286
Definition: optimizer.hpp:36
void reset()
Definition: optimizer.cpp:48
Definition: optimizer.hpp:104
OptimizationOptions
Definition: optimizer.hpp:71
void num(char i, bool last)
Definition: gen_iconv.cpp:12
void popStateSet()
Definition: optimizer.cpp:1053
bool isOperationPermissibleForObjectImplementation(const osg::Drawable *drawable, unsigned int option) const
Definition: optimizer.hpp:219
bool isOperationPermissibleForObject(const osg::Node *object, unsigned int option) const
Definition: optimizer.hpp:201
Definition: optimizer.hpp:81
RemoveEmptyNodesVisitor(Optimizer *optimizer=0)
Definition: optimizer.hpp:320
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::Node *node, unsigned int option) const
Definition: optimizer.hpp:147
Definition: optimizer.hpp:82
void removeEmptyNodes()
Definition: optimizer.cpp:755
Definition: optimizer.hpp:79
Definition: optimizer.hpp:87
std::map< const osg::Object *, unsigned int > PermissibleOptimizationsMap
Definition: optimizer.hpp:252
virtual void apply(osg::Group &group)
Definition: optimizer.cpp:1865
Definition: optimizer.hpp:92
Definition: optimizer.hpp:80
Definition: optimizer.hpp:365
static bool mergePrimitive(osg::DrawArrays &lhs, osg::DrawArrays &rhs)
Definition: optimizer.cpp:1808
Definition: optimizer.hpp:83
static bool mergeGeometry(osg::Geometry &lhs, osg::Geometry &rhs)
Definition: optimizer.cpp:1633
unsigned int _operationType
Definition: optimizer.hpp:56
virtual void apply(osg::Group &group)
Definition: optimizer.cpp:1078
std::set< osg::Node * > NodeList
Definition: optimizer.hpp:334
bool isOperationPermissibleForObjectImplementation(const osg::StateAttribute *attribute, unsigned int option) const
Definition: optimizer.hpp:214
virtual ~Optimizer()
Definition: optimizer.hpp:69
bool isOperationPermissibleForObjectImplementation(const osg::StateSet *stateset, unsigned int option) const
Definition: optimizer.hpp:209
std::set< osg::Node * > NodeList
Definition: optimizer.hpp:317
Optimizer * _optimizer
Definition: optimizer.hpp:55
MergeGeometryVisitor(Optimizer *optimizer=0)
default to traversing all children.
Definition: optimizer.hpp:370
Definition: optimizer.hpp:63
bool isOperationPermissible(osg::Node &node)
Definition: optimizer.cpp:793
std::vector< osg::Transform * > TransformStack
Definition: optimizer.hpp:279
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::StateAttribute *attribute, unsigned int option) const
Definition: optimizer.hpp:137
void removeRedundantNodes()
Definition: optimizer.cpp:839
Definition: optimizer.hpp:86
TransformStack _transformStack
Definition: optimizer.hpp:285
virtual void apply(osg::Node &geode)
Definition: optimizer.cpp:585
Optimizer()
Definition: optimizer.hpp:68
std::set< osg::Node * > NodeSet
Definition: optimizer.hpp:282
virtual void apply(osg::Billboard &)
Definition: optimizer.hpp:389
std::set< osg::MatrixTransform * > TransformSet
Definition: optimizer.hpp:307
void setTargetMaximumNumberOfVertices(unsigned int num)
Definition: optimizer.hpp:374
bool removeTransforms(osg::Node *nodeWeCannotRemove)
Definition: optimizer.cpp:630
void setIsOperationPermissibleForObjectCallback(IsOperationPermissibleForObjectCallback *callback)
Definition: optimizer.hpp:155
std::vector< osg::StateSet * > _stateSetStack
Definition: optimizer.hpp:406
bool removeTransforms(osg::Node *nodeWeCannotRemove)
Definition: optimizer.cpp:687
BaseOptimizerVisitor(Optimizer *optimizer, unsigned int operation)
Definition: optimizer.hpp:40
bool isOperationPermissibleForObjectImplementation(const osg::Node *node, unsigned int option) const
Definition: optimizer.hpp:231
CombineStaticTransformsVisitor(Optimizer *optimizer=0)
Definition: optimizer.hpp:298
void pushStateSet(osg::StateSet *stateSet)
Definition: optimizer.cpp:1047
NodeList _redundantNodeList
Definition: optimizer.hpp:335
bool isOperationPermissibleForObject(const osg::StateSet *object, unsigned int option) const
Definition: optimizer.hpp:177
TransformSet _transformSet
Definition: optimizer.hpp:308
unsigned int getTargetMaximumNumberOfVertices() const
Definition: optimizer.hpp:379
bool _allowedToMerge
Definition: optimizer.hpp:407
virtual void apply(osg::Group &group)
Definition: optimizer.cpp:740
bool mergeGroup(osg::Group &group)
Definition: optimizer.cpp:1092
bool isOperationPermissible(osg::Group &node)
Definition: optimizer.cpp:1850
TransformSet _transformSet
Definition: optimizer.hpp:289
Definition: optimizer.hpp:93
unsigned int getPermissibleOptimizationsForObject(const osg::Object *object) const
Definition: optimizer.hpp:169
osg::ref_ptr< IsOperationPermissibleForObjectCallback > _isOperationPermissibleForObjectCallback
Definition: optimizer.hpp:250
virtual void apply(osg::Group &group)
Definition: optimizer.cpp:810
virtual bool isOperationPermissibleForObjectImplementation(const Optimizer *optimizer, const osg::Drawable *drawable, unsigned int option) const
Definition: optimizer.hpp:142
void checkAllowedToMerge()
Definition: optimizer.cpp:1059
FlattenStaticTransformsVisitor(Optimizer *optimizer=0)
Definition: optimizer.hpp:267
Definition: optimizer.hpp:78
bool isOperationPermissibleForObject(const osg::StateSet *object) const
Definition: optimizer.hpp:412
virtual void optimize(osg::Node *node, unsigned int options)
Definition: optimizer.cpp:52
MergeGroupsVisitor(SceneUtil::Optimizer *optimizer)
Definition: optimizer.hpp:354
Definition: optimizer.hpp:84
IsOperationPermissibleForObjectCallback * getIsOperationPermissibleForObjectCallback()
Definition: optimizer.hpp:158
bool isOperationPermissibleForObject(const osg::StateAttribute *object, unsigned int option) const
Definition: optimizer.hpp:185
void setPermissibleOptimizationsForObject(const osg::Object *object, unsigned int options)
Definition: optimizer.hpp:164
std::set< osg::Billboard * > BillboardSet
Definition: optimizer.hpp:281
Definition: optimizer.hpp:91
RemoveRedundantNodesVisitor(Optimizer *optimizer=0)
Definition: optimizer.hpp:337