Jump to content
  • Advertisement
Sign in to follow this  
IgnisDeus

What to do with odd matrix data

This topic is 4815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm exporting bone animation from maya, and the matrices for the child bones come with the translation from their parent bones in the bindpose. So if the bone is 3 units up from the parent, the matrix looks like this: 1, 0, 0, 0 0, 1, 0, 0 0, 0, 1, 0 0, 3, 0, 1 Now, if I took this matrix and applied it to all the vertices that this bone affects, they would be translated by 3 units up. Which would be a problem, as they are already in the correct position. I was thinking of just saving the bindpose translation values, and then determining for the new matrices what the real translation is by comparing to the old. For example, if the second frame has the bottom row of the matrix looking like this: 0, 4, 0, 1 I know the bone moved up 1. So I would generate the real matrix that would be applied to the vertices, which would be: 0, 4-3, 0, 1 = 0, 1, 0, 1 Is there an easier way? And on a side question: I'm going to be saving the matrices to file, not quaternions or anything, but complete matrices. Don't tell me it's not efficient, I've heard that enough lol. What I was going to ask, since the very right row in the matrix is always (going down) 0, 0, 0, 1, would there be any point of actually saving this to disk? Couldn't I just fill in the very right row during run time? Thanks for reading!

Share this post


Link to post
Share on other sites
Advertisement
I think that the easiest way for you is to correct the situation, when child vertices come in world coordinate system, not in local. This is simple, I hope. I'm not very friendly with Maya export itself, I just use it ))) My incoming models are correct, I mean, vertices are not translated, as you say they are.
It's more simple to fix export bug, then rewrite your loader and skinning algoritm.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Also if you were to convert from a world transformation to a local transformation, the correct math would involve inverting the previous matrix and then multiplying the inverted matrix and the matrix you are converting.

Let M1 be the prevous matrix and M2 be the current matrix. You want to find the matrix M3 that transforms M1 to M2, or M3 * M1 = M2. Thus M3 = M2 * inv(M1). Err, and depending on the matrices, the multiplication might go the other way, I'm not sure. The inversion is necessary because the matrices may contain rotations in addition to translations.

Share this post


Link to post
Share on other sites
Quote:
I think that the easiest way for you is to correct the situation, when child vertices come in world coordinate system, not in local.


Huh? Child vertices? Child bones?

I don't know the exact steps I need to get the bone animation working, as nobody will help me because it seems not many people know the exact steps, and google brings up nothing. From what I've learned, I need the bind pose matrix for each bone, then I need to convert them all to world space by multiplying each child by its parent, and then I need them inverted for animation. That's all I have so far. What I understood is that each bindpose matrix in local space would be an identity, and so when you multiplied them out to get world space, they would all still be an identity because you wouldn't want your vertices moving in the bind pose.

Share this post


Link to post
Share on other sites
It looks like you are set up for do weighted skinning. This is how you do it:

Suppose: the values for the bones in an animation frame (after concatenating with their parents) are A, B, C, and D. A0, B0, C0, and D0 are the "bind pose" values for the bones. v is the bind pose location of a vertex (in model space). vwi is bone i's weight for vertex v. The algorithm works like this:
    for every v
{
v' = vwAAA0-1v + vwBBB0-1v + vwCCC0-1v + vwDDD0-1v
}
Now, you can speed this up by precomputing the value of XX0-1 once per frame instead of once per vertex. X' = XX0-1.

The new algorithm looks like this:
    A' = AA0-1
B' = BB0-1
C' = CC0-1
D' = DD0-1
for every v
{
v' = vwAA'v + vwBB'v + vwCC'v + vwDD'v
}

Quote:
Original post by IgnisDeus
... since the very right row in the matrix is always (going down) 0, 0, 0, 1, would there be any point of actually saving this to disk? Couldn't I just fill in the very right row during run time?

Yes.

Share this post


Link to post
Share on other sites
Oh, and a quick explanation...

Let's assume for simplicity a vertex is weighted by a single bone. The algorithm becomes:
    for every v
{
v' = AA0-1 v
}
v is the location of the vertex in the bind pose in model space. A0 is the bone in the bind pose. A is the bone for a frame of the animation.

Here is how/why it works:

To animate a vertex, you transform it by the animated bone. However, the vertex must be in the bone's local space, but it isn't -- it is in model space. It needs to transformed into the bone's local space first -- then you can animate it.

A bone converts a vertex in the bone's local space to model space. Thus, the inverse of the bone transforms a vertex in model space to the bone's local space.

Here are the steps:

1. Transform the vertex from the bind pose location in model space to the bone's local space. You do this be multiplying the vertex by the inverse of the bind pose bone.
    v' = A0-1 v 
2. Now animate.
    v' = Av 
Combining the two steps, you get:
    v' = AA0-1 v 
One more important thing: Multiplying a vertex by a bone doesn't exactly transform it to model space (as I wrote above). It actually transforms it into the parent bone's local space. However, if you concatenate a bone with all its parents in a hierarchy, the bone will transform to model space. Thus, A and A0 above are really the values gotten by concatenating the bones with their parents.
Normally, the bind pose bones are concatenated before they are exported so they automatically transform a vertex to model space. This is because the concatenation only needs to be done once, so it might as well be done in the exporter.
Bones in an animation may or may not be concatenated with their parents by the exporter. In your case they are not, so every frame you need to concatenate each bone by all of its parents so that the bone will transform a vertex in its local space to model space.

Share this post


Link to post
Share on other sites
*gasp* Somebody explained it!! Hold on, it's still sinking in! lol

Thank you so much for replying with such very good information! I have a couple of questions though:

1)You mention "vwi is bone i's weight for vertex v". I don't believe I know this information, unless there is something I'm missing?

2)You say "v is the bind pose location of a vertex (in model space)". By model space, you mean world space right? Maya doesn't have model space, so between model space, local space, world space and object space, it gets a tiny bit confusing.

3)The first equation in the first post you made, is that if a vertex has 4 different bones acting upon it?

4)Your second post, I would do that after I had multiplied bone A by all it's parents? For example, saying I had a vertex, and it was affected by only bone C. Bone B was the parent of C, and Bone A was the parent of B. Do I just take the matrices for Bone A, multiply it by Bone B, then multiply that by Bone C, multiply that by the bindpose inverse of Bone C, and then multiply that by the vertex to get the final position of the vertex? (A * B * C * Inverse(Bindpose C) * Vertex)

Thank you so much! This lack of information has stalled my project for a good 2 weeks now, and it's refreshing to feel like you're not completely lost.

Share this post


Link to post
Share on other sites
Quote:
Original post by IgnisDeus
1)You mention "vwi is bone i's weight for vertex v". I don't believe I know this information, unless there is something I'm missing?


Each vertex should list the bones that influence it and their weights. Since the weights all add up to 1, there might be n-1 weights listed, and if there is only 1 bone, then there might be no weight since its value must be 1. If there are no weights, then perhaps you might assume that they are all equal.

Quote:
Original post by IgnisDeus
2)You say "v is the bind pose location of a vertex (in model space)". By model space, you mean world space right? Maya doesn't have model space, so between model space, local space, world space and object space, it gets a tiny bit confusing.


The difference between "model" space and "world" space (and "local" and "global") is simply a transform. "World" space in Maya could a "model" space in your game -- it's all a matter of what is relative to what. In fact, frequently you will see an animation system treat the "model-to-world" matrix as just another bone.

Quote:
Original post by IgnisDeus
3)The first equation in the first post you made, is that if a vertex has 4 different bones acting upon it?

Yes, bones A, B, C, and D. Usually, in order to speed up and simplify the code, an animation system will apply a fixed number of bones to every vertex. In my example, it was 4. If there are actually less bones influencing a vertex, then the extras will still be part of the calculation but will be set to the identity matrix or have a weight of 0.

Quote:
Original post by IgnisDeus
4)Your second post, I would do that after I had multiplied bone A by all it's parents? For example, saying I had a vertex, and it was affected by only bone C. Bone B was the parent of C, and Bone A was the parent of B. Do I just take the matrices for Bone A, multiply it by Bone B, then multiply that by Bone C, multiply that by the bindpose inverse of Bone C, and then multiply that by the vertex to get the final position of the vertex? (A * B * C * Inverse(Bindpose C) * Vertex)

Ultimately, you want to transform between bone space and model space. If C is relative to B, which is relative to A, which is relative to model space, then to make C relative to model space, you multiply it by B and A.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!