mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Cleanup, refactor, rename AnimBlendControllerBase -> AnimBlendController
This commit is contained in:
parent
42406ed0af
commit
00a7d0281f
9 changed files with 80 additions and 100 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include <osgParticle/ParticleSystem>
|
#include <osgParticle/ParticleSystem>
|
||||||
|
|
||||||
#include <osgAnimation/Bone>
|
#include <osgAnimation/Bone>
|
||||||
|
#include <osgAnimation/UpdateBone>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
|
@ -400,28 +401,25 @@ namespace
|
||||||
|
|
||||||
return lightModel;
|
return lightModel;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
namespace MWRender
|
void assignBoneBlendCallbackRecursive(MWRender::BoneAnimBlendController* controller,
|
||||||
{
|
MWRender::ActiveControllersVector& activeControllers, osg::Node* parent, bool isRoot)
|
||||||
void assignBoneBlendCallbackRecursive(
|
|
||||||
BoneAnimBlendController* controller, ActiveControllersVector& activeControllers, osg::Node* parent, bool isRoot)
|
|
||||||
{
|
{
|
||||||
// Attempt to cast node to an osgAnimation::Bone
|
// Attempt to cast node to an osgAnimation::Bone
|
||||||
osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(parent);
|
if (!isRoot && dynamic_cast<osgAnimation::Bone*>(parent))
|
||||||
if (!isRoot && bone)
|
|
||||||
{
|
{
|
||||||
// Wrapping in a custom callback object allows for nested callback chaining, otherwise it has link to self
|
// Wrapping in a custom callback object allows for nested callback chaining, otherwise it has link to self
|
||||||
// issues we need to share the base BoneAnimBlendController as that contains blending information and is
|
// issues we need to share the base BoneAnimBlendController as that contains blending information and is
|
||||||
// guaranteed to update before
|
// guaranteed to update before
|
||||||
osg::ref_ptr<osg::Callback> cb = new BoneAnimBlendControllerWrapper(controller, bone);
|
osgAnimation::Bone* bone = static_cast<osgAnimation::Bone*>(parent);
|
||||||
|
osg::ref_ptr<osg::Callback> cb = new MWRender::BoneAnimBlendControllerWrapper(controller, bone);
|
||||||
|
|
||||||
// Ensure there is no other AnimBlendController - this can happen when using
|
// Ensure there is no other AnimBlendController - this can happen when using
|
||||||
// multiple animations with different roots, such as NPC animation
|
// multiple animations with different roots, such as NPC animation
|
||||||
osg::Callback* updateCb = bone->getUpdateCallback();
|
osg::Callback* updateCb = bone->getUpdateCallback();
|
||||||
while (updateCb)
|
while (updateCb)
|
||||||
{
|
{
|
||||||
if (updateCb->className() == std::string_view(controller->className()))
|
if (dynamic_cast<MWRender::BoneAnimBlendController*>(updateCb))
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Callback> nextCb = updateCb->getNestedCallback();
|
osg::ref_ptr<osg::Callback> nextCb = updateCb->getNestedCallback();
|
||||||
bone->removeUpdateCallback(updateCb);
|
bone->removeUpdateCallback(updateCb);
|
||||||
|
@ -438,7 +436,7 @@ namespace MWRender
|
||||||
updateCb = bone->getUpdateCallback();
|
updateCb = bone->getUpdateCallback();
|
||||||
while (updateCb)
|
while (updateCb)
|
||||||
{
|
{
|
||||||
if (updateCb->className() == std::string_view("UpdateBone"))
|
if (dynamic_cast<osgAnimation::UpdateBone*>(updateCb))
|
||||||
{
|
{
|
||||||
// Override the immediate callback after the UpdateBone
|
// Override the immediate callback after the UpdateBone
|
||||||
osg::ref_ptr<osg::Callback> lastCb = updateCb->getNestedCallback();
|
osg::ref_ptr<osg::Callback> lastCb = updateCb->getNestedCallback();
|
||||||
|
@ -458,7 +456,10 @@ namespace MWRender
|
||||||
for (unsigned int i = 0; i < group->getNumChildren(); ++i)
|
for (unsigned int i = 0; i < group->getNumChildren(); ++i)
|
||||||
assignBoneBlendCallbackRecursive(controller, activeControllers, group->getChild(i), false);
|
assignBoneBlendCallbackRecursive(controller, activeControllers, group->getChild(i), false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWRender
|
||||||
|
{
|
||||||
class TransparencyUpdater : public SceneUtil::StateSetUpdater
|
class TransparencyUpdater : public SceneUtil::StateSetUpdater
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -777,7 +778,7 @@ namespace MWRender
|
||||||
blendRules
|
blendRules
|
||||||
= mResourceSystem->getAnimBlendRulesManager()->getRules(globalBlendConfigPath, blendConfigPath);
|
= mResourceSystem->getAnimBlendRulesManager()->getRules(globalBlendConfigPath, blendConfigPath);
|
||||||
if (blendRules == nullptr)
|
if (blendRules == nullptr)
|
||||||
Log(Debug::Warning) << "Animation blending files were not found '" << blendConfigPath.value()
|
Log(Debug::Warning) << "Unable to find animation blending rules: '" << blendConfigPath.value()
|
||||||
<< "' or '" << globalBlendConfigPath.value() << "'";
|
<< "' or '" << globalBlendConfigPath.value() << "'";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1087,7 +1088,7 @@ namespace MWRender
|
||||||
template <typename ControllerType, typename NodeType>
|
template <typename ControllerType, typename NodeType>
|
||||||
inline osg::Callback* Animation::handleBlendTransform(osg::ref_ptr<osg::Node> node,
|
inline osg::Callback* Animation::handleBlendTransform(osg::ref_ptr<osg::Node> node,
|
||||||
osg::ref_ptr<SceneUtil::KeyframeController> keyframeController,
|
osg::ref_ptr<SceneUtil::KeyframeController> keyframeController,
|
||||||
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<AnimBlendControllerBase<NodeType>>>& blendControllers,
|
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<AnimBlendController<NodeType>>>& blendControllers,
|
||||||
const AnimBlendStateData& stateData, const osg::ref_ptr<const SceneUtil::AnimBlendRules>& blendRules,
|
const AnimBlendStateData& stateData, const osg::ref_ptr<const SceneUtil::AnimBlendRules>& blendRules,
|
||||||
const AnimState& active)
|
const AnimState& active)
|
||||||
{
|
{
|
||||||
|
@ -1164,7 +1165,8 @@ namespace MWRender
|
||||||
if (active != mStates.end())
|
if (active != mStates.end())
|
||||||
{
|
{
|
||||||
std::shared_ptr<AnimSource> animsrc = active->second.mSource;
|
std::shared_ptr<AnimSource> animsrc = active->second.mSource;
|
||||||
AnimBlendStateData stateData = active->second.asAnimBlendStateData();
|
const AnimBlendStateData stateData
|
||||||
|
= { .mGroupname = active->second.mGroupname, .mStartKey = active->second.mStartKey };
|
||||||
|
|
||||||
for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin();
|
for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin();
|
||||||
it != animsrc->mControllerMap[blendMask].end(); ++it)
|
it != animsrc->mControllerMap[blendMask].end(); ++it)
|
||||||
|
@ -1173,18 +1175,16 @@ namespace MWRender
|
||||||
it->first); // this should not throw, we already checked for the node existing in addAnimSource
|
it->first); // this should not throw, we already checked for the node existing in addAnimSource
|
||||||
|
|
||||||
const bool useSmoothAnims = Settings::game().mSmoothAnimTransitions;
|
const bool useSmoothAnims = Settings::game().mSmoothAnimTransitions;
|
||||||
const bool isNifTransform = dynamic_cast<NifOsg::MatrixTransform*>(node.get()) != nullptr;
|
|
||||||
const bool isBoneTransform = dynamic_cast<osgAnimation::Bone*>(node.get()) != nullptr;
|
|
||||||
|
|
||||||
osg::Callback* callback = it->second->getAsCallback();
|
osg::Callback* callback = it->second->getAsCallback();
|
||||||
if (useSmoothAnims)
|
if (useSmoothAnims)
|
||||||
{
|
{
|
||||||
if (isNifTransform)
|
if (dynamic_cast<NifOsg::MatrixTransform*>(node.get()))
|
||||||
{
|
{
|
||||||
callback = handleBlendTransform<AnimBlendController, NifOsg::MatrixTransform>(node,
|
callback = handleBlendTransform<NifAnimBlendController, NifOsg::MatrixTransform>(node,
|
||||||
it->second, mAnimBlendControllers, stateData, animsrc->mAnimBlendRules, active->second);
|
it->second, mAnimBlendControllers, stateData, animsrc->mAnimBlendRules, active->second);
|
||||||
}
|
}
|
||||||
else if (isBoneTransform)
|
else if (dynamic_cast<osgAnimation::Bone*>(node.get()))
|
||||||
{
|
{
|
||||||
callback
|
callback
|
||||||
= handleBlendTransform<BoneAnimBlendController, osgAnimation::Bone>(node, it->second,
|
= handleBlendTransform<BoneAnimBlendController, osgAnimation::Bone>(node, it->second,
|
||||||
|
@ -1956,7 +1956,7 @@ namespace MWRender
|
||||||
osg::Callback* cb = node->getUpdateCallback();
|
osg::Callback* cb = node->getUpdateCallback();
|
||||||
while (cb)
|
while (cb)
|
||||||
{
|
{
|
||||||
if (dynamic_cast<AnimBlendController*>(cb) || dynamic_cast<BoneAnimBlendController*>(cb)
|
if (dynamic_cast<NifAnimBlendController*>(cb) || dynamic_cast<BoneAnimBlendController*>(cb)
|
||||||
|| dynamic_cast<SceneUtil::KeyframeController*>(cb))
|
|| dynamic_cast<SceneUtil::KeyframeController*>(cb))
|
||||||
{
|
{
|
||||||
foundKeyframeCtrl = true;
|
foundKeyframeCtrl = true;
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
#define GAME_RENDER_ANIMATION_H
|
#define GAME_RENDER_ANIMATION_H
|
||||||
|
|
||||||
#include "animationpriority.hpp"
|
#include "animationpriority.hpp"
|
||||||
|
#include "animblendcontroller.hpp"
|
||||||
#include "blendmask.hpp"
|
#include "blendmask.hpp"
|
||||||
#include "bonegroup.hpp"
|
#include "bonegroup.hpp"
|
||||||
|
|
||||||
#include "../mwworld/movementdirection.hpp"
|
#include "../mwworld/movementdirection.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
#include "animblendcontroller.hpp"
|
|
||||||
#include <components/misc/strings/algorithm.hpp>
|
#include <components/misc/strings/algorithm.hpp>
|
||||||
#include <components/sceneutil/animblendrules.hpp>
|
#include <components/sceneutil/animblendrules.hpp>
|
||||||
#include <components/sceneutil/controller.hpp>
|
#include <components/sceneutil/controller.hpp>
|
||||||
|
@ -170,12 +170,6 @@ namespace MWRender
|
||||||
float getTime() const { return *mTime; }
|
float getTime() const { return *mTime; }
|
||||||
void setTime(float time) { *mTime = time; }
|
void setTime(float time) { *mTime = time; }
|
||||||
bool blendMaskContains(size_t blendMask) const { return (mBlendMask & (1 << blendMask)); }
|
bool blendMaskContains(size_t blendMask) const { return (mBlendMask & (1 << blendMask)); }
|
||||||
AnimBlendStateData asAnimBlendStateData() const
|
|
||||||
{
|
|
||||||
AnimBlendStateData stateData = { .mGroupname = mGroupname, .mStartKey = mStartKey };
|
|
||||||
return stateData;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool shouldLoop() const { return getTime() >= mLoopStopTime && mLoopingEnabled && mLoopCount > 0; }
|
bool shouldLoop() const { return getTime() >= mLoopStopTime && mLoopingEnabled && mLoopCount > 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -207,7 +201,7 @@ namespace MWRender
|
||||||
ActiveControllersVector mActiveControllers;
|
ActiveControllersVector mActiveControllers;
|
||||||
|
|
||||||
// Keep track of the animation controllers for easy access
|
// Keep track of the animation controllers for easy access
|
||||||
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<AnimBlendController>> mAnimBlendControllers;
|
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<NifAnimBlendController>> mAnimBlendControllers;
|
||||||
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<BoneAnimBlendController>> mBoneAnimBlendControllers;
|
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<BoneAnimBlendController>> mBoneAnimBlendControllers;
|
||||||
|
|
||||||
std::shared_ptr<AnimationTime> mAnimationTimePtr[sNumBlendMasks];
|
std::shared_ptr<AnimationTime> mAnimationTimePtr[sNumBlendMasks];
|
||||||
|
@ -315,7 +309,7 @@ namespace MWRender
|
||||||
template <typename ControllerType, typename NodeType>
|
template <typename ControllerType, typename NodeType>
|
||||||
inline osg::Callback* handleBlendTransform(osg::ref_ptr<osg::Node> node,
|
inline osg::Callback* handleBlendTransform(osg::ref_ptr<osg::Node> node,
|
||||||
osg::ref_ptr<SceneUtil::KeyframeController> keyframeController,
|
osg::ref_ptr<SceneUtil::KeyframeController> keyframeController,
|
||||||
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<AnimBlendControllerBase<NodeType>>>& blendControllers,
|
std::map<osg::ref_ptr<osg::Node>, osg::ref_ptr<AnimBlendController<NodeType>>>& blendControllers,
|
||||||
const AnimBlendStateData& stateData, const osg::ref_ptr<const SceneUtil::AnimBlendRules>& blendRules,
|
const AnimBlendStateData& stateData, const osg::ref_ptr<const SceneUtil::AnimBlendRules>& blendRules,
|
||||||
const AnimState& active);
|
const AnimState& active);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "animblendcontroller.hpp"
|
#include "animblendcontroller.hpp"
|
||||||
|
|
||||||
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
#include <osgAnimation/Bone>
|
#include <osgAnimation/Bone>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -89,9 +91,8 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
AnimBlendControllerBase<NodeClass>::AnimBlendControllerBase(
|
AnimBlendController<NodeClass>::AnimBlendController(osg::ref_ptr<SceneUtil::KeyframeController> keyframeTrack,
|
||||||
osg::ref_ptr<SceneUtil::KeyframeController> keyframeTrack, AnimBlendStateData newState,
|
const AnimBlendStateData& newState, osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules)
|
||||||
osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules)
|
|
||||||
: mTimeFactor(0.0f)
|
: mTimeFactor(0.0f)
|
||||||
, mInterpFactor(0.0f)
|
, mInterpFactor(0.0f)
|
||||||
{
|
{
|
||||||
|
@ -99,8 +100,8 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
void AnimBlendControllerBase<NodeClass>::setKeyframeTrack(osg::ref_ptr<SceneUtil::KeyframeController> kft,
|
void AnimBlendController<NodeClass>::setKeyframeTrack(osg::ref_ptr<SceneUtil::KeyframeController> kft,
|
||||||
AnimBlendStateData newState, osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules)
|
const AnimBlendStateData& newState, osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules)
|
||||||
{
|
{
|
||||||
// If animation has changed then start blending
|
// If animation has changed then start blending
|
||||||
if (newState.mGroupname != mAnimState.mGroupname || newState.mStartKey != mAnimState.mStartKey
|
if (newState.mGroupname != mAnimState.mGroupname || newState.mStartKey != mAnimState.mStartKey
|
||||||
|
@ -139,7 +140,7 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
void AnimBlendControllerBase<NodeClass>::gatherRecursiveBoneTransforms(osgAnimation::Bone* bone, bool isRoot)
|
void AnimBlendController<NodeClass>::gatherRecursiveBoneTransforms(osgAnimation::Bone* bone, bool isRoot)
|
||||||
{
|
{
|
||||||
// Incase group traversal encountered something that isnt a bone
|
// Incase group traversal encountered something that isnt a bone
|
||||||
if (!bone)
|
if (!bone)
|
||||||
|
@ -156,7 +157,7 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
void AnimBlendControllerBase<NodeClass>::applyBoneBlend(osgAnimation::Bone* bone)
|
void AnimBlendController<NodeClass>::applyBoneBlend(osgAnimation::Bone* bone)
|
||||||
{
|
{
|
||||||
// If we are done with interpolation then we can safely skip this as the bones are correct
|
// If we are done with interpolation then we can safely skip this as the bones are correct
|
||||||
if (!mInterpActive)
|
if (!mInterpActive)
|
||||||
|
@ -200,7 +201,7 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
void AnimBlendControllerBase<NodeClass>::calculateInterpFactor(float time)
|
void AnimBlendController<NodeClass>::calculateInterpFactor(float time)
|
||||||
{
|
{
|
||||||
if (mBlendDuration != 0)
|
if (mBlendDuration != 0)
|
||||||
mTimeFactor = std::min((time - mBlendStartTime) / mBlendDuration, 1.0f);
|
mTimeFactor = std::min((time - mBlendStartTime) / mBlendDuration, 1.0f);
|
||||||
|
@ -216,7 +217,7 @@ namespace MWRender
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
void AnimBlendControllerBase<NodeClass>::operator()(osgAnimation::Bone* node, osg::NodeVisitor* nv)
|
void AnimBlendController<NodeClass>::operator()(osgAnimation::Bone* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
// HOW THIS WORKS: This callback method is called only for bones with attached keyframe controllers
|
// HOW THIS WORKS: This callback method is called only for bones with attached keyframe controllers
|
||||||
// such as bip01, bip01 spine1 etc. The child bones of these controllers have their own callback wrapper
|
// such as bip01, bip01 spine1 etc. The child bones of these controllers have their own callback wrapper
|
||||||
|
@ -236,11 +237,11 @@ namespace MWRender
|
||||||
if (mInterpActive)
|
if (mInterpActive)
|
||||||
applyBoneBlend(node);
|
applyBoneBlend(node);
|
||||||
|
|
||||||
SceneUtil::NodeCallback<AnimBlendControllerBase<NodeClass>, osgAnimation::Bone*>::traverse(node, nv);
|
SceneUtil::NodeCallback<AnimBlendController<NodeClass>, osgAnimation::Bone*>::traverse(node, nv);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
void AnimBlendControllerBase<NodeClass>::operator()(NifOsg::MatrixTransform* node, osg::NodeVisitor* nv)
|
void AnimBlendController<NodeClass>::operator()(NifOsg::MatrixTransform* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
// HOW THIS WORKS: The actual retrieval of the bone transformation based on animation is done by the
|
// HOW THIS WORKS: The actual retrieval of the bone transformation based on animation is done by the
|
||||||
// KeyframeController (mKeyframeTrack). The KeyframeController retreives time data (playback position) every
|
// KeyframeController (mKeyframeTrack). The KeyframeController retreives time data (playback position) every
|
||||||
|
@ -302,6 +303,6 @@ namespace MWRender
|
||||||
// instantly hide/show objects in which case the scale interpolation is undesirable.
|
// instantly hide/show objects in which case the scale interpolation is undesirable.
|
||||||
node->setScale(*scale);
|
node->setScale(*scale);
|
||||||
|
|
||||||
SceneUtil::NodeCallback<AnimBlendControllerBase<NodeClass>, NifOsg::MatrixTransform*>::traverse(node, nv);
|
SceneUtil::NodeCallback<AnimBlendController<NodeClass>, NifOsg::MatrixTransform*>::traverse(node, nv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include <osgAnimation/Bone>
|
#include <osgAnimation/Bone>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
|
||||||
#include <components/nifosg/matrixtransform.hpp>
|
#include <components/nifosg/matrixtransform.hpp>
|
||||||
#include <components/sceneutil/animblendrules.hpp>
|
#include <components/sceneutil/animblendrules.hpp>
|
||||||
#include <components/sceneutil/controller.hpp>
|
#include <components/sceneutil/controller.hpp>
|
||||||
|
@ -29,28 +28,26 @@ namespace MWRender
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename NodeClass>
|
template <typename NodeClass>
|
||||||
class AnimBlendControllerBase : public SceneUtil::NodeCallback<AnimBlendControllerBase<NodeClass>, NodeClass*>,
|
class AnimBlendController : public SceneUtil::NodeCallback<AnimBlendController<NodeClass>, NodeClass*>,
|
||||||
public SceneUtil::Controller
|
public SceneUtil::Controller
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AnimBlendControllerBase(osg::ref_ptr<SceneUtil::KeyframeController> keyframeTrack, AnimBlendStateData animState,
|
AnimBlendController(osg::ref_ptr<SceneUtil::KeyframeController> keyframeTrack,
|
||||||
osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules);
|
const AnimBlendStateData& animState, osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules);
|
||||||
|
|
||||||
AnimBlendControllerBase() {}
|
AnimBlendController() {}
|
||||||
|
|
||||||
AnimBlendControllerBase(const AnimBlendControllerBase<NodeClass>& copy, const osg::CopyOp&)
|
AnimBlendController(const AnimBlendController& other, const osg::CopyOp&)
|
||||||
: mTimeFactor(0.0f)
|
: AnimBlendController(other.mKeyframeTrack, other.mAnimState, other.mAnimBlendRules)
|
||||||
, mInterpFactor(0.0f)
|
|
||||||
{
|
{
|
||||||
setKeyframeTrack(copy.getKeyframeTrack(), copy.getAnimState(), copy.getBlendRules());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
META_Object(MWRender, AnimBlendControllerBase<NodeClass>)
|
META_Object(MWRender, AnimBlendController<NodeClass>)
|
||||||
|
|
||||||
void operator()(NifOsg::MatrixTransform* node, osg::NodeVisitor* nv);
|
void operator()(NifOsg::MatrixTransform* node, osg::NodeVisitor* nv);
|
||||||
void operator()(osgAnimation::Bone* node, osg::NodeVisitor* nv);
|
void operator()(osgAnimation::Bone* node, osg::NodeVisitor* nv);
|
||||||
|
|
||||||
void setKeyframeTrack(osg::ref_ptr<SceneUtil::KeyframeController> kft, AnimBlendStateData animState,
|
void setKeyframeTrack(osg::ref_ptr<SceneUtil::KeyframeController> kft, const AnimBlendStateData& animState,
|
||||||
osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules);
|
osg::ref_ptr<const SceneUtil::AnimBlendRules> blendRules);
|
||||||
|
|
||||||
osg::Callback* getAsCallback() { return this; }
|
osg::Callback* getAsCallback() { return this; }
|
||||||
|
@ -60,10 +57,6 @@ namespace MWRender
|
||||||
void gatherRecursiveBoneTransforms(osgAnimation::Bone* parent, bool isRoot = true);
|
void gatherRecursiveBoneTransforms(osgAnimation::Bone* parent, bool isRoot = true);
|
||||||
void applyBoneBlend(osgAnimation::Bone* parent);
|
void applyBoneBlend(osgAnimation::Bone* parent);
|
||||||
|
|
||||||
osg::ref_ptr<SceneUtil::KeyframeController> getKeyframeTrack() const { return mKeyframeTrack; }
|
|
||||||
osg::ref_ptr<const SceneUtil::AnimBlendRules> getBlendRules() const { return mAnimBlendRules; }
|
|
||||||
AnimBlendStateData getAnimState() const { return mAnimState; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Easings::EasingFn mEasingFn;
|
Easings::EasingFn mEasingFn;
|
||||||
float mBlendDuration;
|
float mBlendDuration;
|
||||||
|
@ -87,19 +80,29 @@ namespace MWRender
|
||||||
inline void calculateInterpFactor(float time);
|
inline void calculateInterpFactor(float time);
|
||||||
};
|
};
|
||||||
|
|
||||||
using AnimBlendController = AnimBlendControllerBase<NifOsg::MatrixTransform>;
|
using NifAnimBlendController = AnimBlendController<NifOsg::MatrixTransform>;
|
||||||
using BoneAnimBlendController = AnimBlendControllerBase<osgAnimation::Bone>;
|
using BoneAnimBlendController = AnimBlendController<osgAnimation::Bone>;
|
||||||
|
|
||||||
// Assigned to child bones with an instance of AnimBlendControllerBase
|
// Assigned to child bones with an instance of AnimBlendController
|
||||||
class BoneAnimBlendControllerWrapper : public osg::Callback
|
class BoneAnimBlendControllerWrapper : public osg::Callback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BoneAnimBlendControllerWrapper(osg::ref_ptr<BoneAnimBlendController> rootCallback, osg::Node* node)
|
BoneAnimBlendControllerWrapper(osg::ref_ptr<BoneAnimBlendController> rootCallback, osgAnimation::Bone* node)
|
||||||
|
: mRootCallback(rootCallback)
|
||||||
|
, mNode(node)
|
||||||
{
|
{
|
||||||
mRootCallback = rootCallback;
|
|
||||||
mNode = dynamic_cast<osgAnimation::Bone*>(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoneAnimBlendControllerWrapper() {}
|
||||||
|
|
||||||
|
BoneAnimBlendControllerWrapper(const BoneAnimBlendControllerWrapper& copy, const osg::CopyOp&)
|
||||||
|
: mRootCallback(copy.mRootCallback)
|
||||||
|
, mNode(copy.mNode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
META_Object(MWRender, BoneAnimBlendControllerWrapper)
|
||||||
|
|
||||||
bool run(osg::Object* object, osg::Object* data) override
|
bool run(osg::Object* object, osg::Object* data) override
|
||||||
{
|
{
|
||||||
mRootCallback->applyBoneBlend(mNode);
|
mRootCallback->applyBoneBlend(mNode);
|
||||||
|
@ -107,9 +110,6 @@ namespace MWRender
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* libraryName() const override { return "openmw"; }
|
|
||||||
const char* className() const override { return "AnimBlendController"; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
osg::ref_ptr<BoneAnimBlendController> mRootCallback;
|
osg::ref_ptr<BoneAnimBlendController> mRootCallback;
|
||||||
osgAnimation::Bone* mNode;
|
osgAnimation::Bone* mNode;
|
||||||
|
|
|
@ -26,7 +26,6 @@ namespace Resource
|
||||||
|
|
||||||
AnimBlendRulesManager::AnimBlendRulesManager(const VFS::Manager* vfs, double expiryDelay)
|
AnimBlendRulesManager::AnimBlendRulesManager(const VFS::Manager* vfs, double expiryDelay)
|
||||||
: ResourceManager(vfs, expiryDelay)
|
: ResourceManager(vfs, expiryDelay)
|
||||||
, mVfs(vfs)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,27 +57,15 @@ namespace Resource
|
||||||
|
|
||||||
osg::ref_ptr<const AnimBlendRules> AnimBlendRulesManager::loadRules(VFS::Path::NormalizedView path)
|
osg::ref_ptr<const AnimBlendRules> AnimBlendRulesManager::loadRules(VFS::Path::NormalizedView path)
|
||||||
{
|
{
|
||||||
const std::string normalized = VFS::Path::normalizeFilename(path.value());
|
std::optional<osg::ref_ptr<osg::Object>> obj = mCache->getRefFromObjectCacheOrNone(path);
|
||||||
std::optional<osg::ref_ptr<osg::Object>> obj = mCache->getRefFromObjectCacheOrNone(normalized);
|
|
||||||
if (obj.has_value())
|
if (obj.has_value())
|
||||||
{
|
{
|
||||||
return osg::ref_ptr<AnimBlendRules>(static_cast<AnimBlendRules*>(obj->get()));
|
return osg::ref_ptr<AnimBlendRules>(static_cast<AnimBlendRules*>(obj->get()));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
osg::ref_ptr<AnimBlendRules> blendRules = AnimBlendRules::fromFile(mVfs, path);
|
|
||||||
if (blendRules)
|
|
||||||
{
|
|
||||||
// Blend rules were found in VFS, cache them.
|
|
||||||
mCache->addEntryToObjectCache(normalized, blendRules);
|
|
||||||
return blendRules;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No blend rules were found in VFS, cache a nullptr.
|
osg::ref_ptr<AnimBlendRules> blendRules = AnimBlendRules::fromFile(mVFS, path);
|
||||||
osg::ref_ptr<AnimBlendRules> nullRules = nullptr;
|
mCache->addEntryToObjectCache(path.value(), blendRules);
|
||||||
mCache->addEntryToObjectCache(normalized, nullRules);
|
return blendRules;
|
||||||
return nullRules;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimBlendRulesManager::reportStats(unsigned int frameNumber, osg::Stats* stats) const
|
void AnimBlendRulesManager::reportStats(unsigned int frameNumber, osg::Stats* stats) const
|
||||||
|
|
|
@ -27,8 +27,6 @@ namespace Resource
|
||||||
|
|
||||||
private:
|
private:
|
||||||
osg::ref_ptr<const SceneUtil::AnimBlendRules> loadRules(VFS::Path::NormalizedView path);
|
osg::ref_ptr<const SceneUtil::AnimBlendRules> loadRules(VFS::Path::NormalizedView path);
|
||||||
|
|
||||||
const VFS::Manager* mVfs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ namespace SceneUtil
|
||||||
mRules.insert(mRules.end(), rules.begin(), rules.end());
|
mRules.insert(mRules.end(), rules.begin(), rules.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool AnimBlendRules::fitsRuleString(const std::string& str, const std::string& ruleStr) const
|
inline bool AnimBlendRules::fitsRuleString(const std::string_view& str, const std::string_view& ruleStr) const
|
||||||
{
|
{
|
||||||
// A wildcard only supported in the beginning or the end of the rule string in hopes that this will be more
|
// A wildcard only supported in the beginning or the end of the rule string in hopes that this will be more
|
||||||
// performant. And most likely this kind of support is enough.
|
// performant. And most likely this kind of support is enough.
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace SceneUtil
|
||||||
private:
|
private:
|
||||||
std::vector<BlendRule> mRules;
|
std::vector<BlendRule> mRules;
|
||||||
|
|
||||||
inline bool fitsRuleString(const std::string& str, const std::string& ruleStr) const;
|
inline bool fitsRuleString(const std::string_view& str, const std::string_view& ruleStr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,20 +187,20 @@ namespace SceneUtil
|
||||||
mgr->addWrapper(new GeometrySerializer);
|
mgr->addWrapper(new GeometrySerializer);
|
||||||
|
|
||||||
// ignore the below for now to avoid warning spam
|
// ignore the below for now to avoid warning spam
|
||||||
const char* ignore[] = { "Debug::DebugDrawer", "AnimBlendControllerBase<NifOsg::MatrixTransform>",
|
const char* ignore[] = { "Debug::DebugDrawer", "MWRender::AnimBlendController<NifOsg::MatrixTransform>",
|
||||||
"AnimBlendControllerBase<osgAnimation::Bone>", "MWRender::PtrHolder", "Resource::TemplateRef",
|
"MWRender::AnimBlendController<osgAnimation::Bone>", "MWRender::BoneAnimBlendControllerWrapper",
|
||||||
"Resource::TemplateMultiRef", "SceneUtil::CompositeStateSetUpdater", "SceneUtil::UBOManager",
|
"MWRender::PtrHolder", "Resource::TemplateRef", "Resource::TemplateMultiRef",
|
||||||
"SceneUtil::LightListCallback", "SceneUtil::LightManagerUpdateCallback",
|
"SceneUtil::CompositeStateSetUpdater", "SceneUtil::UBOManager", "SceneUtil::LightListCallback",
|
||||||
"SceneUtil::FFPLightStateAttribute", "SceneUtil::UpdateRigBounds", "SceneUtil::UpdateRigGeometry",
|
"SceneUtil::LightManagerUpdateCallback", "SceneUtil::FFPLightStateAttribute",
|
||||||
"SceneUtil::LightSource", "SceneUtil::DisableLight", "SceneUtil::MWShadowTechnique",
|
"SceneUtil::UpdateRigBounds", "SceneUtil::UpdateRigGeometry", "SceneUtil::LightSource",
|
||||||
"SceneUtil::TextKeyMapHolder", "Shader::AddedState", "Shader::RemovedAlphaFunc",
|
"SceneUtil::DisableLight", "SceneUtil::MWShadowTechnique", "SceneUtil::TextKeyMapHolder",
|
||||||
"NifOsg::FlipController", "NifOsg::KeyframeController", "NifOsg::Emitter",
|
"Shader::AddedState", "Shader::RemovedAlphaFunc", "NifOsg::FlipController",
|
||||||
"NifOsg::ParticleColorAffector", "NifOsg::ParticleSystem", "NifOsg::GravityAffector",
|
"NifOsg::KeyframeController", "NifOsg::Emitter", "NifOsg::ParticleColorAffector",
|
||||||
"NifOsg::ParticleBomb", "NifOsg::GrowFadeAffector", "NifOsg::InverseWorldMatrix",
|
"NifOsg::ParticleSystem", "NifOsg::GravityAffector", "NifOsg::ParticleBomb", "NifOsg::GrowFadeAffector",
|
||||||
"NifOsg::StaticBoundingBoxCallback", "NifOsg::GeomMorpherController", "NifOsg::UpdateMorphGeometry",
|
"NifOsg::InverseWorldMatrix", "NifOsg::StaticBoundingBoxCallback", "NifOsg::GeomMorpherController",
|
||||||
"NifOsg::UVController", "NifOsg::VisController", "osgMyGUI::Drawable", "osg::DrawCallback",
|
"NifOsg::UpdateMorphGeometry", "NifOsg::UVController", "NifOsg::VisController", "osgMyGUI::Drawable",
|
||||||
"osg::UniformBufferObject", "osgOQ::ClearQueriesCallback", "osgOQ::RetrieveQueriesCallback",
|
"osg::DrawCallback", "osg::UniformBufferObject", "osgOQ::ClearQueriesCallback",
|
||||||
"osg::DummyObject" };
|
"osgOQ::RetrieveQueriesCallback", "osg::DummyObject" };
|
||||||
for (size_t i = 0; i < sizeof(ignore) / sizeof(ignore[0]); ++i)
|
for (size_t i = 0; i < sizeof(ignore) / sizeof(ignore[0]); ++i)
|
||||||
{
|
{
|
||||||
mgr->addWrapper(makeDummySerializer(ignore[i]));
|
mgr->addWrapper(makeDummySerializer(ignore[i]));
|
||||||
|
|
Loading…
Reference in a new issue