From 2c38e337ae78d620ec1af72f11b29efb59f6eb0d Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 23 Jan 2019 21:01:54 +0400 Subject: [PATCH] Support NiSwitchNode (feature #4812) --- CHANGELOG.md | 1 + components/nifosg/nifloader.cpp | 25 +++++++++++++++++++++++++ components/sceneutil/optimizer.cpp | 13 +++++++++++++ components/sceneutil/optimizer.hpp | 2 ++ 4 files changed, 41 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fda600fc..31e086842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Feature #3610: Option to invert X axis Feature #4673: Weapon sheathing Feature #4730: Native animated containers support + Feature #4812: Support NiSwitchNode Task #4686: Upgrade media decoder to a more current FFmpeg API 0.45.0 diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 08f6eb96c..0ed485862 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -335,6 +336,13 @@ namespace NifOsg return lod; } + osg::ref_ptr handleSwitchNode(const Nif::NiSwitchNode* niSwitchNode) + { + osg::ref_ptr switchNode (new osg::Switch); + switchNode->setNewChildDefaultValue(false); + return switchNode; + } + osg::ref_ptr handleSourceTexture(const Nif::NiSourceTexture* st, Resource::ImageManager* imageManager) { if (!st) @@ -593,6 +601,23 @@ namespace NifOsg node = lod; } + if (nifNode->recType == Nif::RC_NiSwitchNode) + { + const Nif::NiSwitchNode* niSwitchNode = static_cast(nifNode); + osg::ref_ptr switchNode = handleSwitchNode(niSwitchNode); + node->addChild(switchNode); + const Nif::NodeList &children = niSwitchNode->children; + for(size_t i = 0;i < children.length();++i) + { + if(!children[i].empty()) + handleNode(children[i].getPtr(), switchNode, imageManager, boundTextures, animflags, skipMeshes, hasMarkers, isAnimated, textKeys, rootNode); + } + + // show only first child by default + switchNode->setSingleChildOn(0); + return switchNode; + } + const Nif::NiNode *ninode = dynamic_cast(nifNode); if(ninode) { diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp index 5d50c369d..f2717fea2 100644 --- a/components/sceneutil/optimizer.cpp +++ b/components/sceneutil/optimizer.cpp @@ -807,6 +807,13 @@ void Optimizer::RemoveRedundantNodesVisitor::apply(osg::LOD& lod) traverse(*lod.getChild(i)); } +void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Switch& switchNode) +{ + // We should keep all switch child nodes since they reflect different switch states. + for (unsigned int i=0; i