commit
1d8efb1a3a
@ -532,10 +532,10 @@ class OSGUTIL_EXPORT Optimizer
|
|||||||
return _targetMaximumNumberOfVertices;
|
return _targetMaximumNumberOfVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(osg::Geode& geode) { mergeGeode(geode); }
|
virtual void apply(osg::Group& group) { mergeGroup(group); traverse(group); }
|
||||||
virtual void apply(osg::Billboard&) { /* don't do anything*/ }
|
virtual void apply(osg::Billboard&) { /* don't do anything*/ }
|
||||||
|
|
||||||
bool mergeGeode(osg::Geode& geode);
|
bool mergeGroup(osg::Group& group);
|
||||||
|
|
||||||
static bool geometryContainsSharedArrays(osg::Geometry& geom);
|
static bool geometryContainsSharedArrays(osg::Geometry& geom);
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ osgDB::ReaderWriter::WriteResult ReaderWriterKTX::writeImage(const osg::Image &i
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
osgDB::ReaderWriter::WriteResult ReaderWriterKTX::writeImage(const osg::Image& image, std::ostream& fout, const Options* options) const
|
osgDB::ReaderWriter::WriteResult ReaderWriterKTX::writeImage(const osg::Image& image, std::ostream& fout, const Options* /*options*/) const
|
||||||
{
|
{
|
||||||
// bool noAutoFlipDDSWrite = options && options->getOptionString().find("ddsNoAutoFlipWrite") != std::string::npos; //maybe for ktx too?
|
// bool noAutoFlipDDSWrite = options && options->getOptionString().find("ddsNoAutoFlipWrite") != std::string::npos; //maybe for ktx too?
|
||||||
bool success = writeKTXStream(&image, fout);
|
bool success = writeKTXStream(&image, fout);
|
||||||
|
@ -274,6 +274,20 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options & REMOVE_REDUNDANT_NODES)
|
||||||
|
{
|
||||||
|
OSG_INFO<<"Optimizer::optimize() doing REMOVE_REDUNDANT_NODES"<<std::endl;
|
||||||
|
|
||||||
|
RemoveEmptyNodesVisitor renv(this);
|
||||||
|
node->accept(renv);
|
||||||
|
renv.removeEmptyNodes();
|
||||||
|
|
||||||
|
RemoveRedundantNodesVisitor rrnv(this);
|
||||||
|
node->accept(rrnv);
|
||||||
|
rrnv.removeRedundantNodes();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (options & MERGE_GEODES)
|
if (options & MERGE_GEODES)
|
||||||
{
|
{
|
||||||
OSG_INFO<<"Optimizer::optimize() doing MERGE_GEODES"<<std::endl;
|
OSG_INFO<<"Optimizer::optimize() doing MERGE_GEODES"<<std::endl;
|
||||||
@ -320,20 +334,6 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
|||||||
tsv.stripify();
|
tsv.stripify();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options & REMOVE_REDUNDANT_NODES)
|
|
||||||
{
|
|
||||||
OSG_INFO<<"Optimizer::optimize() doing REMOVE_REDUNDANT_NODES"<<std::endl;
|
|
||||||
|
|
||||||
RemoveEmptyNodesVisitor renv(this);
|
|
||||||
node->accept(renv);
|
|
||||||
renv.removeEmptyNodes();
|
|
||||||
|
|
||||||
RemoveRedundantNodesVisitor rrnv(this);
|
|
||||||
node->accept(rrnv);
|
|
||||||
rrnv.removeRedundantNodes();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options & FLATTEN_BILLBOARDS)
|
if (options & FLATTEN_BILLBOARDS)
|
||||||
{
|
{
|
||||||
FlattenBillboardVisitor fbv(this);
|
FlattenBillboardVisitor fbv(this);
|
||||||
@ -757,12 +757,15 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor
|
|||||||
|
|
||||||
inline bool isOperationPermissibleForObject(const osg::Object* object) const
|
inline bool isOperationPermissibleForObject(const osg::Object* object) const
|
||||||
{
|
{
|
||||||
const osg::Drawable* drawable = dynamic_cast<const osg::Drawable*>(object);
|
const osg::Node* node = object->asNode();
|
||||||
if (drawable) return isOperationPermissibleForObject(drawable);
|
if (node)
|
||||||
|
{
|
||||||
const osg::Node* node = dynamic_cast<const osg::Node*>(object);
|
const osg::Drawable* drawable = node->asDrawable();
|
||||||
if (node) return isOperationPermissibleForObject(node);
|
if (drawable)
|
||||||
|
return isOperationPermissibleForObject(drawable);
|
||||||
|
else
|
||||||
|
return isOperationPermissibleForObject(node);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -872,7 +875,10 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor
|
|||||||
|
|
||||||
void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& matrix)
|
void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& matrix)
|
||||||
{
|
{
|
||||||
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(obj);
|
osg::Node* node = obj->asNode();
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
osg::Drawable* drawable = node->asDrawable();
|
||||||
if (drawable)
|
if (drawable)
|
||||||
{
|
{
|
||||||
osgUtil::TransformAttributeFunctor tf(matrix);
|
osgUtil::TransformAttributeFunctor tf(matrix);
|
||||||
@ -1058,7 +1064,10 @@ bool CollectLowestTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRem
|
|||||||
group->setDataVariance(osg::Object::STATIC);
|
group->setDataVariance(osg::Object::STATIC);
|
||||||
group->setNodeMask(transform->getNodeMask());
|
group->setNodeMask(transform->getNodeMask());
|
||||||
group->setStateSet(transform->getStateSet());
|
group->setStateSet(transform->getStateSet());
|
||||||
group->setUserData(transform->getUserData());
|
group->setUpdateCallback(transform->getUpdateCallback());
|
||||||
|
group->setEventCallback(transform->getEventCallback());
|
||||||
|
group->setCullCallback(transform->getCullCallback());
|
||||||
|
group->setUserDataContainer(transform->getUserDataContainer());
|
||||||
group->setDescriptions(transform->getDescriptions());
|
group->setDescriptions(transform->getDescriptions());
|
||||||
for(unsigned int i=0;i<transform->getNumChildren();++i)
|
for(unsigned int i=0;i<transform->getNumChildren();++i)
|
||||||
{
|
{
|
||||||
@ -1072,11 +1081,11 @@ bool CollectLowestTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRem
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(titr->first);
|
osg::MatrixTransform* mt = titr->first->asMatrixTransform();
|
||||||
if (mt) mt->setMatrix(osg::Matrix::identity());
|
if (mt) mt->setMatrix(osg::Matrix::identity());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(titr->first);
|
osg::PositionAttitudeTransform* pat = titr->first->asPositionAttitudeTransform();
|
||||||
if (pat)
|
if (pat)
|
||||||
{
|
{
|
||||||
pat->setPosition(osg::Vec3(0.0f,0.0f,0.0f));
|
pat->setPosition(osg::Vec3(0.0f,0.0f,0.0f));
|
||||||
@ -1279,7 +1288,7 @@ void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
|
|||||||
{
|
{
|
||||||
// only remove empty groups, but not empty occluders.
|
// only remove empty groups, but not empty occluders.
|
||||||
if (group.getNumChildren()==0 && isOperationPermissibleForObject(&group) &&
|
if (group.getNumChildren()==0 && isOperationPermissibleForObject(&group) &&
|
||||||
(typeid(group)==typeid(osg::Group) || (dynamic_cast<osg::Transform*>(&group) && !dynamic_cast<osg::CameraView*>(&group))) &&
|
(typeid(group)==typeid(osg::Group) || (group.asTransform() && !dynamic_cast<osg::CameraView*>(&group))) &&
|
||||||
(group.getNumChildrenRequiringUpdateTraversal()==0 && group.getNumChildrenRequiringEventTraversal()==0) )
|
(group.getNumChildrenRequiringUpdateTraversal()==0 && group.getNumChildrenRequiringEventTraversal()==0) )
|
||||||
{
|
{
|
||||||
_redundantNodeList.insert(&group);
|
_redundantNodeList.insert(&group);
|
||||||
@ -1380,7 +1389,7 @@ void Optimizer::RemoveRedundantNodesVisitor::removeRedundantNodes()
|
|||||||
itr!=_redundantNodeList.end();
|
itr!=_redundantNodeList.end();
|
||||||
++itr)
|
++itr)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(*itr);
|
osg::ref_ptr<osg::Group> group = (*itr)->asGroup();
|
||||||
if (group.valid())
|
if (group.valid())
|
||||||
{
|
{
|
||||||
// take a copy of parents list since subsequent removes will modify the original one.
|
// take a copy of parents list since subsequent removes will modify the original one.
|
||||||
@ -1776,15 +1785,13 @@ bool isAbleToMerge(const osg::Geometry& g1, const osg::Geometry& g2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
bool Optimizer::MergeGeometryVisitor::mergeGroup(osg::Group& group)
|
||||||
{
|
{
|
||||||
if (!isOperationPermissibleForObject(&geode)) return false;
|
if (!isOperationPermissibleForObject(&group)) return false;
|
||||||
|
|
||||||
if (geode.getNumDrawables()>=2)
|
if (group.getNumChildren()>=2)
|
||||||
{
|
{
|
||||||
|
|
||||||
// OSG_NOTICE<<"Before "<<geode.getNumDrawables()<<std::endl;
|
|
||||||
|
|
||||||
typedef std::vector<osg::Geometry*> DuplicateList;
|
typedef std::vector<osg::Geometry*> DuplicateList;
|
||||||
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
|
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
|
||||||
typedef std::map<osg::Geometry*,DuplicateList,LessGeometry> GeometryDuplicateMap;
|
typedef std::map<osg::Geometry*,DuplicateList,LessGeometry> GeometryDuplicateMap;
|
||||||
@ -1795,9 +1802,9 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
|||||||
DrawableList standardDrawables;
|
DrawableList standardDrawables;
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for(i=0;i<geode.getNumDrawables();++i)
|
for(i=0;i<group.getNumChildren();++i)
|
||||||
{
|
{
|
||||||
osg::Drawable* drawable = geode.getDrawable(i);
|
osg::Drawable* drawable = group.getChild(i)->asDrawable();
|
||||||
if (drawable)
|
if (drawable)
|
||||||
{
|
{
|
||||||
osg::Geometry* geom = drawable->asGeometry();
|
osg::Geometry* geom = drawable->asGeometry();
|
||||||
@ -1939,26 +1946,6 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
|||||||
|
|
||||||
if (needToDoMerge)
|
if (needToDoMerge)
|
||||||
{
|
{
|
||||||
// first take a reference to all the drawables to prevent them being deleted prematurely
|
|
||||||
DrawableList keepDrawables;
|
|
||||||
keepDrawables.resize(geode.getNumDrawables());
|
|
||||||
for(i=0; i<geode.getNumDrawables(); ++i)
|
|
||||||
{
|
|
||||||
osg::Drawable* drawable = geode.getDrawable(i);
|
|
||||||
if (drawable) keepDrawables[i] = geode.getDrawable(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now clear the drawable list of the Geode so we don't have to remove items one by one (which is slow)
|
|
||||||
geode.removeDrawables(0, geode.getNumDrawables());
|
|
||||||
|
|
||||||
// add back in the standard drawables which arn't possible to merge.
|
|
||||||
for(DrawableList::iterator sitr = standardDrawables.begin();
|
|
||||||
sitr != standardDrawables.end();
|
|
||||||
++sitr)
|
|
||||||
{
|
|
||||||
geode.addDrawable(sitr->get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// now do the merging of geometries
|
// now do the merging of geometries
|
||||||
for(MergeList::iterator mitr = mergeList.begin();
|
for(MergeList::iterator mitr = mergeList.begin();
|
||||||
mitr != mergeList.end();
|
mitr != mergeList.end();
|
||||||
@ -1968,18 +1955,15 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
|||||||
if (duplicateList.size()>1)
|
if (duplicateList.size()>1)
|
||||||
{
|
{
|
||||||
osg::Geometry* lhs = duplicateList.front();
|
osg::Geometry* lhs = duplicateList.front();
|
||||||
geode.addDrawable(lhs);
|
|
||||||
for(DuplicateList::iterator ditr = duplicateList.begin()+1;
|
for(DuplicateList::iterator ditr = duplicateList.begin()+1;
|
||||||
ditr != duplicateList.end();
|
ditr != duplicateList.end();
|
||||||
++ditr)
|
++ditr)
|
||||||
{
|
{
|
||||||
mergeGeometry(*lhs,**ditr);
|
mergeGeometry(*lhs,**ditr);
|
||||||
|
|
||||||
|
group.removeChild(*ditr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (duplicateList.size()>0)
|
|
||||||
{
|
|
||||||
geode.addDrawable(duplicateList.front());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2029,16 +2013,17 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// OSG_NOTICE<<"After "<<geode.getNumDrawables()<<std::endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// convert all polygon primitives which has 3 indices into TRIANGLES, 4 indices into QUADS.
|
// convert all polygon primitives which has 3 indices into TRIANGLES, 4 indices into QUADS.
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for(i=0;i<geode.getNumDrawables();++i)
|
for(i=0;i<group.getNumChildren();++i)
|
||||||
{
|
{
|
||||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
osg::Drawable* drawable = group.getChild(i)->asDrawable();
|
||||||
|
if (!drawable)
|
||||||
|
continue;
|
||||||
|
osg::Geometry* geom = drawable->asGeometry();
|
||||||
if (geom)
|
if (geom)
|
||||||
{
|
{
|
||||||
osg::Geometry::PrimitiveSetList& primitives = geom->getPrimitiveSetList();
|
osg::Geometry::PrimitiveSetList& primitives = geom->getPrimitiveSetList();
|
||||||
@ -2063,9 +2048,12 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// now merge any compatible primitives.
|
// now merge any compatible primitives.
|
||||||
for(i=0;i<geode.getNumDrawables();++i)
|
for(i=0;i<group.getNumChildren();++i)
|
||||||
{
|
{
|
||||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
osg::Drawable* drawable = group.getChild(i)->asDrawable();
|
||||||
|
if (!drawable)
|
||||||
|
continue;
|
||||||
|
osg::Geometry* geom = drawable->asGeometry();
|
||||||
if (geom)
|
if (geom)
|
||||||
{
|
{
|
||||||
if (geom->getNumPrimitiveSets()>0 &&
|
if (geom->getNumPrimitiveSets()>0 &&
|
||||||
|
Loading…
Reference in New Issue
Block a user