🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

MS3D Loader in powerbasic(help with joints)

Started by
3 comments, last by redwraith 16 years, 10 months ago
So I decided to start coding some again. Stupid world of warcraft and studies steal all my time. Anyhow, Ive started doing a "game" for fun. Hopefully it will be playable. See, Ive created somewhat of a Milkshape 3D Model read for my program(powerbasic) however I do not understand the join section. Ive included to where I currently am with my loader(it works and display my model) furthes down on this page. How do the joints work? What Im assuming is that each joint is a vertix(x,y,z) which have a number of triangles vertixes assign to it and when I move the joint the triangles moves to where the joint is but I dont seem to understand what is what. word nNumJoints; This is the number of joints that is in the model. typedef struct { float time; // time in seconds float rotation[3]; // x, y, z angles } ms3d_keyframe_rot_t; ------------This is the type that includes the rotation for that joint and how -------------long it lasts(time). typedef struct { float time; // time in seconds float position[3]; // local position } ms3d_keyframe_pos_t; ------------This is the type that includes the new position for that join and --------------the time it lasts that way. typedef struct { byte flags; // SELECTED | DIRTY char name[32]; // char parentName[32]; // float rotation[3]; // local reference matrix float position[3]; word numKeyFramesRot; // word numKeyFramesTrans; // ms3d_keyframe_rot_t keyFramesRot[numKeyFramesRot]; // local animation matrices ms3d_keyframe_pos_t keyFramesTrans[numKeyFramesTrans]; // local animation matrices } ms3d_joint_t; ------------This is the actual joint. How many of these exist is specififed in -------------beginning, it contains the original position and rotation of the ---------------joint and the information for each new fram(keyFramesRot,and Trans). This is how I have understood this. However, Nowhere is there written what triangles are connected to the joints. If I have understood anything wrong then please, enlighten me :D thanks /RedWraith
Advertisement
The MS3D Vertex structure has a BoneID which is how the vertex is attached to a joint. The triangles are just indexes to the vertices. Everything else that you have said seems correct.
Member of the NeHe team.
Quote"The MS3D Vertex structure has a BoneID which is how the vertex is attached to a joint. The triangles are just indexes to the vertices. Everything else that you have said seems correct.

Member of the NeHe team. | SheepLib - My OpenGL helper library"

Thanks for the slow reply. Let's see if I get it straight.
Each vertex that exist AND have a bone_id that isnt -1 is connected to a joint.
So, if I get it right, when Im drawing the actual model:

each vertex that is connected to a joint actually becomes:

vertex.x = vertex.x + KeyFramesTrans(Frame).position(1)
vertex.y = vertex.y + KeyFramesTrans(Frame).position(2)
vertex.z = vertex.z + KeyFramesTrans(Frame).position(3)

for each frame. Playing through the entire animation would mean Delaying "time" amount of seconds before Frame=Frame+1 which would go to next jointdata for this current item?

Thanks yet again.

/RedWraith




typedef struct
{
byte flags; // SELECTED | SELECTED2 | HIDDEN
float vertex[3]; //
char boneId; // -1 = no bone
byte referenceCount;
} ms3d_vertex_t;

typedef struct
{
byte flags; // SELECTED | DIRTY
char name[32]; //
char parentName[32]; //
float rotation[3]; // local reference matrix
float position[3];

word numKeyFramesRot; //
word numKeyFramesTrans; //

ms3d_keyframe_rot_t keyFramesRot[numKeyFramesRot]; // local animation matrices
ms3d_keyframe_pos_t keyFramesTrans[numKeyFramesTrans]; // local animation matrices
} ms3d_joint_t;

from the .h file.

Quote:
Thanks for the slow reply


Slow?? I posted an hour after you did, and as soon as I saw the post!

OK, I'll try and explain as best I know... some of this may be incorrect as it's from memory...

Each joint has a parent joint (unless it's the root), when you first load the model you need to set up the appropriate joint transforms based on the hierarchy. So for each joint you first build the "relative" matrix to the parent joint. You must also store the "absolute" matrix for each joint, this is the same as the "relative" matrix if the joint has no parent otherwise it is the parents absolute matrix multiplied with the joints relative matrix. This is done by using the rotation and position attributes of the joint. Something like (pseudo):

Mat4 absolute, relative, X, Y, Z;X = buildRotationX(joint.rotation[0]);Y = buildRotationY(joint.rotation[1]);Z = buildRotationZ(joint.rotation[2]);relative = X * Y * Z;relative.41 = joint.position[0];relative.42 = joint.position[1];relative.43 = joint.position[2];if (joint.hasParent) {     absolute = parent.absolute * relative;} else {     absolute = relative;}


You then loop through the vertices, and transform them by their associated joints absolute matrix.

During animation you do a similar kind of thing, except you get the interpolated matrix between the 2 keyframes (e.g first get the interpolation between the 2 closest position vectors and rotation vectors in the keyframe joints and build a matrix from the interpolated values) then multiply that with the joints relative matrix to get the final matrix for the joint. Then if there is a parent joint, multiply the final joint matrix with the parent's to get the matrix to transform the vertices by.

It's hard to explain in English, far easier in code. Look at some sample code and compare that to what I've just said, hopefully it will be of some help.
Member of the NeHe team.
Hahaha Im sorry mate...didnt mean slow i meant Fast..my bad.

Thanks for the help Ill study it some and try implement it..

/RedWraith

This topic is closed to new replies.

Advertisement