History: MOGRE AnimationBlender
Source of version: 3 (current)
Copy to clipboard
This is a port of the ((AnimationBlender|C++ AnimationBlender class)) to Mogre and C# by ((User:Smernesto|Ernesto Gutiérrez (smernesto))). It was tested with Mogre 0.2.0 (Ogre 1.4.0)
To __blend__ is to fade between two states. In the animation process it allows to create a transition between two animations.
If you have some questions, want to add something or you have some bug fixes please post at this [http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=4758|Forum topic]
{CODE(wrap="1", colors="c#")}//Porting notes:
//* Ported by Ernesto Gutierrez (smernesto) - 02-july-2007
//* Added properties for the public variables
//* Changed the code to the C# coding style
//* Tested with Mogre 0.2.0 (Ogre 1.4.0)
using System;
using Mogre;
namespace Mogre
{
public class AnimationBlender
{
public enum BlendingTransition
{
BlendSwitch, // stop source and start dest
BlendWhileAnimating, // cross fade, blend source animation out while blending destination animation in
BlendThenAnimate // blend source to first frame of dest, when done, start dest anim
}
private Entity mEntity;
private AnimationState mSource;
private AnimationState mTarget;
private BlendingTransition mTransition;
private bool loop;
private float mTimeleft, mDuration;
private bool complete;
public void Blend(string animation, BlendingTransition transition, float duration, bool l)
{
loop = l;
if (transition == BlendingTransition.BlendSwitch)
{
if (mSource != null)
mSource.Enabled = false;
mSource = mEntity.GetAnimationState(animation);
mSource.Enabled = true;
mSource.Weight = 1;
mSource.TimePosition = 0;
mTimeleft = 0;
}
else
{
AnimationState newTarget = mEntity.GetAnimationState(animation);
if (mTimeleft > 0)
{
// oops, weren't finished yet
if (newTarget == mTarget)
{
// nothing to do! (ignoring duration here)
}
else if (newTarget == mSource)
{
// going back to the source state, so let's switch
mSource = mTarget;
mTarget = newTarget;
mTimeleft = mDuration - mTimeleft; // i'm ignoring the new duration here
}
else
{
// ok, newTarget is really new, so either we simply replace the target with this one, or
// we make the target the new source
if (mTimeleft < mDuration * 0.5)
{
// simply replace the target with this one
mTarget.Enabled = false;
mTarget.Weight = 0;
}
else
{
// old target becomes new source
mSource.Enabled = false;
mSource.Weight = 0;
mSource = mTarget;
}
mTarget = newTarget;
mTarget.Enabled = true;
mTarget.Weight = 1.0f - mTimeleft / mDuration;
mTarget.TimePosition = 0;
}
}
else
{
// assert( target == 0, "target should be 0 when not blending" )
// mSource->setEnabled(true);
// mSource->setWeight(1);
mTransition = transition;
mTimeleft = mDuration = duration;
mTarget = newTarget;
mTarget.Enabled = true;
mTarget.Weight = 0;
mTarget.TimePosition = 0;
}
}
}
public void AddTime(float time)
{
if (mSource != null)
{
if (mTimeleft > 0)
{
mTimeleft -= time;
if (mTimeleft < 0)
{
// finish blending
mSource.Enabled = false;
mSource.Weight = 0;
mSource = mTarget;
mSource.Enabled = true;
mSource.Weight = 1;
mTarget = null;
}
else
{
// still blending, advance weights
mSource.Weight = mTimeleft / mDuration;
mTarget.Weight = 1.0f - mTimeleft / mDuration;
if (mTransition == BlendingTransition.BlendWhileAnimating)
mTarget.AddTime(time);
}
}
if (mSource.TimePosition >= mSource.Length)
{
complete = true;
}
else
{
complete = false;
}
mSource.AddTime(time);
mSource.Loop = loop;
}
}
public AnimationBlender(Entity entity)
{
mEntity = entity;
}
public void Init(string animation)
{
AnimationStateSet set = mEntity.AllAnimationStates;
foreach (AnimationState anim in set.GetAnimationStateIterator())
{
anim.Enabled = false;
anim.Weight = 0;
anim.TimePosition = 0;
}
mSource = mEntity.GetAnimationState(animation);
mSource.Enabled = true;
mSource.Weight = 1;
mTimeleft = 0;
mDuration = 1;
mTarget = null;
complete = false;
}
//Properties
public float Progress
{
get { return mTimeleft / mDuration; }
}
public AnimationState Source
{
get { return mSource; }
}
public AnimationState Target
{
get { return mTarget; }
}
public bool Complete
{
get { return complete; }
}
public float TimeLeft
{
get { return mTimeleft; }
}
public float Duration
{
get { return mDuration; }
}
}
}{CODE}