From ead73fce312a215374fecde6f401761b87f7e793 Mon Sep 17 00:00:00 2001 From: Wolfgang Lieff Date: Tue, 29 Mar 2022 21:47:37 +0200 Subject: [PATCH] initial NiFltAnimationNode support --- apps/openmw/mwrender/objectpaging.cpp | 13 +++++++++++++ components/nif/niffile.cpp | 1 + components/nif/node.hpp | 11 +++++++++++ components/nif/record.hpp | 1 + components/nifosg/nifloader.cpp | 19 +++++++++++++++++++ components/sceneutil/optimizer.cpp | 16 +++++++++++++++- components/sceneutil/optimizer.hpp | 2 ++ 7 files changed, 62 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 4748491dd4..4865f1088e 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,13 @@ namespace MWRender n->setDataVariance(osg::Object::STATIC); return n; } + if (const osg::Sequence* sq = dynamic_cast(node)) + { + osg::Group* n = new osg::Group; + n->addChild(operator()(sq->getChild(sq->getValue()))); + n->setDataVariance(osg::Object::STATIC); + return n; + } mNodePath.push_back(node); @@ -301,6 +309,11 @@ namespace MWRender traverse(*lod->getChild(i)); return; } + if (osg::Sequence* sq = dynamic_cast(&node)) + { + traverse(*sq->getChild(sq->getValue())); + return; + } traverse(node); } diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 0a1acde5b5..57d1ce6457 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -36,6 +36,7 @@ static std::map makeFactory() {"NiNode" , &construct }, {"NiSwitchNode" , &construct }, {"NiLODNode" , &construct }, + {"NiFltAnimationNode" , &construct }, {"AvoidNode" , &construct }, {"NiCollisionSwitch" , &construct }, {"NiBSParticleNode" , &construct }, diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 34ac12e490..6452e2b8af 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -431,6 +431,17 @@ struct NiLODNode : public NiSwitchNode } }; +struct NiFltAnimationNode : public NiSwitchNode +{ + float Interval; + + void read(NIFStream *nif) override + { + NiSwitchNode::read(nif); + Interval = nif->getFloat(); + } +}; + // Abstract struct NiAccumulator : Record { diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 133c393ab5..37084af44e 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -38,6 +38,7 @@ enum RecordType RC_NiNode, RC_NiSwitchNode, RC_NiLODNode, + RC_NiFltAnimationNode, RC_NiBillboardNode, RC_AvoidNode, RC_NiCollisionSwitch, diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 3007bc6cf2..9d66d3f4b6 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -416,6 +417,17 @@ namespace NifOsg return switchNode; } + static osg::ref_ptr handleSequenceNode(const Nif::NiFltAnimationNode* niFltAnimationNode) + { + osg::ref_ptr sequenceNode (new osg::Sequence); + sequenceNode->setName(niFltAnimationNode->name); + sequenceNode->setDefaultTime(niFltAnimationNode->Interval); + sequenceNode->setInterval(osg::Sequence::LOOP, 0,-1); + sequenceNode->setDuration( -1.0f, -1); + sequenceNode->setMode(osg::Sequence::START); + return sequenceNode; + } + osg::ref_ptr handleSourceTexture(const Nif::NiSourceTexture* st, Resource::ImageManager* imageManager) { if (!st) @@ -711,6 +723,13 @@ namespace NifOsg node->addChild(lodNode); currentNode = lodNode; } + else if (nifNode->recType == Nif::RC_NiFltAnimationNode) + { + const Nif::NiFltAnimationNode* niFltAnimationNode = static_cast(nifNode); + osg::ref_ptr sequenceNode = handleSequenceNode(niFltAnimationNode); + node->addChild(sequenceNode); + currentNode = sequenceNode; + } const Nif::NiNode *ninode = dynamic_cast(nifNode); if(ninode) diff --git a/components/sceneutil/optimizer.cpp b/components/sceneutil/optimizer.cpp index 748ceee952..00e113afb9 100644 --- a/components/sceneutil/optimizer.cpp +++ b/components/sceneutil/optimizer.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -845,7 +846,7 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes() ++pitr) { osg::Group* parent = *pitr; - if (!parent->asSwitch() && !dynamic_cast(parent)) + if (!parent->asSwitch() && !dynamic_cast(parent) && !dynamic_cast(parent)) { parent->removeChild(nodeToRemove.get()); if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent); @@ -887,6 +888,13 @@ void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Switch& switchNode) traverse(*switchNode.getChild(i)); } +void Optimizer::RemoveRedundantNodesVisitor::apply(osg::Sequence& sequenceNode) +{ + // We should keep all sequence child nodes since they reflect different sequence states. + for (unsigned int i=0; i