From e125308dd87d84ced535eb762d09c6c308d078e0 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sun, 8 Aug 2021 09:06:01 +0300 Subject: [PATCH] Force assign head animation timer (bug #4389) --- CHANGELOG.md | 1 + apps/openmw/mwrender/actoranimation.cpp | 2 +- apps/openmw/mwrender/npcanimation.cpp | 16 ++++++++++------ components/sceneutil/controller.cpp | 15 +++++++++++++++ components/sceneutil/controller.hpp | 12 +++++++++++- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c491cb83c0..461afc892e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes Bug #3905: Great House Dagoth issues Bug #4203: Resurrecting an actor should close the loot GUI + Bug #4389: NPC's lips do not move if his head model has the NiBSAnimationNode root node Bug #4602: Robert's Bodies: crash inside createInstance() Bug #4700: Editor: Incorrect command implementation Bug #4744: Invisible particles must still be processed diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index 7706f7d7f1..c8607cd97b 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -335,7 +335,7 @@ void ActorAnimation::resetControllers(osg::Node* node) std::shared_ptr src; src.reset(new NullAnimationTime); - SceneUtil::AssignControllerSourcesVisitor removeVisitor(src); + SceneUtil::ForceControllerSourcesVisitor removeVisitor(src); node->accept(removeVisitor); } diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 0d6c21c308..7031b5a02b 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -837,14 +837,18 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g } } } + SceneUtil::ForceControllerSourcesVisitor assignVisitor(src); + node->accept(assignVisitor); } - else if (type == ESM::PRT_Weapon) - src = mWeaponAnimationTime; else - src.reset(new NullAnimationTime); - - SceneUtil::AssignControllerSourcesVisitor assignVisitor(src); - node->accept(assignVisitor); + { + if (type == ESM::PRT_Weapon) + src = mWeaponAnimationTime; + else + src.reset(new NullAnimationTime); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(src); + node->accept(assignVisitor); + } } return true; diff --git a/components/sceneutil/controller.cpp b/components/sceneutil/controller.cpp index dfc72918aa..2c7507d0a3 100644 --- a/components/sceneutil/controller.cpp +++ b/components/sceneutil/controller.cpp @@ -121,6 +121,21 @@ namespace SceneUtil ctrl.setSource(mToAssign); } + ForceControllerSourcesVisitor::ForceControllerSourcesVisitor() + : AssignControllerSourcesVisitor() + { + } + + ForceControllerSourcesVisitor::ForceControllerSourcesVisitor(std::shared_ptr toAssign) + : AssignControllerSourcesVisitor(toAssign) + { + } + + void ForceControllerSourcesVisitor::visit(osg::Node&, Controller &ctrl) + { + ctrl.setSource(mToAssign); + } + FindMaxControllerLengthVisitor::FindMaxControllerLengthVisitor() : SceneUtil::ControllerVisitor() , mMaxLength(0) diff --git a/components/sceneutil/controller.hpp b/components/sceneutil/controller.hpp index 2656d654e1..6ef800f05b 100644 --- a/components/sceneutil/controller.hpp +++ b/components/sceneutil/controller.hpp @@ -85,10 +85,20 @@ namespace SceneUtil /// By default assigns the ControllerSource passed to the constructor of this class if no ControllerSource is assigned to that controller yet. void visit(osg::Node& node, Controller& ctrl) override; - private: + protected: std::shared_ptr mToAssign; }; + class ForceControllerSourcesVisitor : public AssignControllerSourcesVisitor + { + public: + ForceControllerSourcesVisitor(); + ForceControllerSourcesVisitor(std::shared_ptr toAssign); + + /// Assign the wanted ControllerSource even if one is already assigned to the controller. + void visit(osg::Node& node, Controller& ctrl) override; + }; + /// Finds the maximum of all controller functions in the given scene graph class FindMaxControllerLengthVisitor : public ControllerVisitor {