329a8a1656
a static transform it would crash when this root was deleted. Have fixed by recognising this node as one not to remove and set it to identity instead.
216 lines
7.3 KiB
C++
216 lines
7.3 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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_OPTIMIZER
|
|
#define OSGUTIL_OPTIMIZER
|
|
|
|
#include <osg/NodeVisitor>
|
|
#include <osg/Matrix>
|
|
#include <osg/Geometry>
|
|
#include <osg/Transform>
|
|
|
|
#include <osgUtil/Export>
|
|
|
|
#include <set>
|
|
|
|
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_REDUNDANT_NODES = 0x2,
|
|
COMBINE_ADJACENT_LODS = 0x4,
|
|
SHARE_DUPLICATE_STATE = 0x8,
|
|
ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
|
|
REMOVE_REDUNDANT_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);
|
|
|
|
|
|
/** ConvertGeoSetsToGeometryVisitor all the old GeoSet Drawables to the new Geometry Drawables.*/
|
|
class OSGUTIL_EXPORT ConvertGeoSetsToGeometryVisitor : public osg::NodeVisitor
|
|
{
|
|
public:
|
|
|
|
ConvertGeoSetsToGeometryVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
|
|
|
virtual void apply(osg::Geode& geode);
|
|
virtual void apply(osg::Node& node) { traverse(node); }
|
|
|
|
};
|
|
|
|
|
|
/** Flatten Static Trasform nodes by applying their transform to the
|
|
* geometry on the leaves of the scene graph, then removing the
|
|
* now redundant transforms.*/
|
|
class OSGUTIL_EXPORT FlattenStaticTransformsVisitor : public osg::NodeVisitor
|
|
{
|
|
public:
|
|
|
|
|
|
|
|
FlattenStaticTransformsVisitor():
|
|
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
|
|
|
virtual void apply(osg::Geode& geode);
|
|
virtual void apply(osg::Billboard& geode);
|
|
virtual void apply(osg::Transform& transform);
|
|
|
|
bool removeTransforms(osg::Node* nodeWeCannotRemove);
|
|
|
|
|
|
protected:
|
|
|
|
typedef std::vector<osg::Transform*> TransformStack;
|
|
typedef std::set<osg::Drawable*> DrawableSet;
|
|
typedef std::set<osg::Billboard*> BillboardSet;
|
|
typedef std::set<osg::Transform*> TransformSet;
|
|
|
|
TransformStack _transformStack;
|
|
DrawableSet _drawableSet;
|
|
BillboardSet _billboardSet;
|
|
TransformSet _transformSet;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
/** Remove rendundant nodes, such as groups with one single child.*/
|
|
class OSGUTIL_EXPORT RemoveEmptyNodesVisitor : public osg::NodeVisitor
|
|
{
|
|
public:
|
|
|
|
|
|
typedef std::set<osg::Node*> NodeList;
|
|
NodeList _redundantNodeList;
|
|
|
|
RemoveEmptyNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
|
|
|
virtual void apply(osg::Geode& geode);
|
|
virtual void apply(osg::Group& group);
|
|
|
|
void removeEmptyNodes();
|
|
|
|
};
|
|
|
|
/** Remove rendundant nodes, such as groups with one single child.*/
|
|
class OSGUTIL_EXPORT RemoveRedundantNodesVisitor : public osg::NodeVisitor
|
|
{
|
|
public:
|
|
|
|
typedef std::set<osg::Node*> NodeList;
|
|
NodeList _redundantNodeList;
|
|
|
|
RemoveRedundantNodesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
|
|
|
virtual void apply(osg::Group& group);
|
|
virtual void apply(osg::Transform& transform);
|
|
|
|
void removeRedundantNodes();
|
|
|
|
};
|
|
|
|
/** 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;
|
|
|
|
};
|
|
|
|
|
|
class OSGUTIL_EXPORT MergeGeometryVisitor : public osg::NodeVisitor
|
|
{
|
|
public:
|
|
|
|
/// default to traversing all children.
|
|
MergeGeometryVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
|
|
|
|
virtual void apply(osg::Geode& geode) { mergeGeode(geode); }
|
|
virtual void apply(osg::Billboard&) { /* don't do anything*/ }
|
|
|
|
static bool mergeGeode(osg::Geode& geode);
|
|
|
|
static bool geometryContainsSharedArrays(osg::Geometry& geom);
|
|
|
|
static bool mergeGeometry(osg::Geometry& lhs,osg::Geometry& rhs);
|
|
|
|
static bool mergePrimitive(osg::DrawArrays& lhs,osg::DrawArrays& rhs);
|
|
static bool mergePrimitive(osg::DrawArrayLengths& lhs,osg::DrawArrayLengths& rhs);
|
|
static bool mergePrimitive(osg::DrawElementsUByte& lhs,osg::DrawElementsUByte& rhs);
|
|
static bool mergePrimitive(osg::DrawElementsUShort& lhs,osg::DrawElementsUShort& rhs);
|
|
static bool mergePrimitive(osg::DrawElementsUInt& lhs,osg::DrawElementsUInt& rhs);
|
|
|
|
};
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|