#ifndef OPENMW_MWRENDER_ANIMBLENDCONTROLLER_H #define OPENMW_MWRENDER_ANIMBLENDCONTROLLER_H #include #include #include #include #include #include #include #include #include #include #include namespace MWRender { namespace Easings { typedef float (*EasingFn)(float); } struct AnimBlendStateData { std::string mGroupname; std::string mStartKey; }; template class AnimBlendControllerBase : public SceneUtil::NodeCallback, NodeClass*>, public SceneUtil::Controller { public: AnimBlendControllerBase(osg::ref_ptr keyframeTrack, AnimBlendStateData animState, osg::ref_ptr blendRules); void operator()(NifOsg::MatrixTransform* node, osg::NodeVisitor* nv); void operator()(osgAnimation::Bone* node, osg::NodeVisitor* nv); void setKeyframeTrack(osg::ref_ptr kft, AnimBlendStateData animState, osg::ref_ptr blendRules); osg::Callback* getAsCallback() { return this; } bool getBlendTrigger() const { return mBlendTrigger; } void gatherRecursiveBoneTransforms(osgAnimation::Bone* parent, bool isRoot = true); void applyBoneBlend(osgAnimation::Bone* parent); const char* libraryName() const override { return "openmw"; } const char* className() const override { return "AnimBlendController"; } protected: osg::ref_ptr mKeyframeTrack; inline void calculateInterpFactor(float time); private: Easings::EasingFn mEasingFn; float mBlendDuration; bool mBlendTrigger = false; float mBlendStartTime; osg::Quat mBlendStartRot; osg::Vec3f mBlendStartTrans; float mBlendStartScale; float mTimeFactor; float mInterpFactor; bool mInterpActive; AnimBlendStateData mAnimState; osg::ref_ptr mAnimBlendRules; std::unordered_map mBlendBoneTransforms; }; typedef AnimBlendControllerBase AnimBlendController; typedef AnimBlendControllerBase BoneAnimBlendController; // Assigned to child bones with an instance of AnimBlendControllerBase class BoneAnimBlendControllerWrapper : public osg::Callback { public: BoneAnimBlendControllerWrapper(osg::ref_ptr rootCallback, osg::Node* node) { mRootCallback = rootCallback; mNode = dynamic_cast(node); } bool run(osg::Object* object, osg::Object* data) override { mRootCallback->applyBoneBlend(mNode); traverse(object, data); return true; } const char* libraryName() const override { return "openmw"; } const char* className() const override { return "AnimBlendController"; } private: osg::ref_ptr mRootCallback; osgAnimation::Bone* mNode; }; } #endif