#region File Description
//-----------------------------------------------------------------------------
// AnimationBinder.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using RobotGameData.Helper;
#endregion
namespace RobotGameData.GameObject
{
///
/// This class calculates the animation key frame for the bones of character
/// with time flow.
/// Each character bone corresponds to each AnimtionBinder and each has
/// key frame for an animation.
/// Therefore, in order to do the animation blend,
/// two key frame values of AnimationBinder need to be combined.
///
public class AnimationBinder
{
#region Fields
AnimPlayMode playMode = AnimPlayMode.Repeat;
float localTime = 0.0f;
float timeScaleFactor = 1.0f;
KeyFrameSequence keyFrameSequence = null;
#endregion
#region Properties
public KeyFrameSequence KeyFrameSequence { get { return keyFrameSequence; } }
public AnimPlayMode PlayMode { get { return playMode; } }
public float LocalTime { get { return localTime; } }
public float Duration { get { return KeyFrameSequence.Duration; } }
public float ScaleFactor { get { return timeScaleFactor; } }
public bool IsPlayDone { get { return (LocalTime >= Duration); } }
#endregion
///
/// sets the mode of the animation play.
///
/// animation mode
public void SetPlayMode(AnimPlayMode mode)
{
playMode = mode;
}
///
/// sets the animation’s local time.
///
public void SetTime(float time)
{
localTime = time;
}
///
/// sets the time flow of animation.
/// If the value is bigger than 1.0, the animate speed becomes faster.
/// If lower than 1.0, the animate speed becomes lower.
///
/// time scale factor
public void SetTimeScaleFactor(float scaleFactor)
{
timeScaleFactor = scaleFactor;
}
///
/// sets the animation key frame structure.
///
public void SetKeyFrameSequence(KeyFrameSequence keyFrame)
{
keyFrameSequence = keyFrame;
}
///
/// binds the animation key frame.
///
/// Animation key frame sequence
/// Start time of the animaton
/// Time scale of the animaton
/// Play mode of the animaton
public void BindKeyFrameSequence(KeyFrameSequence keyFrame,
float startTime,
float timeScaleFactor,
AnimPlayMode mode)
{
SetKeyFrameSequence(keyFrame);
SetTime(startTime);
SetTimeScaleFactor(timeScaleFactor);
SetPlayMode(mode);
}
///
/// Initialize members
///
public void Initialize()
{
SetKeyFrameSequence(null);
SetTime(0.0f);
SetTimeScaleFactor(1.0f);
SetPlayMode(AnimPlayMode.Repeat);
}
///
/// Copies to target AnimationBinder
///
/// target AnimationBinder
public void CopyTo(AnimationBinder target)
{
target.SetKeyFrameSequence(KeyFrameSequence);
target.SetTime(LocalTime);
target.SetTimeScaleFactor(ScaleFactor);
target.SetPlayMode(PlayMode);
}
///
/// calculates the key frame of the animation of the specified time.
///
/// animation time
/// animation key frame
public KeyFrame GetKeyFrame(float time)
{
if (KeyFrameSequence == null)
{
throw new InvalidOperationException("Sequence is not set.");
}
// Don't do anything if the timeScaleFactor is 0. (default scale is 1.0)
if (ScaleFactor != 0.0f)
{
// Accumulate animation local time
localTime += (float)(ScaleFactor * time);
switch (PlayMode)
{
case AnimPlayMode.Once: // Just play once
{
if (localTime > KeyFrameSequence.Duration)
localTime = KeyFrameSequence.Duration;
}
break;
case AnimPlayMode.Repeat: // Play looping
{
// Calculate time remainder after local time looping
if (localTime > Duration)
localTime = HelperMath.CalculateModulo(localTime,
KeyFrameSequence.Duration);
}
break;
default:
throw new NotSupportedException("Not supported play mode");
}
return KeyFrameSequence.GetInterpolateKeyFrame(localTime, PlayMode);
}
return new KeyFrame();
}
///
/// calculates the key frame of the animation of the specified time.
///
/// animation time
/// Matrix of the animation key frame
public Matrix GetKeyFrameMatrix(float time)
{
if (KeyFrameSequence == null)
{
throw new InvalidOperationException("Sequence is not set.");
}
// Don't do anything if the timeScaleFactor is 0. (default scale is 1.0)
if (ScaleFactor != 0.0f)
{
// Accumulate animation local time
localTime += (float)(ScaleFactor * time);
switch (PlayMode)
{
case AnimPlayMode.Once: // Just play once
{
if (localTime > KeyFrameSequence.Duration)
localTime = KeyFrameSequence.Duration;
}
break;
case AnimPlayMode.Repeat: // Play looping
{
// Calculate time remainder after local time looping
if (localTime > Duration)
localTime = HelperMath.CalculateModulo(localTime,
KeyFrameSequence.Duration);
}
break;
default:
throw new NotSupportedException("Not supported play mode");
}
return KeyFrameSequence.GetInterpolateMatrix(localTime, PlayMode);
}
return Matrix.Identity;
}
}
}