#region File Description
//-----------------------------------------------------------------------------
// SkinnedAnimationPlayer.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace CustomModelAnimation
{
///
/// The animation player manipulates a skinned model
///
public class SkinnedAnimationPlayer : ModelAnimationPlayerBase
{
// Current animation transform matrices.
Matrix[] boneTransforms;
Matrix[] worldTransforms;
Matrix[] skinTransforms;
List bindPose;
List inverseBindPose;
List skeletonHierarchy;
///
/// Constructs a new animation player.
///
public SkinnedAnimationPlayer(List bindPose, List inverseBindPose, List skeletonHierarchy)
{
if (bindPose == null || bindPose.Count == 0)
throw new Exception("Bad arguments to model animation player");
boneTransforms = new Matrix[bindPose.Count];
worldTransforms = new Matrix[bindPose.Count];
skinTransforms = new Matrix[bindPose.Count];
this.bindPose = bindPose;
this.inverseBindPose = inverseBindPose;
this.skeletonHierarchy = skeletonHierarchy;
}
///
/// Initializes the animation clip
///
protected override void InitClip()
{
bindPose.CopyTo(boneTransforms);
}
///
/// Sets the key frame for the passed in frame
///
///
protected override void SetKeyframe(ModelKeyframe keyframe)
{
boneTransforms[keyframe.Bone] = keyframe.Transform;
}
///
/// Updates the transformations ultimately needed for rendering
///
protected override void OnUpdate()
{
if (CurrentClip != null)
{
// Root bone.
worldTransforms[0] = boneTransforms[0];
skinTransforms[0] = inverseBindPose[0] * worldTransforms[0];
// Child bones.
for (int bone = 1; bone < worldTransforms.Length; bone++)
{
int parentBone = skeletonHierarchy[bone];
worldTransforms[bone] = boneTransforms[bone] * worldTransforms[parentBone];
skinTransforms[bone] = inverseBindPose[bone] * worldTransforms[bone];
}
}
}
///
/// Gets the current bone transform matrices, relative to their parent bones.
///
private Matrix[] GetBoneTransforms()
{
return boneTransforms;
}
///
/// Gets the current bone transform matrices, in absolute format.
///
private Matrix[] GetWorldTransforms()
{
return worldTransforms;
}
///
/// Gets the current bone transform matrices, relative to the skinning bind pose.
///
public Matrix[] GetSkinTransforms()
{
return skinTransforms;
}
}
}