redarrow
04-28-2006, 12:42 AM
Hi all,
Has anyone got any links to good references on deforming a mesh with a skeletal structure?
I really can't figure it out...
I have a basic structure allowing me to assign multiple bones to a vertex and specifying the influence for each, something like this:
typedef struct {
...
float s_pos[3]; /* The base postion of the bone */
float e_pos[3]; /* The end position of the bone */
float matrix[16]; /* Rotation matrix */
} Bone;
typedef struct {
...
float v[3]; /* Original vertex position */
float av[3]; /* Final vertex position */
int num_bones; /* Number of bones assigned to this vertex */
float *influence; /* Array of floats indicating influence setting for each attached bone */
Bone **bone; /* Array of pointers to attached bones */
} Vertex;Each bone is drawn by translating to it's s_pos
and transforming by it's rotation matrix like:
glPushMatrix();
glTranslate(bone->s_pos[0], bone->s_pos[1], bone->s_pos[2]);
glMultMatrixf(bone->matrix);
/* .. draw bone graphic here .. */
glPopMatrix();Now the part that's stumping me is how precisely to calculate the vertice's positons based on bone assignments?
Each vertex contains the original position (as loaded from a static mesh model) in vertex->v, I need to calculate the deform and place it in vertex->av ...
The method I've been trying is like this:
float tv[3]; /* Temporary vertex positional data */
Bone *bone;
float influence;
for (i = 0; i < 3; i++) vertex->av[i] = vertex->v[i]; /* Set the vertex to the intial position */
for (b = 0; b < vertex->num_bones; b++) {
bone = vertex->bone[B]; /* Get current bone */
influence = vertex->influence[B]; /* Get influence of current bone */
/* Set tv to original vertex position and subtract bone base position - so that rotation happens about the bones axis and not the origin */
for (i = 0; i < 3; i++) tv[i] = vertex->v[i] - bone->s_pos[a];
mult_vector_by_matrix(tv, bone->matrix); /* Transform tv by the bone's rotation matrix */
for (i = 0; i < 3; i++) {
tv[i] += bone->pos[i]; /* Add bone's base position back into tv */
vertex->v[i] += ((tv[i] - vertex->v[i]) * influence); /* Calculate offest to orginal position and multiply by influence */
}
}I found this method somewhere on the web, it works partly - if I attach a vertex to a bone and rotate _only_ that bone it works right .. the minute I rotate a bone higher in the hierarchy (i.e. that bones parent) it goes all wrong... :confused:
Sorry for the rather long ramble... :D
Any help/ideas/links appreciated ..
Thanks!
Has anyone got any links to good references on deforming a mesh with a skeletal structure?
I really can't figure it out...
I have a basic structure allowing me to assign multiple bones to a vertex and specifying the influence for each, something like this:
typedef struct {
...
float s_pos[3]; /* The base postion of the bone */
float e_pos[3]; /* The end position of the bone */
float matrix[16]; /* Rotation matrix */
} Bone;
typedef struct {
...
float v[3]; /* Original vertex position */
float av[3]; /* Final vertex position */
int num_bones; /* Number of bones assigned to this vertex */
float *influence; /* Array of floats indicating influence setting for each attached bone */
Bone **bone; /* Array of pointers to attached bones */
} Vertex;Each bone is drawn by translating to it's s_pos
and transforming by it's rotation matrix like:
glPushMatrix();
glTranslate(bone->s_pos[0], bone->s_pos[1], bone->s_pos[2]);
glMultMatrixf(bone->matrix);
/* .. draw bone graphic here .. */
glPopMatrix();Now the part that's stumping me is how precisely to calculate the vertice's positons based on bone assignments?
Each vertex contains the original position (as loaded from a static mesh model) in vertex->v, I need to calculate the deform and place it in vertex->av ...
The method I've been trying is like this:
float tv[3]; /* Temporary vertex positional data */
Bone *bone;
float influence;
for (i = 0; i < 3; i++) vertex->av[i] = vertex->v[i]; /* Set the vertex to the intial position */
for (b = 0; b < vertex->num_bones; b++) {
bone = vertex->bone[B]; /* Get current bone */
influence = vertex->influence[B]; /* Get influence of current bone */
/* Set tv to original vertex position and subtract bone base position - so that rotation happens about the bones axis and not the origin */
for (i = 0; i < 3; i++) tv[i] = vertex->v[i] - bone->s_pos[a];
mult_vector_by_matrix(tv, bone->matrix); /* Transform tv by the bone's rotation matrix */
for (i = 0; i < 3; i++) {
tv[i] += bone->pos[i]; /* Add bone's base position back into tv */
vertex->v[i] += ((tv[i] - vertex->v[i]) * influence); /* Calculate offest to orginal position and multiply by influence */
}
}I found this method somewhere on the web, it works partly - if I attach a vertex to a bone and rotate _only_ that bone it works right .. the minute I rotate a bone higher in the hierarchy (i.e. that bones parent) it goes all wrong... :confused:
Sorry for the rather long ramble... :D
Any help/ideas/links appreciated ..
Thanks!