public static AnimationStatus RenderFrame(Avatar avatar, Animation animation, int frame, float fraction, float weight)
{
bool completed = (frame < 0 || frame > animation.NumFrames);
frame = Math.Max(Math.Min(frame, animation.NumFrames), 0);
var numDone = 0;
foreach (var motion in animation.Motions)
{
var bone = avatar.Skeleton.GetBone(motion.BoneName);
if (bone == null) continue; //fixes bugs with missing bones.. need to find out what R_FINGERPOLY0 is though.
var motionFrame = frame;
if (frame >= motion.FrameCount)
{
numDone++;
motionFrame = (int)motion.FrameCount - 1;
}
if (motion.HasTranslation)
{
Vector3 trans;
if (fraction >= 0)
{
var trans1 = animation.Translations[motion.FirstTranslationIndex + motionFrame];
var trans2 = (frame + 1 >= motion.FrameCount) ? trans1 : animation.Translations[motion.FirstTranslationIndex + motionFrame+1];
trans = Vector3.Lerp(trans1, trans2, fraction);
}
else
{
trans = animation.Translations[motion.FirstTranslationIndex + motionFrame];
}
if (weight == 1) bone.Translation = trans;
else bone.Translation = Vector3.Lerp(bone.Translation, trans, weight);
}
if (motion.HasRotation)
{
Quaternion quat;
if (fraction >= 0)
{
var quat1 = animation.Rotations[motion.FirstRotationIndex + motionFrame];
var quat2 = (frame + 1 >= motion.FrameCount) ? quat1 : animation.Rotations[motion.FirstRotationIndex + motionFrame + 1];
quat = Quaternion.Slerp(quat1, quat2, fraction);
}
else
{
quat = animation.Rotations[motion.FirstRotationIndex + motionFrame];
}
if (weight == 1) bone.Rotation = quat;
else bone.Rotation = Quaternion.Slerp(bone.Rotation, quat, weight);
}
}
if (completed || frame+1 > animation.NumFrames) return AnimationStatus.COMPLETED;
return AnimationStatus.IN_PROGRESS;
}