Added RemoveLoadedProxyNodes pass to Optimizer, set on by default at present.
This commit is contained in:
parent
81f60233a9
commit
adba6fa559
@ -20,24 +20,25 @@
|
||||
|
||||
namespace osg {
|
||||
|
||||
class Geode;
|
||||
class Billboard;
|
||||
class LightSource;
|
||||
class ClearNode;
|
||||
class ClipNode;
|
||||
class TexGenNode;
|
||||
class CoordinateSystemNode;
|
||||
class Geode;
|
||||
class Group;
|
||||
class Transform;
|
||||
class Impostor;
|
||||
class LightSource;
|
||||
class LOD;
|
||||
class MatrixTransform;
|
||||
class OccluderNode;
|
||||
class PagedLOD;
|
||||
class PositionAttitudeTransform;
|
||||
class Projection;
|
||||
class LOD;
|
||||
class PagedLOD;
|
||||
class Switch;
|
||||
class Impostor;
|
||||
class ClearNode;
|
||||
class OccluderNode;
|
||||
class ProxyNode;
|
||||
class Sequence;
|
||||
class CoordinateSystemNode;
|
||||
class Switch;
|
||||
class TexGenNode;
|
||||
class Transform;
|
||||
|
||||
/** Visitor for type safe operations on osg::Nodes.
|
||||
Based on GOF's Visitor pattern. The NodeVisitor
|
||||
@ -222,6 +223,8 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced
|
||||
|
||||
virtual void apply(Group& node) { apply((Node&)node); }
|
||||
|
||||
virtual void apply(ProxyNode& node) { apply((Group&)node); }
|
||||
|
||||
virtual void apply(Projection& node) { apply((Group&)node); }
|
||||
|
||||
virtual void apply(CoordinateSystemNode& node) { apply((Group&)node); }
|
||||
|
@ -61,19 +61,19 @@ class OSG_EXPORT ProxyNode : public Group
|
||||
/** Get how the center of object should be determined when computed which child is active.*/
|
||||
CenterMode getCenterMode() const { return _centerMode; }
|
||||
|
||||
/** Sets the object-space point which defines the center of the osg::LOD.
|
||||
center is affected by any transforms in the hierarchy above the osg::LOD.*/
|
||||
/** Sets the object-space point which defines the center of the osg::ProxyNode.
|
||||
center is affected by any transforms in the hierarchy above the osg::ProxyNode.*/
|
||||
inline void setCenter(const Vec3& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; }
|
||||
|
||||
/** return the LOD center point. */
|
||||
/** return the ProxyNode center point. */
|
||||
inline const Vec3& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); }
|
||||
|
||||
|
||||
/** Set the object-space reference radius of the volume enclosed by the LOD.
|
||||
* Used to detmine the bounding sphere of the LOD in the absense of any children.*/
|
||||
/** Set the object-space reference radius of the volume enclosed by the ProxyNode.
|
||||
* Used to detmine the bounding sphere of the ProxyNode in the absense of any children.*/
|
||||
inline void setRadius(float radius) { _radius = radius; }
|
||||
|
||||
/** Get the object-space radius of the volume enclosed by the LOD.*/
|
||||
/** Get the object-space radius of the volume enclosed by the ProxyNode.*/
|
||||
inline float getRadius() const { return _radius; }
|
||||
|
||||
protected :
|
||||
|
@ -41,17 +41,19 @@ class OSGUTIL_EXPORT Optimizer
|
||||
{
|
||||
FLATTEN_STATIC_TRANSFORMS = 0x001,
|
||||
REMOVE_REDUNDANT_NODES = 0x002,
|
||||
COMBINE_ADJACENT_LODS = 0x004,
|
||||
SHARE_DUPLICATE_STATE = 0x008,
|
||||
MERGE_GEOMETRY = 0x010,
|
||||
CHECK_GEOMETRY = 0x020,
|
||||
SPATIALIZE_GROUPS = 0x040,
|
||||
COPY_SHARED_NODES = 0x080,
|
||||
TRISTRIP_GEOMETRY = 0x100,
|
||||
TESSELATE_GEOMETRY = 0x200,
|
||||
OPTIMIZE_TEXTURE_SETTINGS = 0x400,
|
||||
REMOVE_LOADED_PROXY_NODES = 0x004,
|
||||
COMBINE_ADJACENT_LODS = 0x008,
|
||||
SHARE_DUPLICATE_STATE = 0x010,
|
||||
MERGE_GEOMETRY = 0x020,
|
||||
CHECK_GEOMETRY = 0x040,
|
||||
SPATIALIZE_GROUPS = 0x080,
|
||||
COPY_SHARED_NODES = 0x100,
|
||||
TRISTRIP_GEOMETRY = 0x200,
|
||||
TESSELATE_GEOMETRY = 0x400,
|
||||
OPTIMIZE_TEXTURE_SETTINGS = 0x800,
|
||||
DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
|
||||
REMOVE_REDUNDANT_NODES |
|
||||
REMOVE_LOADED_PROXY_NODES |
|
||||
COMBINE_ADJACENT_LODS |
|
||||
SHARE_DUPLICATE_STATE |
|
||||
MERGE_GEOMETRY |
|
||||
@ -59,6 +61,7 @@ class OSGUTIL_EXPORT Optimizer
|
||||
OPTIMIZE_TEXTURE_SETTINGS,
|
||||
ALL_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
|
||||
REMOVE_REDUNDANT_NODES |
|
||||
REMOVE_LOADED_PROXY_NODES |
|
||||
COMBINE_ADJACENT_LODS |
|
||||
SHARE_DUPLICATE_STATE |
|
||||
MERGE_GEOMETRY |
|
||||
@ -315,7 +318,7 @@ class OSGUTIL_EXPORT Optimizer
|
||||
|
||||
};
|
||||
|
||||
/** Remove rendundant nodes, such as groups with one single child.*/
|
||||
/** Remove redundant nodes, such as groups with one single child.*/
|
||||
class OSGUTIL_EXPORT RemoveRedundantNodesVisitor : public BaseOptimizerVisitor
|
||||
{
|
||||
public:
|
||||
@ -333,6 +336,23 @@ class OSGUTIL_EXPORT Optimizer
|
||||
|
||||
};
|
||||
|
||||
/** Remove loaded proxy nodes.*/
|
||||
class OSGUTIL_EXPORT RemoveLoadedProxyNodesVisitor : public BaseOptimizerVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::set<osg::Node*> NodeList;
|
||||
NodeList _redundantNodeList;
|
||||
|
||||
RemoveLoadedProxyNodesVisitor(Optimizer* optimizer=0):
|
||||
BaseOptimizerVisitor(optimizer, REMOVE_LOADED_PROXY_NODES) {}
|
||||
|
||||
virtual void apply(osg::ProxyNode& group);
|
||||
|
||||
void removeRedundantNodes();
|
||||
|
||||
};
|
||||
|
||||
/** Tesselate all geodes, to remove POLYGONS.*/
|
||||
class OSGUTIL_EXPORT TesselateVisitor : public BaseOptimizerVisitor
|
||||
{
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <osg/Switch>
|
||||
#include <osg/Texture>
|
||||
#include <osg/PagedLOD>
|
||||
#include <osg/ProxyNode>
|
||||
|
||||
#include <osgUtil/TransformAttributeFunctor>
|
||||
#include <osgUtil/TriStripVisitor>
|
||||
@ -43,7 +44,7 @@ void Optimizer::reset()
|
||||
{
|
||||
}
|
||||
|
||||
static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \"<type> [<type>]\"","OFF | DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS");
|
||||
static osg::ApplicationUsageProxy Optimizer_e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_OPTIMIZER \"<type> [<type>]\"","OFF | DEFAULT | FLATTEN_STATIC_TRANSFORMS | REMOVE_REDUNDANT_NODES | COMBINE_ADJACENT_LODS | SHARE_DUPLICATE_STATE | MERGE_GEOMETRY | SPATIALIZE_GROUPS | COPY_SHARED_NODES | TRISTRIP_GEOMETRY | OPTIMIZE_TEXTURE_SETTINGS | REMOVE_LOADED_PROXY_NODES");
|
||||
|
||||
void Optimizer::optimize(osg::Node* node)
|
||||
{
|
||||
@ -66,6 +67,9 @@ void Optimizer::optimize(osg::Node* node)
|
||||
if(str.find("~REMOVE_REDUNDANT_NODES")!=std::string::npos) options ^= REMOVE_REDUNDANT_NODES;
|
||||
else if(str.find("REMOVE_REDUNDANT_NODES")!=std::string::npos) options |= REMOVE_REDUNDANT_NODES;
|
||||
|
||||
if(str.find("~REMOVE_LOADED_PROXY_NODES")!=std::string::npos) options ^= REMOVE_LOADED_PROXY_NODES;
|
||||
else if(str.find("REMOVE_LOADED_PROXY_NODES")!=std::string::npos) options |= REMOVE_LOADED_PROXY_NODES;
|
||||
|
||||
if(str.find("~COMBINE_ADJACENT_LODS")!=std::string::npos) options ^= COMBINE_ADJACENT_LODS;
|
||||
else if(str.find("COMBINE_ADJACENT_LODS")!=std::string::npos) options |= COMBINE_ADJACENT_LODS;
|
||||
|
||||
@ -112,6 +116,16 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
node->accept(tsv);
|
||||
}
|
||||
|
||||
if (options & REMOVE_LOADED_PROXY_NODES)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing REMOVE_LOADED_PROXY_NODES"<<std::endl;
|
||||
|
||||
RemoveLoadedProxyNodesVisitor rlpnv(this);
|
||||
node->accept(rlpnv);
|
||||
rlpnv.removeRedundantNodes();
|
||||
|
||||
}
|
||||
|
||||
if (options & COMBINE_ADJACENT_LODS)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing COMBINE_ADJACENT_LODS"<<std::endl;
|
||||
@ -187,6 +201,7 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (options & CHECK_GEOMETRY)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing CHECK_GEOMETRY"<<std::endl;
|
||||
@ -1210,6 +1225,57 @@ void Optimizer::RemoveRedundantNodesVisitor::removeRedundantNodes()
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// RemoveLoadedProxyNodesVisitor.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Optimizer::RemoveLoadedProxyNodesVisitor::apply(osg::ProxyNode& proxyNode)
|
||||
{
|
||||
if (proxyNode.getNumParents()>0 && proxyNode.getNumFileNames()==proxyNode.getNumChildren())
|
||||
{
|
||||
if (isOperationPermissibleForObject(&proxyNode))
|
||||
{
|
||||
_redundantNodeList.insert(&proxyNode);
|
||||
}
|
||||
}
|
||||
traverse(proxyNode);
|
||||
}
|
||||
|
||||
void Optimizer::RemoveLoadedProxyNodesVisitor::removeRedundantNodes()
|
||||
{
|
||||
|
||||
for(NodeList::iterator itr=_redundantNodeList.begin();
|
||||
itr!=_redundantNodeList.end();
|
||||
++itr)
|
||||
{
|
||||
osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(*itr);
|
||||
if (group.valid())
|
||||
{
|
||||
// take a copy of parents list since subsequent removes will modify the original one.
|
||||
osg::Node::ParentList parents = group->getParents();
|
||||
|
||||
for(unsigned int i=0;i<group->getNumChildren();++i)
|
||||
{
|
||||
osg::Node* child = group->getChild(i);
|
||||
for(osg::Node::ParentList::iterator pitr=parents.begin();
|
||||
pitr!=parents.end();
|
||||
++pitr)
|
||||
{
|
||||
(*pitr)->replaceChild(group.get(),child);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN)<<"Optimizer::RemoveLoadedProxyNodesVisitor::removeRedundantNodes() - failed dynamic_cast"<<std::endl;
|
||||
}
|
||||
}
|
||||
_redundantNodeList.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// combine LOD's.
|
||||
|
Loading…
Reference in New Issue
Block a user