diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp index 2cfabbfe19..b9d2f5bac7 100644 --- a/components/sceneutil/optimizer.cpp +++ b/components/sceneutil/optimizer.cpp @@ -171,7 +171,7 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor setTraversalMode(osg::NodeVisitor::TRAVERSE_PARENTS); } - void apply(osg::Node& node) override + void apply(osg::Group& node) override { if (node.getNumParents()) { @@ -180,7 +180,7 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor else { // for all current objects mark a nullptr transform for them. - registerWithCurrentObjects(0); + registerWithCurrentObjects(static_cast(nullptr)); } } @@ -198,15 +198,19 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor // for all current objects associated this transform with them. registerWithCurrentObjects(&transform); } + void apply(osg::MatrixTransform& transform) override + { + // for all current objects associated this transform with them. + registerWithCurrentObjects(&transform); + } - void apply(osg::Geode& geode) override + void apply(osg::Node& node) override { - traverse(geode); + traverse(node); } - void apply(osg::Billboard& geode) override + void apply(osg::Geometry& geode) override { - traverse(geode); } void collectDataFor(osg::Node* node) @@ -293,7 +297,19 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor ObjectStruct():_canBeApplied(true),_moreThanOneMatrixRequired(false) {} - void add(osg::Transform* transform, bool canOptimize) + inline const osg::Matrix& getMatrix(osg::MatrixTransform* transform) + { + return transform->getMatrix(); + } + osg::Matrix getMatrix(osg::Transform* transform) + { + osg::Matrix matrix; + transform->computeLocalToWorldMatrix(matrix, 0); + return matrix; + } + + template + void add(T* transform, bool canOptimize) { if (transform) { @@ -301,12 +317,10 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor else if (transform->getReferenceFrame()!=osg::Transform::RELATIVE_RF) _moreThanOneMatrixRequired=true; else { - if (_transformSet.empty()) transform->computeLocalToWorldMatrix(_firstMatrix,0); + if (_transformSet.empty()) _firstMatrix = getMatrix(transform); else { - osg::Matrix matrix; - transform->computeLocalToWorldMatrix(matrix,0); - if (_firstMatrix!=matrix) _moreThanOneMatrixRequired=true; + if (_firstMatrix!=getMatrix(transform)) _moreThanOneMatrixRequired=true; } } } @@ -327,8 +341,8 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor TransformSet _transformSet; }; - - void registerWithCurrentObjects(osg::Transform* transform) + template + void registerWithCurrentObjects(T* transform) { for(ObjectList::iterator itr=_currentObjectList.begin(); itr!=_currentObjectList.end(); @@ -633,19 +647,23 @@ osg::Array* cloneArray(osg::Array* array, osg::VertexBufferObject*& vbo, const o return array; } -void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Drawable& drawable) +void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Geometry& geometry) { - osg::Geometry *geometry = drawable.asGeometry(); - if((geometry) && (isOperationPermissibleForObject(&drawable))) + if(isOperationPermissibleForObject(&geometry)) { osg::VertexBufferObject* vbo = nullptr; - if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) - geometry->setVertexArray(cloneArray(geometry->getVertexArray(), vbo, geometry)); - if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) - geometry->setNormalArray(cloneArray(geometry->getNormalArray(), vbo, geometry)); - if(geometry->getTexCoordArray(7) && geometry->getTexCoordArray(7)->referenceCount() > 1) // tangents - geometry->setTexCoordArray(7, cloneArray(geometry->getTexCoordArray(7), vbo, geometry)); + if(geometry.getVertexArray() && geometry.getVertexArray()->referenceCount() > 1) + geometry.setVertexArray(cloneArray(geometry.getVertexArray(), vbo, &geometry)); + if(geometry.getNormalArray() && geometry.getNormalArray()->referenceCount() > 1) + geometry.setNormalArray(cloneArray(geometry.getNormalArray(), vbo, &geometry)); + if(geometry.getTexCoordArray(7) && geometry.getTexCoordArray(7)->referenceCount() > 1) // tangents + geometry.setTexCoordArray(7, cloneArray(geometry.getTexCoordArray(7), vbo, &geometry)); } + _drawableSet.insert(&geometry); +} + +void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Drawable& drawable) +{ _drawableSet.insert(&drawable); } @@ -673,6 +691,11 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Transform& transform) _transformStack.pop_back(); } +void Optimizer::FlattenStaticTransformsVisitor::apply(osg::MatrixTransform& transform) +{ + apply(static_cast(transform)); +} + bool Optimizer::FlattenStaticTransformsVisitor::removeTransforms(osg::Node* nodeWeCannotRemove) { CollectLowestTransformsVisitor cltv(_optimizer); @@ -1112,10 +1135,13 @@ bool isAbleToMerge(const osg::Geometry& g1, const osg::Geometry& g2) } -void Optimizer::MergeGeometryVisitor::pushStateSet(osg::StateSet *stateSet) +bool Optimizer::MergeGeometryVisitor::pushStateSet(osg::StateSet *stateSet) { + if (_mergeAlphaBlending || !stateSet || stateSet->getRenderBinMode() & osg::StateSet::INHERIT_RENDERBIN_DETAILS) + return false; _stateSetStack.push_back(stateSet); checkAlphaBlendingActive(); + return true; } void Optimizer::MergeGeometryVisitor::popStateSet() @@ -1145,15 +1171,14 @@ void Optimizer::MergeGeometryVisitor::checkAlphaBlendingActive() void Optimizer::MergeGeometryVisitor::apply(osg::Group &group) { - if (group.getStateSet()) - pushStateSet(group.getStateSet()); + bool pushed = pushStateSet(group.getStateSet()); if (!_alphaBlendingActive || _mergeAlphaBlending) mergeGroup(group); traverse(group); - if (group.getStateSet()) + if (pushed) popStateSet(); } diff --git a/components/sceneutil/optimizer.hpp b/components/sceneutil/optimizer.hpp index 7b32bafee2..5191bcf322 100644 --- a/components/sceneutil/optimizer.hpp +++ b/components/sceneutil/optimizer.hpp @@ -285,9 +285,11 @@ class Optimizer BaseOptimizerVisitor(optimizer, FLATTEN_STATIC_TRANSFORMS) {} void apply(osg::Node& geode) override; + void apply(osg::Geometry& drawable) override; void apply(osg::Drawable& drawable) override; void apply(osg::Billboard& geode) override; - void apply(osg::Transform& transform) override; + void apply(osg::Transform& transform) override final; + void apply(osg::MatrixTransform& transform) override; bool removeTransforms(osg::Node* nodeWeCannotRemove); @@ -316,6 +318,7 @@ class Optimizer BaseOptimizerVisitor(optimizer, FLATTEN_STATIC_TRANSFORMS) {} void apply(osg::MatrixTransform& transform) override; + void apply(osg::Geometry&) override { } bool removeTransforms(osg::Node* nodeWeCannotRemove); @@ -338,6 +341,7 @@ class Optimizer BaseOptimizerVisitor(optimizer, REMOVE_REDUNDANT_NODES) {} void apply(osg::Group& group) override; + void apply(osg::Geometry&) override { } void removeEmptyNodes(); @@ -358,6 +362,7 @@ class Optimizer void apply(osg::Transform& transform) override; void apply(osg::LOD& lod) override; void apply(osg::Switch& switchNode) override; + void apply(osg::Geometry&) override { } bool isOperationPermissible(osg::Node& node); @@ -376,6 +381,7 @@ class Optimizer bool isOperationPermissible(osg::Group& node); + void apply(osg::Geometry&) override { } void apply(osg::Group& group) override; void apply(osg::LOD& lod) override; void apply(osg::Switch& switchNode) override; @@ -409,10 +415,10 @@ class Optimizer return _targetMaximumNumberOfVertices; } - void pushStateSet(osg::StateSet* stateSet); + bool pushStateSet(osg::StateSet* stateSet); void popStateSet(); void checkAlphaBlendingActive(); - + void apply(osg::Geometry&) override { } void apply(osg::Group& group) override; void apply(osg::Billboard&) override { /* don't do anything*/ }