From 72e5043eda98e95cdce973e027e27f69829cac2f Mon Sep 17 00:00:00 2001 From: Capostrophic Date: Thu, 14 May 2020 23:43:01 +0300 Subject: [PATCH] CopyRigVisitor fixes Make sure it copies all relevant drawable parent nodes (e.g. including the node with the environment map effect) Make sure it doesn't copy nodes multiple times --- CHANGELOG.md | 1 + components/sceneutil/attach.cpp | 35 ++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba33d9392..434b45fb33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Bug #5369: Spawnpoint in the Grazelands doesn't produce oversized creatures Bug #5370: Opening an unlocked but trapped door uses the key Bug #5400: Editor: Verifier checks race of non-skin bodyparts + Bug #5415: Environment maps in ebony cuirass and HiRez Armors Indoril cuirass don't work Bug #5416: Junk non-node records before the root node are not handled gracefully Feature #5362: Show the soul gems' trapped soul in count dialog diff --git a/components/sceneutil/attach.cpp b/components/sceneutil/attach.cpp index 5126a37764..b5e5d38444 100644 --- a/components/sceneutil/attach.cpp +++ b/components/sceneutil/attach.cpp @@ -45,23 +45,26 @@ namespace SceneUtil virtual void apply(osg::Drawable& drawable) { - std::string lowerName = Misc::StringUtils::lowerCase(drawable.getName()); - if ((lowerName.size() >= mFilter.size() && lowerName.compare(0, mFilter.size(), mFilter) == 0) - || (lowerName.size() >= mFilter2.size() && lowerName.compare(0, mFilter2.size(), mFilter2) == 0)) + if (!filterMatches(drawable.getName())) + return; + + osg::Node* node = &drawable; + if (!node) + return; + while (node->getNumParents()) { - osg::Node* node = &drawable; - while (node && node->getNumParents() && !node->getStateSet()) - node = node->getParent(0); - if (node) - mToCopy.push_back(node); + osg::Group* parent = node->getParent(0); + if (!parent || !filterMatches(parent->getName())) + break; + node = parent; } + mToCopy.emplace(node); } void doCopy() { - for (std::vector >::iterator it = mToCopy.begin(); it != mToCopy.end(); ++it) + for (const osg::ref_ptr& node : mToCopy) { - osg::ref_ptr node = *it; if (node->getNumParents() > 1) Log(Debug::Error) << "Error CopyRigVisitor: node has multiple parents"; while (node->getNumParents()) @@ -73,8 +76,16 @@ namespace SceneUtil } private: - typedef std::vector > NodeVector; - NodeVector mToCopy; + + bool filterMatches(const std::string& name) const + { + std::string lowerName = Misc::StringUtils::lowerCase(name); + return (lowerName.size() >= mFilter.size() && lowerName.compare(0, mFilter.size(), mFilter) == 0) + || (lowerName.size() >= mFilter2.size() && lowerName.compare(0, mFilter2.size(), mFilter2) == 0); + } + + using NodeSet = std::set>; + NodeSet mToCopy; osg::ref_ptr mParent; std::string mFilter;