From 33e654f94daa16041088e03042285f71d7ef74f4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 4 Feb 2017 02:15:55 +0100 Subject: [PATCH] Add explicit handling of most commonly used nodes to NodeVisitors to avoid excessive virtual function calls --- apps/openmw/mwrender/animation.cpp | 9 +++++++++ components/nifosg/particle.cpp | 18 +++++++++++++++++- components/nifosg/particle.hpp | 9 ++++++++- components/sceneutil/attach.cpp | 18 ++++++++++++++++++ components/sceneutil/controller.cpp | 17 +++++++++++++++++ components/sceneutil/controller.hpp | 7 +++++++ components/sceneutil/visitor.cpp | 29 ++++++++++++++++++++++++++--- components/sceneutil/visitor.hpp | 7 +++++++ 8 files changed, 109 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index e7227178f..d0806b511 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -179,6 +179,15 @@ namespace { } + virtual void apply(osg::Group& node) + { + traverse(node); + } + virtual void apply(osg::MatrixTransform& node) + { + traverse(node); + } + void remove() { for (RemoveVec::iterator it = mToRemove.begin(); it != mToRemove.end(); ++it) diff --git a/components/nifosg/particle.cpp b/components/nifosg/particle.cpp index 0259b27e4..fa0fe0be3 100644 --- a/components/nifosg/particle.cpp +++ b/components/nifosg/particle.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -315,7 +316,22 @@ FindGroupByRecIndex::FindGroupByRecIndex(int recIndex) { } -void FindGroupByRecIndex::apply(osg::Node &searchNode) +void FindGroupByRecIndex::apply(osg::Node &node) +{ + applyNode(node); +} + +void FindGroupByRecIndex::apply(osg::MatrixTransform &node) +{ + applyNode(node); +} + +void FindGroupByRecIndex::apply(osg::Geometry &node) +{ + applyNode(node); +} + +void FindGroupByRecIndex::applyNode(osg::Node &searchNode) { if (searchNode.getUserDataContainer() && searchNode.getUserDataContainer()->getNumUserObjects()) { diff --git a/components/nifosg/particle.hpp b/components/nifosg/particle.hpp index f9c4abdac..7a2377f9d 100644 --- a/components/nifosg/particle.hpp +++ b/components/nifosg/particle.hpp @@ -196,7 +196,14 @@ namespace NifOsg public: FindGroupByRecIndex(int recIndex); - virtual void apply(osg::Node &searchNode); + virtual void apply(osg::Node &node); + + // Technically not required as the default implementation would trickle down to apply(Node&) anyway, + // but we'll shortcut instead to avoid the chain of virtual function calls + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Geometry& node); + + void applyNode(osg::Node& searchNode); osg::Group* mFound; osg::NodePath mFoundPath; diff --git a/components/sceneutil/attach.cpp b/components/sceneutil/attach.cpp index f80ae9520..2a8f94c7c 100644 --- a/components/sceneutil/attach.cpp +++ b/components/sceneutil/attach.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -29,7 +30,24 @@ namespace SceneUtil mFilter2 = "tri " + mFilter; } + virtual void apply(osg::MatrixTransform& node) + { + applyNode(node); + } + virtual void apply(osg::Geometry& node) + { + applyNode(node); + } virtual void apply(osg::Node& node) + { + applyNode(node); + } + virtual void apply(osg::Group& node) + { + applyNode(node); + } + + void applyNode(osg::Node& node) { std::string lowerName = Misc::StringUtils::lowerCase(node.getName()); if ((lowerName.size() >= mFilter.size() && lowerName.compare(0, mFilter.size(), mFilter) == 0) diff --git a/components/sceneutil/controller.cpp b/components/sceneutil/controller.cpp index 15a614880..6cd0cb036 100644 --- a/components/sceneutil/controller.cpp +++ b/components/sceneutil/controller.cpp @@ -3,6 +3,8 @@ #include "statesetupdater.hpp" #include +#include +#include #include namespace SceneUtil @@ -62,6 +64,21 @@ namespace SceneUtil } void ControllerVisitor::apply(osg::Node &node) + { + applyNode(node); + } + + void ControllerVisitor::apply(osg::MatrixTransform &node) + { + applyNode(node); + } + + void ControllerVisitor::apply(osg::Geometry &node) + { + applyNode(node); + } + + void ControllerVisitor::applyNode(osg::Node &node) { osg::Callback* callback = node.getUpdateCallback(); while (callback) diff --git a/components/sceneutil/controller.hpp b/components/sceneutil/controller.hpp index 3f1ec874e..fd8964ae1 100644 --- a/components/sceneutil/controller.hpp +++ b/components/sceneutil/controller.hpp @@ -64,6 +64,13 @@ namespace SceneUtil virtual void apply(osg::Node& node); + // Technically not required as the default implementation would trickle down to apply(Node&) anyway, + // but we'll shortcut instead to avoid the chain of virtual function calls + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Geometry& node); + + void applyNode(osg::Node& node); + virtual void visit(osg::Node& node, Controller& ctrl) = 0; }; diff --git a/components/sceneutil/visitor.cpp b/components/sceneutil/visitor.cpp index d147ced7f..74b9be63d 100644 --- a/components/sceneutil/visitor.cpp +++ b/components/sceneutil/visitor.cpp @@ -1,5 +1,7 @@ #include "visitor.hpp" +#include + #include #include @@ -7,14 +9,35 @@ namespace SceneUtil { - void FindByNameVisitor::apply(osg::Group &group) + bool FindByNameVisitor::checkGroup(osg::Group &group) { if (Misc::StringUtils::ciEqual(group.getName(), mNameToFind)) { mFoundNode = &group; - return; + return true; } - traverse(group); + return false; + } + + void FindByNameVisitor::apply(osg::Group &group) + { + if (!checkGroup(group)) + traverse(group); + } + + void FindByNameVisitor::apply(osg::MatrixTransform &node) + { + if (!checkGroup(node)) + traverse(node); + } + + void FindByNameVisitor::apply(osg::Geometry&) + { + } + + void DisableFreezeOnCullVisitor::apply(osg::MatrixTransform &node) + { + traverse(node); } void DisableFreezeOnCullVisitor::apply(osg::Drawable& drw) diff --git a/components/sceneutil/visitor.hpp b/components/sceneutil/visitor.hpp index 751339d02..209f2d9bd 100644 --- a/components/sceneutil/visitor.hpp +++ b/components/sceneutil/visitor.hpp @@ -21,6 +21,11 @@ namespace SceneUtil virtual void apply(osg::Group& group); + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Geometry& node); + + bool checkGroup(osg::Group& group); + std::string mNameToFind; osg::Group* mFoundNode; }; @@ -34,6 +39,8 @@ namespace SceneUtil { } + virtual void apply(osg::MatrixTransform& node); + virtual void apply(osg::Drawable& drw); };