Sign in to follow this  

Getting animation data in MilkShape plugin

Recommended Posts

I originally asked this question here but haven't gotten any response, so I thought I might try my luck here. I'm trying to write an export plugin for Milkshape that can export to my own custom model format. So far I can export all the vertices and whatnot, and static models work great. But I still can't figure out how to export the animation data. It looks like msBone_GetPositionKeyAt() and msBone_GetRotationKeyAt() are the functions I should be using, but I can't figure out exactly what they give me, and I can't find any documentation. Are the positions and rotations relative to something? If so, to what?

Share this post

Link to post
Share on other sites

First, be sure you understand well how skeletal animation works and what is the data required for animating a model in that way; basically you need:

- The vertices and triangles: when rendered as is (exactly how they are stored in file) the model will be seen in bind pose.

- The skeleton: which is built using severals nodes called Joints, (but technically in milkshape they are also refered as bones). the position of each joint before any rotation/translation will show the skeleton in bind pose.

- The keyframes: this is a list of translation/rotation for every joint; which are used for calculate in run time a new pose for the skeleton. Several keyframes played will show an animation.

For geting the animation data from the milkshape sdk i think what you need to do is:

- msModel_GetBoneCount: for get the amount joints in the model.
Then for every joint in the model do:
- msModel_GetBoneAt: used to get a joint object for current loop interaction.
- msBone_GetName: using the curent joint object for get the name joint.
- msBone_GetParentName; to get the parent of current joint. (none if the joint is the root joint).
- msBone_GetPosition; to get joint relative position from parent position. (bind pose)
- msBone_GetRotation; to get joint relative rotation from parent rotation. (bind pose)
- msBone_GetPositionKeyCount and msBone_GetRotationKeyCount: (which i think they should always return same count) for get the amount keyframes for current joint.
Then for every keyframe in the current joint use:
- msBone_GetPositionKeyAt: for get the translation for current kayframe. (relative from parent and bind pose).
- msBone_GetRotationKeyAt: for get the rotation for current keyframe. (relative from parent and bind pose).

Basically that is all for get the animation data, the next step is a litle harder which is to imterpret that data and trnsfor the vertices for draw the model in every keyframe pose.

You should download from milkshape website the ms3d viewer source code where it teach how interpret data.

good luck.

[Edited by - tpascal on February 19, 2008 1:20:00 PM]

Share this post

Link to post
Share on other sites
I think I'm getting closer, but the animation still isn't behaving quite right. Here's how I'm generating each bone's world coordinates when animating (in pseudo-code):
keyPosition = msBone_GetPositionKeyAt()
keyRotation = msBone_GetRotationKeyAt()

bindPosition = msBone_GetPosition()
bindRotation = msBone_GetRotation()

parentPosition = previously calculated world coordinates of the parent bone
parentRotation = previously calculated final rotation of the parent bone

bonePosition = parentRotation * (keyPosition + bindPosition) + parentPosition
boneRotation = keyRotation * bindRotation * parentRotation

I'm converting from Euler angles to quaternions and doing the rotations that way, if that makes any difference.

Am I doing my calculations correctly? In the right order and everything?

Share this post

Link to post
Share on other sites

Your seudocode looks good, however i suggest you should try first to draw the skeleton in the bind pose before any joint keyframe translation/rotation; I remember that was a litle tricky to do from milkshape data; some people preffer to use the "Zero joints" option from menu tools before exporting the model, that will zeroed the bone rotation and will adjust the bone position for compensate;

Also be sure you are using same coordinate system from milkshape or make sure youare comverting correctly the data if you app coordinate system is different, i mean Z negative could point diffrent in your app; also rotations have to be in X,Y,Z order and be sure they are rotating in the same direction as like in milkshape.

Share this post

Link to post
Share on other sites
Original post by tpascal
also rotations have to be in X,Y,Z order and be sure they are rotating in the same direction as like in milkshape.

That might be where the problem lies. If the Euler angles are XYZ ordered, does that mean the angles are ordered as pitch, yaw, roll (since Milkshape seems to treat -Z as forward and +Y as up (which also matches my coordinate system))?

When I create just a very simple animation where something rotates around a center point and I play back the animation, the rotation is in the opposite direction that Milkshape plays it.

Share this post

Link to post
Share on other sites
It happen a long time since I did my milkshape reader to my engine; i am using DirectX and front faces is defined passing vertices in clockwise order. for reading the model vertices from milkshape I am inverting all Z values (z=z*-1) and changing the vertices order; for joint positions,translations and keyframes translation i am also inverting Z value; for keyframes angles rotation i am inverting X and Y (anglex=anglex*-1; angleY=angley*-1;), i dont remember why.

hope this help

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this