From 45d68487f045458b083bc8c154cb283e35a5faad Mon Sep 17 00:00:00 2001 From: funto66 Date: Tue, 22 Oct 2013 13:31:10 +0000 Subject: [PATCH] Add animation strength parameter control for skeletal animations to Irrlicht git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14285 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- lib/irrlicht/include/IAnimatedMeshSceneNode.h | 8 ++++++++ lib/irrlicht/include/ISkinnedMesh.h | 2 +- .../Irrlicht/CAnimatedMeshSceneNode.cpp | 19 +++++++++++++++++-- .../source/Irrlicht/CAnimatedMeshSceneNode.h | 10 ++++++++++ lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp | 17 ++++++++++++----- lib/irrlicht/source/Irrlicht/CSkinnedMesh.h | 4 ++-- 6 files changed, 50 insertions(+), 10 deletions(-) diff --git a/lib/irrlicht/include/IAnimatedMeshSceneNode.h b/lib/irrlicht/include/IAnimatedMeshSceneNode.h index 84d25a2aa..6cc125cd6 100644 --- a/lib/irrlicht/include/IAnimatedMeshSceneNode.h +++ b/lib/irrlicht/include/IAnimatedMeshSceneNode.h @@ -86,6 +86,14 @@ namespace scene /** \return Frames per second played. */ virtual f32 getAnimationSpeed() const =0; + //! Sets the animation strength (how important the animation is) + /** \param strength: The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */ + virtual void setAnimationStrength(f32 strength) =0; + + //! Gets the animation strength (how important the animation is) + /** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */ + virtual f32 getAnimationStrength() const =0; + //! Creates shadow volume scene node as child of this node. /** The shadow can be rendered using the ZPass or the zfail method. ZPass is a little bit faster because the shadow volume diff --git a/lib/irrlicht/include/ISkinnedMesh.h b/lib/irrlicht/include/ISkinnedMesh.h index 03f5016fb..93dbec801 100644 --- a/lib/irrlicht/include/ISkinnedMesh.h +++ b/lib/irrlicht/include/ISkinnedMesh.h @@ -69,7 +69,7 @@ namespace scene virtual void animateMesh(f32 frame, f32 blend)=0; //! Preforms a software skin on this mesh based of joint positions - virtual void skinMesh() = 0; + virtual void skinMesh(f32 strength=1.f) = 0; //! converts the vertex type of all meshbuffers to tangents. /** E.g. used for bump mapping. */ diff --git a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp index a9f1276be..05dcacb05 100644 --- a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp +++ b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.cpp @@ -33,7 +33,7 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh, const core::vector3df& scale) : IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), StartFrame(0), EndFrame(0), FramesPerSecond(0.025f), - CurrentFrameNr(0.f), LastTimeMs(0), + CurrentFrameNr(0.f), AnimationStrength(1.f), LastTimeMs(0), TransitionTime(0), Transiting(0.f), TransitingBlend(0.f), JointMode(EJUOR_NONE), JointsUsed(false), Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(false), @@ -210,7 +210,7 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame() skinnedMesh->animateMesh(getFrameNr(), 1.0f); // Update the skinned mesh for the current joint transforms. - skinnedMesh->skinMesh(); + skinnedMesh->skinMesh(AnimationStrength); if (JointMode == EJUOR_READ)//read from mesh { @@ -516,6 +516,21 @@ f32 CAnimatedMeshSceneNode::getAnimationSpeed() const } +//! Sets the animation strength (how important the animation is) +/** \param strength: The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */ +void CAnimatedMeshSceneNode::setAnimationStrength(f32 strength) +{ + AnimationStrength = strength; +} + +//! Gets the animation strength (how important the animation is) +/** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */ +f32 CAnimatedMeshSceneNode::getAnimationStrength() const +{ + return AnimationStrength; +} + + //! returns the axis aligned bounding box of this node const core::aabbox3d& CAnimatedMeshSceneNode::getBoundingBox() const { diff --git a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h index 522393d6e..f2c44f432 100644 --- a/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h +++ b/lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h @@ -66,6 +66,14 @@ namespace scene //! gets the speed with which the animation is played virtual f32 getAnimationSpeed() const; + //! Sets the animation strength (how important the animation is) + /** \param strength: The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */ + virtual void setAnimationStrength(f32 strength); + + //! Gets the animation strength (how important the animation is) + /** \return The importance of the animation: 1.f keeps the original animation, 0.f is no animation. */ + virtual f32 getAnimationStrength() const; + //! returns the material based on the zero based index i. To get the amount //! of materials used by this scene node, use getMaterialCount(). //! This function is needed for inserting the node into the scene hirachy on a @@ -183,6 +191,8 @@ namespace scene f32 FramesPerSecond; f32 CurrentFrameNr; + f32 AnimationStrength; + u32 LastTimeMs; u32 TransitionTime; //Transition time in millisecs f32 Transiting; //is mesh transiting (plus cache of TransitionTime) diff --git a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp index e1ab5a520..bb4a50474 100644 --- a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp +++ b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.cpp @@ -445,7 +445,7 @@ void CSkinnedMesh::getFrameData(f32 frame, SJoint *joint, //-------------------------------------------------------------------------- //! Preforms a software skin on this mesh based of joint positions -void CSkinnedMesh::skinMesh() +void CSkinnedMesh::skinMesh(f32 strength) { if (!HasAnimation || SkinnedLastFrame) return; @@ -478,7 +478,7 @@ void CSkinnedMesh::skinMesh() //skin starting with the root joints for (i=0; isize(); ++i) (*SkinningBuffers)[i]->setDirty(EBT_VERTEX); @@ -486,8 +486,7 @@ void CSkinnedMesh::skinMesh() updateBoundingBox(); } - -void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint) +void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint, f32 strength) { if (joint->Weights.size()) { @@ -510,6 +509,14 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint) if (AnimateNormals) jointVertexPull.rotateVect(thisNormalMove, weight.StaticNormal); + // Apply animation strength + if(strength != 1.f) + { + thisVertexMove = core::lerp(weight.StaticPos, thisVertexMove, strength); + if(AnimateNormals) + thisNormalMove = core::lerp(weight.StaticNormal, thisNormalMove, strength); + } + if (! (*(weight.Moved)) ) { *(weight.Moved) = true; @@ -537,7 +544,7 @@ void CSkinnedMesh::skinJoint(SJoint *joint, SJoint *parentJoint) //Skin all children for (u32 j=0; jChildren.size(); ++j) - skinJoint(joint->Children[j], joint); + skinJoint(joint->Children[j], joint, strength); } diff --git a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h index cb3665ca8..564693c84 100644 --- a/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h +++ b/lib/irrlicht/source/Irrlicht/CSkinnedMesh.h @@ -52,7 +52,7 @@ namespace scene virtual void animateMesh(f32 frame, f32 blend); //! Preforms a software skin on this mesh based of joint positions - virtual void skinMesh(); + virtual void skinMesh(f32 strength=1.f); //! returns amount of mesh buffers. virtual u32 getMeshBufferCount() const; @@ -176,7 +176,7 @@ private: void calculateGlobalMatrices(SJoint *Joint,SJoint *ParentJoint); - void skinJoint(SJoint *Joint, SJoint *ParentJoint); + void skinJoint(SJoint *Joint, SJoint *ParentJoint, f32 strength=1.f); void calculateTangents(core::vector3df& normal, core::vector3df& tangent, core::vector3df& binormal,