#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; } } }