Files
OpenSceneGraph/include/osgUtil/Optimizer
Robert Osfield f16776da22 Fixed FlattenStaticTransformVisitor bug which related to incorrect handling
of objects which were transformed by multiple matrices at one time - this
cannot be handled in the flattening process (since we only have one piece
of geometry to transform).  This visitor now handles this case by disabling
flattening of any objects and transforms associated in this way.
2002-01-22 19:30:51 +00:00

202 lines
6.7 KiB
Plaintext

//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSGUTIL_OPTIMIZER
#define OSGUTIL_OPTIMIZER
#include <osg/NodeVisitor>
#include <osg/Matrix>
#include <osgUtil/Export>
namespace osgUtil {
/** Insert impostor nodes into scene graph.
* For example of usage see src/Demos/osgimpostor.
*/
class OSGUTIL_EXPORT Optimizer
{
public:
Optimizer() {}
enum OptimizationOptions
{
FLATTEN_STATIC_TRANSFORMS = 0x1,
REMOVE_REDUNDENT_NODES = 0x2,
COMBINE_ADJACENT_LODS = 0x4,
SHARE_DUPLICATE_STATE = 0x8,
ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
REMOVE_REDUNDENT_NODES |
COMBINE_ADJACENT_LODS |
SHARE_DUPLICATE_STATE
};
/** traverse the node and its subgraph with a series of optimization
* visitors, specificied by the OptizationOptions.*/
virtual void optimize(osg::Node* node, unsigned int options = ALL_OPTIMIZATIONS);
/** Flatten Static Trasform nodes by applying their transform to the
* geometry on the leaves of the scene graph, then removing the
* now redundent transforms.*/
class OSGUTIL_EXPORT FlattenStaticTransformsVisitor : public osg::NodeVisitor
{
public:
FlattenStaticTransformsVisitor(bool ignoreDynamicTransforms=true):
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_ignoreDynamicTransforms(ignoreDynamicTransforms) {}
virtual void apply(osg::Geode& geode);
virtual void apply(osg::Billboard& billboard);
virtual void apply(osg::LOD& lod);
virtual void apply(osg::Transform& transform);
void removeTransforms();
protected:
typedef std::vector<osg::Transform*> TransformStack;
typedef std::vector<osg::Matrix> MatrixStack;
struct TransformStruct
{
typedef std::set<osg::Object*> ObjectSet;
TransformStruct():_canBeApplied(true) {}
void add(osg::Object* obj) { _objectSet.insert(obj); }
bool _canBeApplied;
ObjectSet _objectSet;
};
struct ObjectStruct
{
typedef std::set<osg::Transform*> TransformSet;
ObjectStruct():_canBeApplied(true),_matrixSet(false),_moreThanOneMatrixRequired(false) {}
void add(TransformStack& transforms,osg::Matrix& matrix)
{
_transformSet.insert(transforms.begin(),transforms.end());
if (!_matrixSet)
{
_matrixSet = true;
_moreThanOneMatrixRequired = false;
_matrix = matrix;
}
else if (_matrix!=matrix)
{
_moreThanOneMatrixRequired = true;
}
}
bool _canBeApplied;
bool _matrixSet;
bool _moreThanOneMatrixRequired;
osg::Matrix _matrix;
TransformSet _transformSet;
};
typedef std::map<osg::Transform*,TransformStruct> TransformMap;
typedef std::map<osg::Object*,ObjectStruct> ObjectMap;
void disableObject(osg::Object* object)
{
disableObject(_objectMap.find(object));
}
void disableObject(ObjectMap::iterator itr);
void disableTransform(osg::Transform* transform);
void doTransform(osg::Object* obj,osg::Matrix& matrix);
bool _ignoreDynamicTransforms;
MatrixStack _matrixStack;
TransformStack _transformStack;
TransformMap _transformMap;
ObjectMap _objectMap;
};
/** Remove rendundent nodes, such as groups with one single child.*/
class OSGUTIL_EXPORT RemoveRedundentNodesVisitor : public osg::NodeVisitor
{
public:
typedef std::set<osg::Node*> NodeList;
NodeList _redundentNodeList;
RemoveRedundentNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Group& group);
void removeRedundentNodes();
};
/** Optimize the LOD groups, by combining adjacent LOD's which have
* complementary ranges.*/
class OSGUTIL_EXPORT CombineLODsVisitor : public osg::NodeVisitor
{
public:
typedef std::set<osg::Group*> GroupList;
GroupList _groupList;
CombineLODsVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::LOD& lod);
void combineLODs();
};
/** Optimize State in the scene graph by removing duplicate state,
* replacing it with shared instances, both for StateAttributes,
* and whole StateSets.*/
class OSGUTIL_EXPORT StateVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
StateVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
/** empty visitor, make it ready for next traversal.*/
virtual void reset();
virtual void apply(osg::Node& node);
virtual void apply(osg::Geode& geode);
void optimize();
protected:
void addStateSet(osg::StateSet* stateset,osg::Object* obj);
typedef std::set<osg::Object*> ObjectSet;
typedef std::map<osg::StateSet*,ObjectSet> StateSetMap;
StateSetMap _statesets;
};
};
};
#endif