(History blog)
This was a daunting task for a 3d newbie. Needing some animations to work with, I went back to hacking to extract some animations for the character Claris. After some tedious days, I had most of claris' animations at my disposal. I created an export script in 3d studio to get them into a basic file format of keyframed euler rotations. Now what? I was asking myself that often over the next few days;P
I better explain how the models and animations where stored in NiGHTS. A 3d model is an array of meshes, one for each bodypart. An animation key-frame is an array of XYZ-local-euler rotations for each mesh. An animation is an array of key-frame arrays and a speed to interpolate them. It was a fairly basic setup compared to the complex bone/IK/morph target deforming a skinned mesh system that games use today.
After alot of trial and error, I had the body parts finaly being rendered on screen based on the keyframes which looked like Claris was having a seizure, flailing her limbs all over the place. After alot more trial and error, I had the animation working correctly (I learned the important lesson that you cannot multiply matricies in any order you feel like).
Getting the animation working and testing the efficiency by rendering several hundred animated Claris' all running around on screen made me feel pretty hot, as if I was a pro at efficient use of XNA all ready. But when I latter tackled billboarded sprites, which turned out to be the most unefficient, slow, and downright crappy system I have ever written, I learned my lesson;P
Basic Animation Structure:
enum enumBodyPart//array indexes for each body part
{
PELVIS, CHEST, HEAD, R_SHOLDER, R_ARM, R_HAND, L_SHOLDER, L_ARM, L_HAND, R_LEG, R_CALVE, R_FOOT, L_LEG, L_CALVE, L_FOOT
}
struct BODY_PART
{
public VertexBuffer vb;//vertex (position,texture,normal)
public IndexBuffer ib;//index
public int NumPrimatives;//number of triangles in mesh
public Vector3 RootPos;//root position of bodypart (static position, standing up with arms out)
}
struct ANIMATION_FRAME
{
public Vector3[] Rotations;//array of each bodyparts euler rotation for the frame
}
struct ANIMATION
{
public int NumFrames;
public float Speed;
public ANIMATION_FRAME[] Frames;//each frame
}
struct FRAME_INFO
{
public int AnimID;//animation index
public int FrameID;//frame index
}
struct ANIM_OBJ
{
public Vector3 Pos;//position vector
public Vector3 Dir;//direction vector
public Vector3 Rot;//rotation eulers
public BODY_PART[] body;//each body part
public Texture2D tex;
public ANIMATION[] Animations;//animations
public FRAME_INFO CurFrame;//active animation
public FRAME_INFO NextFrame;//animation to interpolate to
public float LastFrameTime;//gametime of last frame interpolation
}
Animation Video: Claris Exploring Soft Museum
Monday, March 12, 2007
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment