#region File Description
//-----------------------------------------------------------------------------
// KeyFrameTable.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;
#endregion
namespace RobotGameData.ParticleSystem
{
///
/// this structure has a key value which varies along time.
///
[Serializable]
public class KeyFrameTable
{
#region Enum Interpolation
public enum Interpolation
{
///
/// no interpolate
///
None,
///
/// interpolate using Lerp
///
Lerp,
///
/// interpolate using Slerp
///
Slerp,
///
/// interpolate using Spline
///
Spline,
};
#endregion
#region Fields
public int Count = 0;
public bool IsFixedInterval = true;
public List Table = null;
public List Time = null;
// Volatile Members
float step = 0.0f;
#endregion
///
/// Initialize members
///
public void Initialize()
{
if (Count == 0)
step = 0.0f;
else
step = 1.0f / (float) Count;
}
///
/// gets a key value of defined time using interpolation method.
///
/// defined time
/// interpolation method
/// key value
public float GetKeyFrame(float t, Interpolation mode)
{
int idx = -1;
float s = 0.0f;
if (Time != null && Time.Count > 0)
idx = GetTimeIndex(t);
else
idx = GetIndex(t);
if (idx >= Count)
idx = Count - 1;
switch (mode)
{
case Interpolation.Lerp:
{
if (idx < (Count - 1))
{
if( Time != null && Time.Count > 0)
s = (t - Time[idx]) / (Time[idx + 1] - Time[idx]);
else
s = (t - ((float)idx * step)) * (float)Count;
return Table[idx] + ((Table[idx + 1] - Table[idx]) * s);
}
return Table[idx];
}
default:
{
return Table[idx];
}
}
}
///
/// gets a key index of defined time.
///
/// defined time
/// key index
protected int GetIndex(float t)
{
return (int)(t * Count);
}
///
/// gets a time index of defined time.
///
/// defined time
/// time index
protected int GetTimeIndex(float t)
{
int si = 0;
int ei = Count - 1;
int mi = 0;
if (t >= Time[ei])
{
return ei;
}
do
{
mi = (si + ei) / 2;
if ((ei - si) <= 1)
{
break;
}
else if (Time[mi] < t)
{
si = mi;
}
else if (Time[mi] > t)
{
ei = mi;
}
else
{
si = mi;
break;
}
} while ((ei - si) > 1);
return si;
}
}
}