Animations on bones

Topics: Developer Forum, User Forum
Jan 29, 2014 at 6:52 AM
Edited Jan 29, 2014 at 6:57 AM
Hi everyone,

I am able to display and rotate, translate the whole fbx model in XNA framework. I want to move and animate individual bones in XNA. But there is no animation class provided for that. Can anyone suggest me how to proceed.

Meanwhile i tried with the help of few posts from different forums. i used bonetransforms and with the bone index i rotated the bone and finally set the world, view and transform matrices accordingly . But the model is not getting displayed only the screen is comming up. so pls help.
Apr 22, 2014 at 12:46 AM
namespace IRISFrameWork.Graphics.XNA.Models.MyModel
{
public class MyBone
{

    /// <summary>
    /// Children of this bone.
    /// </summary>
    public MyModelBoneCollection Children { get;   private set;}
    /// <summary>
    /// index of this bone in bones collection at Model.
    /// </summary>
    public int Index {   get;private set;}

   /// <summary>
    /// name of this bone.
    /// </summary>
    public string Name { get;private set;  }

    /// <summary>
    /// Parent of this bone.
    /// </summary>
    public MyBone Parent {  get;    private set;}
    /// <summary>
    /// Bone transfrom.
    /// </summary>
    public MyLimitedProperty<Matrix> Transform {    get;     private set;  }

    public MyLimitedProperty<Matrix> BindPose  {    get;     private set;    }

    public MyLimitedProperty<Matrix> InverseBindPose    {        get;        private set;      }

    public bool IsSkinned { get; private set; }

    public  MyBone(string name, Matrix transform, int index)
    {
        Name = name;
        Transform = new MyLimitedProperty<Matrix>(this,"Transform", transform);
        Index  = index;

    }

    public MyBone(string name, Matrix transform, int index,Matrix bindPose,Matrix inverseBindPose):this(name,transform,index)
    {
        BindPose = new MyLimitedProperty<Matrix>(this, "BindPose", bindPose);
        InverseBindPose = new MyLimitedProperty<Matrix>(this, "InverseBindPose", inverseBindPose);
        IsSkinned = true;
    }

    // void SetParentAndChildren(MyBone newParent, MyBone[] newChildren)
    //{
    //    Parent= newParent;
    //    Children = new MyModelBoneCollection(newChildren);

    //}


   public  static MyModelBoneCollection CreateBonesFromModel(Components.ModelComponent modelComponent)
   {
       MyBone[] myBones;
       MyModelBoneCollection boneCollection = null;

       SkinnedModel.SkinningData skinnedData = modelComponent.skinningData;

       if (skinnedData != null)
       {
           var SkeletonHierachy = skinnedData.SkeletonHierarchy;
           myBones = new MyBone[SkeletonHierachy.Count];

           foreach (var item in skinnedData.BoneIndices)
           {
               myBones[item.Value] = new MyBone(item.Key,Matrix.Identity,  item.Value, skinnedData.BindPose[item.Value], skinnedData.InverseBindPose[item.Value]);
           }

           for (int index = 0; index < SkeletonHierachy.Count; index++)
           {
               MyBone bone = myBones[index];
               int parent = SkeletonHierachy[index];
               if (parent > -1)
               {
                   bone.Parent = myBones[parent];
               }

               List<MyBone> childBones = new List<MyBone>();
               for (int i = 0; i < SkeletonHierachy.Count; i++)
               {
                   if (i == index || i == parent) continue;
                   if (SkeletonHierachy[i] == index)
                   {
                       childBones.Add(myBones[i]);
                   }
               }
               bone.Children = new MyModelBoneCollection(childBones.ToArray());


           }

       }
       else
       {
           ModelBoneCollection modelBones = modelComponent.Model.Bones;
           ModelBone[] bones = new ModelBone[modelBones.Count];
           modelBones.CopyTo(bones, 0);

           myBones = new MyBone[bones.Length];

           //CreateBonesFromSkinnedModel(null, modelComponent.skinningData);

           for (int i = 0; i < myBones.Length; i++)
           {
               ModelBone bone = bones[i];
               myBones[i] = new MyBone(bone.Name, bone.Transform, bone.Index);
               if (bone.Parent != null)
                   myBones[i].Parent = myBones[bone.Parent.Index];
           }

           for (int i = 0; i < myBones.Length; i++)
           {
               ModelBone bone = bones[i];
               List<MyBone> childBones = new List<MyBone>();
               foreach (var childbone in bone.Children)
               {
                   childBones.Add(myBones[childbone.Index]);
               }
               myBones[i].Children = new MyModelBoneCollection(childBones.ToArray());
           }

       }
       boneCollection= new MyModelBoneCollection(myBones,true);
       return boneCollection;
   }


   //public static MyBone[] CreateBonesFromModel(MyBone bone , ModelBoneCollection bones)
   //{
   //    MyBone[] children = new MyBone[bones.Count];

   //    for (int i = 0; i < children.Length; i++)
   //    {
   //        ModelBone bon=bones[i];
   //        children[i] = new MyBone(bon.Name, bon.Transform, bon.Index) { Parent = bone };
   //        children[i].Children =new MyModelBoneCollection( CreateBonesFromModel(children[i], bon.Children));
   //    }
   //    return children;
   //}

   public static Matrix[] CalculateAbsoluteTransforms(MyModelBoneCollection Bones, Matrix world)
   {
       int BONECOUNT = Bones.Count;
       MyBone[] bones = new MyBone[BONECOUNT];
       Bones.CopyTo(bones, 0);

       Matrix[] boneTransforms = new Matrix[BONECOUNT];
       Matrix[] worldTransforms = new Matrix[BONECOUNT];
       int[] Parent = new int[BONECOUNT];

       for (int i = 0; i < BONECOUNT; i++)
       {
           MyBone bone = bones[i];
           boneTransforms[i] = bone.Transform.Value;
           Parent[i] = bone.Parent != null ? bone.Parent.Index : -1;
       }

       bool isSkinned = Bones[0].IsSkinned;

       if (isSkinned)
       {
           Matrix[] bindPose = new Matrix[BONECOUNT];
           Matrix[] inversebindPose = new Matrix[BONECOUNT];
           Matrix[] skintransforms = new Matrix[BONECOUNT];

           for (int i = 0; i < BONECOUNT; i++)
           {
               MyBone bone = bones[i];
               bindPose[i] = bone.BindPose.Value;
               inversebindPose[i] = bone.InverseBindPose.Value;
           }

           worldTransforms[0] = boneTransforms[0] * bindPose[0] * world;

           for (int i = 1; i < BONECOUNT; i++)
           {
               worldTransforms[i] = boneTransforms[i] * bindPose[i] * worldTransforms[Parent[i]];
           }

           for (int i = 0; i < BONECOUNT; i++)
           {
               skintransforms[i] = inversebindPose[i] * worldTransforms[i];
           }

           return skintransforms;
       }
       else
       {

           worldTransforms[0] = boneTransforms[0] * world;
           for (int i = 1; i < BONECOUNT; i++)
           {
               worldTransforms[i] = boneTransforms[i] * worldTransforms[Parent[i]];
           }
       }
       return worldTransforms;
   }


}



}
Apr 22, 2014 at 12:47 AM
create new bone and bonecollection class