From Roland Smeenk, "While working on the Collada plugin I noticed that all geometry created by the dae reader result in slow path geometry.
Because there already exists the option to convert slow path geometry to the fast path by computing an internal fast path alternative, I added a new optimizer option that automatically does this. To check the results I also made some changes to the statistics gathering and rendering. Somewhat unrelated, but also part of the optimizer I disabled removal of CameraView nodes during RemoveRedundantNodes optimization. As discussed on the ML, CameraViews were removed from the scenegraph. This solves that issue. Summary: -Geometry::areFastPathsUsed now also looks at internalOptimizedGeometry -Added Optimize option to make all slow path geometry compute their internal fast path alternative -Added fast geometry counter to the statistics -Disabled removel of CameraViews in optimizer "
This commit is contained in:
@@ -331,7 +331,13 @@ class OSG_EXPORT Geometry : public Drawable
|
||||
* use glBegin()/glVertex.../glEnd(). Use of per primitive bindings or per vertex indexed
|
||||
* arrays will drop the rendering path off the fast path.
|
||||
*/
|
||||
inline bool areFastPathsUsed() const { return _fastPath && _fastPathHint; }
|
||||
inline bool areFastPathsUsed() const
|
||||
{
|
||||
if (_internalOptimizedGeometry.valid())
|
||||
return _internalOptimizedGeometry->areFastPathsUsed();
|
||||
else
|
||||
return _fastPath && _fastPathHint;
|
||||
}
|
||||
|
||||
bool computeFastPathsUsed();
|
||||
|
||||
|
||||
@@ -74,22 +74,24 @@ class OSGUTIL_EXPORT Optimizer
|
||||
SHARE_DUPLICATE_STATE = (1 << 4),
|
||||
MERGE_GEOMETRY = (1 << 5),
|
||||
CHECK_GEOMETRY = (1 << 6),
|
||||
SPATIALIZE_GROUPS = (1 << 7),
|
||||
COPY_SHARED_NODES = (1 << 8),
|
||||
TRISTRIP_GEOMETRY = (1 << 9),
|
||||
TESSELLATE_GEOMETRY = (1 << 10),
|
||||
OPTIMIZE_TEXTURE_SETTINGS = (1 << 11),
|
||||
MERGE_GEODES = (1 << 12),
|
||||
FLATTEN_BILLBOARDS = (1 << 13),
|
||||
TEXTURE_ATLAS_BUILDER = (1 << 14),
|
||||
STATIC_OBJECT_DETECTION = (1 << 15),
|
||||
FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 16),
|
||||
MAKE_FAST_GEOMETRY = (1 << 7),
|
||||
SPATIALIZE_GROUPS = (1 << 8),
|
||||
COPY_SHARED_NODES = (1 << 9),
|
||||
TRISTRIP_GEOMETRY = (1 << 10),
|
||||
TESSELLATE_GEOMETRY = (1 << 11),
|
||||
OPTIMIZE_TEXTURE_SETTINGS = (1 << 12),
|
||||
MERGE_GEODES = (1 << 13),
|
||||
FLATTEN_BILLBOARDS = (1 << 14),
|
||||
TEXTURE_ATLAS_BUILDER = (1 << 15),
|
||||
STATIC_OBJECT_DETECTION = (1 << 16),
|
||||
FLATTEN_STATIC_TRANSFORMS_DUPLICATING_SHARED_SUBGRAPHS = (1 << 17),
|
||||
DEFAULT_OPTIMIZATIONS = FLATTEN_STATIC_TRANSFORMS |
|
||||
REMOVE_REDUNDANT_NODES |
|
||||
REMOVE_LOADED_PROXY_NODES |
|
||||
COMBINE_ADJACENT_LODS |
|
||||
SHARE_DUPLICATE_STATE |
|
||||
MERGE_GEOMETRY |
|
||||
MAKE_FAST_GEOMETRY |
|
||||
CHECK_GEOMETRY |
|
||||
OPTIMIZE_TEXTURE_SETTINGS |
|
||||
STATIC_OBJECT_DETECTION,
|
||||
@@ -100,6 +102,7 @@ class OSGUTIL_EXPORT Optimizer
|
||||
SHARE_DUPLICATE_STATE |
|
||||
MERGE_GEODES |
|
||||
MERGE_GEOMETRY |
|
||||
MAKE_FAST_GEOMETRY |
|
||||
CHECK_GEOMETRY |
|
||||
SPATIALIZE_GROUPS |
|
||||
COPY_SHARED_NODES |
|
||||
@@ -506,6 +509,20 @@ class OSGUTIL_EXPORT Optimizer
|
||||
|
||||
};
|
||||
|
||||
class OSGUTIL_EXPORT MakeFastGeometryVisitor : public BaseOptimizerVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
/// default to traversing all children.
|
||||
MakeFastGeometryVisitor(Optimizer* optimizer=0):
|
||||
BaseOptimizerVisitor(optimizer, MAKE_FAST_GEOMETRY) {}
|
||||
|
||||
virtual void apply(osg::Geode& geode) { checkGeode(geode); }
|
||||
|
||||
void checkGeode(osg::Geode& geode);
|
||||
|
||||
};
|
||||
|
||||
class OSGUTIL_EXPORT MergeGeometryVisitor : public BaseOptimizerVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -201,6 +201,7 @@ public:
|
||||
unsigned int _numInstancedGeode;
|
||||
unsigned int _numInstancedDrawable;
|
||||
unsigned int _numInstancedGeometry;
|
||||
unsigned int _numInstancedFastGeometry;
|
||||
unsigned int _numInstancedStateSet;
|
||||
|
||||
NodeSet _groupSet;
|
||||
@@ -210,6 +211,7 @@ public:
|
||||
NodeSet _geodeSet;
|
||||
DrawableSet _drawableSet;
|
||||
DrawableSet _geometrySet;
|
||||
DrawableSet _fastGeometrySet;
|
||||
StateSetSet _statesetSet;
|
||||
|
||||
osgUtil::Statistics _uniqueStats;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/LOD>
|
||||
#include <osg/Billboard>
|
||||
#include <osg/CameraView>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Notify>
|
||||
#include <osg/OccluderNode>
|
||||
@@ -109,6 +110,9 @@ void Optimizer::optimize(osg::Node* node)
|
||||
|
||||
if(str.find("~CHECK_GEOMETRY")!=std::string::npos) options ^= CHECK_GEOMETRY;
|
||||
else if(str.find("CHECK_GEOMETRY")!=std::string::npos) options |= CHECK_GEOMETRY;
|
||||
|
||||
if(str.find("~MAKE_FAST_GEOMETRY")!=std::string::npos) options ^= MAKE_FAST_GEOMETRY;
|
||||
else if(str.find("MAKE_FAST_GEOMETRY")!=std::string::npos) options |= MAKE_FAST_GEOMETRY;
|
||||
|
||||
if(str.find("~FLATTEN_BILLBOARDS")!=std::string::npos) options ^= FLATTEN_BILLBOARDS;
|
||||
else if(str.find("FLATTEN_BILLBOARDS")!=std::string::npos) options |= FLATTEN_BILLBOARDS;
|
||||
@@ -279,6 +283,14 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
node->accept(mgv);
|
||||
}
|
||||
|
||||
if (options & MAKE_FAST_GEOMETRY)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing MAKE_FAST_GEOMETRY"<<std::endl;
|
||||
|
||||
MakeFastGeometryVisitor mgv(this);
|
||||
node->accept(mgv);
|
||||
}
|
||||
|
||||
if (options & MERGE_GEOMETRY)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing MERGE_GEOMETRY"<<std::endl;
|
||||
@@ -1308,7 +1320,7 @@ void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
|
||||
{
|
||||
// only remove empty groups, but not empty occluders.
|
||||
if (group.getNumChildren()==0 && isOperationPermissibleForObject(&group) &&
|
||||
(typeid(group)==typeid(osg::Group) || dynamic_cast<osg::Transform*>(&group)))
|
||||
(typeid(group)==typeid(osg::Group) || (dynamic_cast<osg::Transform*>(&group) && !dynamic_cast<osg::CameraView*>(&group))))
|
||||
{
|
||||
_redundantNodeList.insert(&group);
|
||||
}
|
||||
@@ -1785,6 +1797,24 @@ void Optimizer::CheckGeometryVisitor::checkGeode(osg::Geode& geode)
|
||||
}
|
||||
}
|
||||
|
||||
void Optimizer::MakeFastGeometryVisitor::checkGeode(osg::Geode& geode)
|
||||
{
|
||||
if (isOperationPermissibleForObject(&geode))
|
||||
{
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
|
||||
if (geom && isOperationPermissibleForObject(geom))
|
||||
{
|
||||
if (!geom->areFastPathsUsed() && !geom->getInternalOptimizedGeometry())
|
||||
{
|
||||
geom->computeInternalOptimizedGeometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
||||
{
|
||||
if (!isOperationPermissibleForObject(&geode)) return false;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <ostream>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace osgUtil;
|
||||
|
||||
@@ -143,6 +144,7 @@ StatsVisitor::StatsVisitor():
|
||||
_numInstancedGeode(0),
|
||||
_numInstancedDrawable(0),
|
||||
_numInstancedGeometry(0),
|
||||
_numInstancedFastGeometry(0),
|
||||
_numInstancedStateSet(0)
|
||||
{}
|
||||
|
||||
@@ -155,6 +157,7 @@ void StatsVisitor::reset()
|
||||
_numInstancedGeode = 0;
|
||||
_numInstancedDrawable = 0;
|
||||
_numInstancedGeometry = 0;
|
||||
_numInstancedFastGeometry = 0;
|
||||
_numInstancedStateSet = 0;
|
||||
|
||||
_groupSet.clear();
|
||||
@@ -164,6 +167,7 @@ void StatsVisitor::reset()
|
||||
_geodeSet.clear();
|
||||
_drawableSet.clear();
|
||||
_geometrySet.clear();
|
||||
_fastGeometrySet.clear();
|
||||
_statesetSet.clear();
|
||||
|
||||
_uniqueStats.reset();
|
||||
@@ -264,12 +268,18 @@ void StatsVisitor::apply(osg::Drawable& drawable)
|
||||
drawable.accept(_instancedStats);
|
||||
|
||||
_drawableSet.insert(&drawable);
|
||||
|
||||
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(&drawable);
|
||||
|
||||
osg::Geometry* geometry = drawable.asGeometry();
|
||||
if (geometry)
|
||||
{
|
||||
++_numInstancedGeometry;
|
||||
_geometrySet.insert(geometry);
|
||||
|
||||
if (geometry->areFastPathsUsed())
|
||||
{
|
||||
++_numInstancedFastGeometry;
|
||||
_fastGeometrySet.insert(geometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,16 +315,19 @@ void StatsVisitor::print(std::ostream& out)
|
||||
instanced_primitives += pcmitr->second;
|
||||
}
|
||||
|
||||
out<<"Object Type\t#Unique\t#Instanced"<<std::endl;
|
||||
out<<"StateSet \t"<<_statesetSet.size()<<"\t"<<_numInstancedStateSet<<std::endl;
|
||||
out<<"Group \t"<<_groupSet.size()<<"\t"<<_numInstancedGroup<<std::endl;
|
||||
out<<"Transform \t"<<_transformSet.size()<<"\t"<<_numInstancedTransform<<std::endl;
|
||||
out<<"LOD \t"<<_lodSet.size()<<"\t"<<_numInstancedLOD<<std::endl;
|
||||
out<<"Switch \t"<<_switchSet.size()<<"\t"<<_numInstancedSwitch<<std::endl;
|
||||
out<<"Geode \t"<<_geodeSet.size()<<"\t"<<_numInstancedGeode<<std::endl;
|
||||
out<<"Drawable \t"<<_drawableSet.size()<<"\t"<<_numInstancedDrawable<<std::endl;
|
||||
out<<"Geometry \t"<<_geometrySet.size()<<"\t"<<_numInstancedGeometry<<std::endl;
|
||||
out<<"Vertices \t"<<_uniqueStats._vertexCount<<"\t"<<_instancedStats._vertexCount<<std::endl;
|
||||
out<<"Primitives \t"<<unique_primitives<<"\t"<<instanced_primitives<<std::endl;
|
||||
|
||||
out << std::setw(12) << "Object Type" << std::setw(10) << "Unique" << std::setw(10) << "Instanced" << std::endl;
|
||||
out << std::setw(12) << "-----------" << std::setw(10) << "------" << std::setw(10) << "---------" << std::endl;
|
||||
out << std::setw(12) << "StateSet " << std::setw(10) << _statesetSet.size() << std::setw(10) << _numInstancedStateSet << std::endl;
|
||||
out << std::setw(12) << "Group " << std::setw(10) << _groupSet.size() << std::setw(10) << _numInstancedGroup << std::endl;
|
||||
out << std::setw(12) << "Transform " << std::setw(10) << _transformSet.size() << std::setw(10) << _numInstancedTransform << std::endl;
|
||||
out << std::setw(12) << "LOD " << std::setw(10) << _lodSet.size() << std::setw(10) << _numInstancedLOD << std::endl;
|
||||
out << std::setw(12) << "Switch " << std::setw(10) << _switchSet.size() << std::setw(10) << _numInstancedSwitch << std::endl;
|
||||
out << std::setw(12) << "Geode " << std::setw(10) << _geodeSet.size() << std::setw(10) << _numInstancedGeode << std::endl;
|
||||
out << std::setw(12) << "Drawable " << std::setw(10) << _drawableSet.size() << std::setw(10) << _numInstancedDrawable << std::endl;
|
||||
out << std::setw(12) << "Geometry " << std::setw(10) << _geometrySet.size() << std::setw(10) << _numInstancedGeometry << std::endl;
|
||||
out << std::setw(12) << "Fast geom. " << std::setw(10) << _fastGeometrySet.size() << std::setw(10) << _numInstancedFastGeometry << std::endl;
|
||||
out << std::setw(12) << "Vertices " << std::setw(10) << _uniqueStats._vertexCount << std::setw(10) << _instancedStats._vertexCount << std::endl;
|
||||
out << std::setw(12) << "Primitives " << std::setw(10) << unique_primitives << std::setw(10) << instanced_primitives << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ void ViewerBase::startThreading()
|
||||
|
||||
if (!gc->isRealized())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizing window "<<gc<<std::endl;
|
||||
osg::notify(osg::INFO)<<"ViewerBase::startThreading() : Realizng window "<<gc<<std::endl;
|
||||
gc->realize();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user