Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411528 Posts in 69377 Topics- by 58433 Members - Latest Member: Bohdan_Zoshchenko

April 29, 2024, 12:42:17 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)skeletal animation
Pages: [1]
Print
Author Topic: skeletal animation  (Read 2021 times)
Jolli
Guest
« on: January 31, 2010, 09:13:27 PM »

Sad i hav problem. it bug me for couple weeks now
i try to code skeletal animation... but it dont work!!!
i can post what i have currently that isnt working

ill post some things im using...

i am exporting model from blender.

my model format:
Screamy i use a 4x4 matrix for each bone. blender calls the 4x4 matrix "armaturespace". theres also a 3x3 matrix called "bonespace" but i dont use that one... i dont really know which one i should be using.
Screamy each vert looks like this:
x y z xnormal ynormal znormal
['bonename', weight with bone]
['bonename2', weight with bone]
['bonename3', weight with bone]
etc.

im using c++/opengl for the gam
no trouble in loading the blender model
i only export still pose and load that

no trouble with everything else besides the drawing...

this is my draw code...

Code:
int drawModelAnim(MODEL* modelname, GLuint texname, float mod_x, float mod_y, float mod_z)
{
  int triCount;
  int v1, v2, v3;
  float temp[16];
  float x_, y_, z_, u_, v_;
  float* normal;
  float* vert;
  triCount = modelname->triCount;

  glTranslatef(mod_x,mod_y,mod_z);
  glBindTexture(GL_TEXTURE_2D, texname);

  glBegin(GL_TRIANGLES);

  for(int t=0; t<triCount; t++)
  {
    //verts from triangle
    v1=modelname->triangle[t].v1;
    v2=modelname->triangle[t].v2;
    v3=modelname->triangle[t].v3;

    //VERTEX 1
    x_=modelname->vertex[v1].x; y_=modelname->vertex[v1].y; z_=modelname->vertex[v1].z;
    u_ = modelname->triangle[t].v1U;
    v_ = modelname->triangle[t].v1V;

    for (int j=0; j<16; j++){ temp[j] = 0; }

    for(int i; i<modelname->vertex[v1].boneamount; i++){
      for(int j = 0; j<16; j++){
        temp[j] += ( modelname->bone[ modelname->vertex[v1].boneind[i] ].mat_rotation[j] ) *
        ( modelname->vertex[v1].bonewgt[i] );
        }
      }
    normal = multiplybymatrix(modelname->vertex[v1].normx, modelname->vertex[v1].normy, modelname->vertex[v1].normz, temp);
    vert = multiplybymatrix(x_, y_, z_, temp);
    glTexCoord2f(u_, v_);
    glNormal3f(normal[0], normal[1], normal[2]);
    glVertex3f(vert[0], vert[1], vert[2]);


    //VERTEX 2
    x_=modelname->vertex[v2].x; y_=modelname->vertex[v2].y; z_=modelname->vertex[v2].z;
    u_ = modelname->triangle[t].v2U;
    v_ = modelname->triangle[t].v2V;

    for (int j=0; j<16; j++){ temp[j] = 0; }

    for(int i; i<modelname->vertex[v1].boneamount; i++){
      for(int j = 0; j<16; j++){
        temp[j] += ( modelname->bone[ modelname->vertex[v2].boneind[i] ].mat_rotation[j] ) *
        ( modelname->vertex[v2].bonewgt[i] );
        }
      }
    normal = multiplybymatrix(modelname->vertex[v2].normx, modelname->vertex[v2].normy, modelname->vertex[v2].normz, temp);
    vert = multiplybymatrix(x_, y_, z_, temp);

    glNormal3f(normal[0], normal[1], normal[2]);
    glVertex3f(vert[0], vert[1], vert[2]);

    //VERT 3
    x_=modelname->vertex[v3].x; y_=modelname->vertex[v3].y; z_=modelname->vertex[v3].z;
    u_ = modelname->triangle[t].v3U;
    v_ = modelname->triangle[t].v3V;

    for (int j=0; j<16; j++){ temp[j] = 0; }

    for(int i; i<modelname->vertex[v3].boneamount; i++){
      for(int j = 0; j<16; j++){
        temp[j] += ( modelname->bone[ modelname->vertex[v3].boneind[i] ].mat_rotation[j] ) *
        ( modelname->vertex[v3].bonewgt[i] );
        }
      }

    normal = multiplybymatrix(modelname->vertex[v3].normx, modelname->vertex[v3].normy, modelname->vertex[v3].normz, temp);
    vert = multiplybymatrix(x_, y_, z_, temp);

    glTexCoord2f(u_, v_);

    glNormal3f(normal[0], normal[1], normal[2]);
    glVertex3f(vert[0], vert[1], vert[2]);

  }
  glEnd();
}


and this is the multiplybymatrix

Code:
float* multiplybymatrix( float x, float y, float z, float* matrix)
{
float ret[3];
ret[0] = x*matrix[0]+y*matrix[4]+z*matrix[8]+matrix[12];
ret[1] = x*matrix[1]+y*matrix[5]+z*matrix[9]+matrix[13];
ret[2] = x*matrix[2]+y*matrix[6]+z*matrix[10]+matrix[14];
return ret;
}

/*
ive tried both
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

and

0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15

orders, with no result.
*/

this what it looks like if i just draw without bone calculation

this character is not visible on screen (or idk where its drawn) if i do try drawing with the skeletabob

...

i hope this enough info... Smiley
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #1 on: January 31, 2010, 09:45:46 PM »

I wrote a skeletal animation export script for blender awhile ago, but mine exported the quaternion bezier paths instead of matrices, so I might or might not be able to help you.

First thing I would take a look at is the bone parenting. I'm pretty sure that the bone matrices you're extracting in blender are in coordinates relative to the bone's parent's matrix. That means that you have to do the additive matrix multiplication of all the bone's parents on the other end or do it before exporting the matrix in blender.

Another thing to look into is the space coordinates in blender. From what I remember, the base armature coordinates were always out of whack for me and had to be readjusted. Remember that your model and the skeleton must be in exactly the same coordinate system, so their origins must match.

Take a look at the python scripts for the existing exporters that export skeletal animation. You can get most of what you need from them.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
David Pittman
Level 2
**


MAEK GAEM


View Profile WWW
« Reply #2 on: January 31, 2010, 10:03:54 PM »

For starters, if you're only exporting the base pose, your bone matrices should all be identity matrices (because you expect the mesh to look exactly the same as it does when you're not using the bones, so there shouldn't be any actual transformation happening). So I'd start from there: take a look at each matrix and see how it is different from identity. Hopefully that will tell you something useful; perhaps you need to transform each matrix by its parent bone space, or perhaps Blender uses a different coordinate system, or something.
Logged

Zaphos
Guest
« Reply #3 on: January 31, 2010, 10:57:36 PM »

my model format:
Screamy i use a 4x4 matrix for each bone. blender calls the 4x4 matrix "armaturespace". theres also a 3x3 matrix called "bonespace" but i dont use that one... i dont really know which one i should be using.
3x3 matrices have no translation part -- they are just rotation -- and they probably store an orientation of the bone relative to the previous bone.  4x4s store a translation, so they can position the bone in space relative to eg the root.

normal = multiplybymatrix(modelname->vertex[v3].normx, modelname->vertex[v3].normy, modelname->vertex[v3].normz, temp);
This obviously isn't your main problem, but if there's a translation component to the matrix temp, this will do strange things to your normal.  You want to make sure you don't 'translate' a direction vector.

Other strange things will also happen the normal if your skeletal animation includes non-uniform scaling, which you will probably have if you're just taking a weighted average of matrices without re-ortho-normalizing them ...

/*
ive tried both
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

and

0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15

orders, with no result.
*/
You could check if 12,13,14 is always zero, or if 3,7,11 is always zero.  If only one is all zero, the nonzero ones are probably translation and should go in the right column, while the zeros should go on the bottom row.  (Also double check that 15 is always 1 ...)

Quote
this character is not visible on screen (or idk where its drawn) if i do try drawing with the skeletabob
Try printing out the matrices you're transforming your vertices by to see what it's doing.  Also, use gluLookAt (or whatever you want) to point your camera at (some vertex of) the character where-ever it ends up.

Quote
i hope this enough info... Smiley
Seeing what's in those matrices might help, and/or some documentation on what they're supposed to do?  I'm guessing the armature matrices are actually supposed to do something other than what you're doing with them, like perhaps to transform from local bone coordinates to model space coordinates or something ...
Logged
Jolli
Guest
« Reply #4 on: February 01, 2010, 05:38:06 PM »

Quote
Seeing what's in those matrices might help, and/or some documentation on what they're supposed to do?
this is example of those 4x4 matrix from the model file:

Code:
bones_ Bone_R.004
[-0.638594, 0.613949, 0.463965, 0.000000](vector)
[-0.740089, -0.324765, -0.588894, 0.000000](vector)
[-0.210871, -0.719440, 0.661770, 0.000000](vector)
[-13.658981, 4.677871, -2.142759, 1.000000](vector)
Logged
Zaphos
Guest
« Reply #5 on: February 01, 2010, 09:02:26 PM »

Is that from a frame when the model is supposed to be in its rest pose?  (Are there any frames not in the rest pose?)

You can see from the bottom row that it's trying to translate by (-13.658981, 4.677871, -2.142759), so if it's a rest pose it's clearly not something you should be applying to your undeformed vertices directly; like David said, you'd expect to transform your vertices by the identity matrix for your rest pose.

Looking about at what blender people seem to mean by the armature matrix, I'd guess that your armature matrix is a matrix for going from bone space to model space.  In that case you'd have, say, matrix A_0 which takes a bone from bone space to your rest pose, and matrix A_t which takes the bone to your pose at time t, and you'd want to transform each attached vertex by A_t*(A_0^-1).  If you don't have an A_t provided, and instead have eg some other matrix R saying how your rotate the bone at time t, you could build A_t as A_0*R.

(also, you may want to switch to quaternion splines instead of matrices, like ivan uses; unless your keyframes are really dense, interpolating matrices is not so great ...)
Logged
Jolli
Guest
« Reply #6 on: February 02, 2010, 03:37:31 PM »

theres only 1 frame.

transform verticies by identity matrix? does that mean multiply the matricies by
[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[0,0,0,1]
?

im having hard time understanding everything
Logged
Zaphos
Guest
« Reply #7 on: February 02, 2010, 03:45:40 PM »

transform the vertices by the identity matrix means you multiply the vertices by the identity matrix.  Which really just means you leave the vertices alone; the identity matrix does nothing.  The idea is that if your 1 frame is the rest pose, then the vertices are already in that pose, so the tranformation matrices should have no effect in that case.
Logged
Jolli
Guest
« Reply #8 on: February 03, 2010, 07:23:15 PM »

i just tried multiplying armaturespace(4x4) of bone with its parents 4x4's (and parent's parent's etc) and exporting them..
still nothing tho

is that what i should be doing? :S
Logged
Zaphos
Guest
« Reply #9 on: February 03, 2010, 08:20:53 PM »

No, the armaturespace matrices should all be defined wrt the same space (armature space) so you shouldn't need to transform them up the hierarchy like that.

edit: also, you should probably be looking at the pose and posebone matrices.
« Last Edit: February 03, 2010, 08:33:07 PM by Zaphos » Logged
Jolli
Guest
« Reply #10 on: February 03, 2010, 09:00:19 PM »

ergggggggggggrggr sorry... i am lost  Sad
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic