bone matrices in 3d formats...

Started by
25 comments, last by JoakimPdelski 13 years ago
I'm making a Blender importer/addon for a game format we're using. The format uses 4x4 inverse transform matrices for bones. I'm very puzzled because when I import the bones to Blender, or load the file in our game engine, the bone rotations seem way off.
Here are some screens:
www.postimage.org/image/258d8jh8k/
www.postimage.org/image/25889xfr8/
www.postimage.org/image/2584yuqro/

I'm sure most of you will agree that these rotations don't make any sense. Its not very likely that the 3d artists made the bones like that. The only explanation is that some 3d modellers store matrices in a different way or something.

I tried to do the same with Blender.
Seems correct:
www.postimage.org/image/252j7aeis/
www.postimage.org/image/2536ct9fo/

(note that the bones aren't connected in any of the images, because the 3d formats dont store real bones per se, only transform matrices and the scale value in the matrix is not used for the lenght of the bone (it's always 1.0)

I then tried to import other formats in Blender/3d engine and I got the same results.

However, if I play the animations created for those 3d models, everything looks exactly as it should. So this means I'm not doing anything wrong during import, because the animations would screw up if the bones had wrong angles.

What does this mean? Why should I care?
This means that I can't make a proper importer for Blender, as those angles of bones would be unusable for modding. It also means if I hand edited the bone angles or just connected the bones, then the newly exported models wouldn't be campatible with the existing animation files.

So I'm pretty stuck. I could post the importer and some sample files, but like I said it's also the case for other formats.
Why is it like this? Is this some kind of conundrum or historycal meaning? Can something be done?

this is the blender function for loading and creating the bones:

def read_joint(index, file_object):
# 64 byte matrix (16* 4byte float), 4x4, inverse
data_chunk = file_object.read(64)
rawlist = struct.unpack_from('<16f', data_chunk) # '<16f' = "little endian, 16* float (4 byte)"
r0 = [[rawlist for i in range(el,el+4)] for el in range(0, 15, 4)]

# create a Blender matrix
bmat = Blender.Mathutils.Matrix(r0[0],r0[1],r0[2],r0[3])

bmat.invert() # inverts this matrix

# You need to set this explicitly.
skeleton.makeEditable()

newBone = Blender.Armature.Editbone()

newBone.matrix = bmat

armature.update()


heres an example skeleton with the weird bone angles, in blend format:
www.megaupload.com/?d=H72YS2Q8
Advertisement
I don't know about blender exactly, but in Maya, the modeling program doesn't care how the bones are laid out in the file. The only thing that matters is how you constrain them. That means at work we'll end up with many models where many of the bones point "back" or "down", because it is easiest to just lay out the bones from some ortho projection resulting in many of them "facing" in one direction, and not along the limb. You can always constrain them on any axis you want, so, to the artists, it usually only matters that some axis points down the length of the limb.

From a gameplay perspective, that means it is impossible to use bones for game data, as they are effectively pointing in random directions. We resort to skinning attachment point matrices placed on the model. That way, the skinned attachment will point in the correct direction. This only means storing a single bone-relative-matrix for each attach point.
i don't think that answers my question, or maybe you didnt get what I mean?
bump
Might not be entirely relevant, but I know that when I started with quaternions, I had many bone joints with rotation quaternions that were wildly incorrect. It turned out, that the quaternions that were out of the correct range were actually synonymous, and weren't handled properly.

Such as, sin(90 degrees) is the same as sin(450 degrees), but for a function that expects degrees in the range 0 <= x < 360, the answers could be unpredictable for values outside the range. Might not be the problem, but just a thought.
First, thank you for replying.

Now then, when you say you had seemingly wrong rotations, did the animations still work as expected?
When you say "synonymous" does that mean they can be replaced with each other and not cause any problems at all?

I dont set the rotations as quaternions in Blender or the game engine and I get the same results. However, I dont know what the functions do internaly, so maybe they set them as quat in the end.

i don't think that answers my question, or maybe you didnt get what I mean?

hmmm. Maybe I didn't understand what you meant.
You have some models with what you think are invalid bone directions. Do they animate properly still? or are the bones actually messed up, and you can't get the model to skin properly because of it?

What I was getting at in my other post, if I open up one of our humanoid models here at work, we have them facing down positive Z. Looking at the bones, the "Z" or "at" of almost every single bone is pointing left-ish. The "X" or "left" of every bone is point up-ish on the right side of the model, and that is mirrored down-ish on the left side of the model. Now, if I go to some other humanoid model (still facing down +Z), all the bones are facing forward-ish, with X pointing up or down based on the side of the model. So, depending on what direction the limb is facing in the file, it wil have some axis aligned to it, but its just as likely to be any axis, positive or negative.
If you are drawing those arrow markers based solely on the bone's matrix from the exporter, then it could technically be facing anywhere and still be correct as long as SOME axis is aligned along the pivot the artist needed for that joint.

If you look at your second image, if that were in standard bind pose, almost all the bones would be facing backwards-ish or up-ish. This is almost exactly what I see in our models at work.
You have some models with what you think are invalid bone directions. Do they animate properly still? or are the bones actually messed up, and you can't get the model to skin properly because of it?[/quote]
Well, the angles seem weird, but they animate the model properly in the game engine. The animation transform matrices aren't relative to the bone transform matrix, but the vertices are, I guess. If you set the bone matrices to something insane in the modeller (or directly in the 3d file), you will notice when rendering the bones, that the bones are in place during animation, but vertices are not. I think this will be also the case if modifying only the angles.

My goal right now is to make a Blender importer for the 3d format of the game, and although I didn't have to care about how the bones looked in the game engine and it worked as long as the model animated correctly, I really need to have proper bones after import in the 3d modeller. You have to agree that it would be inconvenient to work with such bones. They need to have proper angles and be connected (I can connect after having proper angles easily). If I hand edit the bone angles in the importer, then it wont be campatible with the existing animations anymore, right? Even if it was, you can't know what bone doesnt seem right beforehand for every single model.

What I was getting at in my other post, if I open up one of our humanoid models here at work, we have them facing down positive Z. Looking at the bones, the "Z" or "at" of almost every single bone is pointing left-ish. The "X" or "left" of every bone is point up-ish on the right side of the model, and that is mirrored down-ish on the left side of the model.[/quote]
You open what? In your 3d modeller? Is it the original model file, or in the game's format? Most of what you described is also like that for me. Is there an explanation for that? Is it caused by the matrix data in the 3d modellers during export?

If you are drawing those arrow markers based solely on the bone's matrix from the exporter, then it could technically be facing anywhere and still be correct as long as SOME axis is aligned along the pivot the artist needed for that joint.[/quote]
I don't understan this.
It also looks like that when creating bones in Blender with our model importer, not just when rendering the joints with those "markers" in the game.

If you look at your second image, if that were in standard bind pose, almost all the bones would be facing backwards-ish or up-ish. This is almost exactly what I see in our models at work. [/quote]
I don't understand this too (btw bind pose is "rest pose"?)

Well, the angles seem weird, but they animate the model properly in the game engine.

Well, then the angles are probably fine.


You open what? In your 3d modeller? Is it the original model file, or in the game's format?
[/quote]
Open the original model in the original modeling program. Or, draw the skeleton in our game engine. Its the same data on both sides, I'd see the same thing.


Most of what you described is also like that for me. Is there an explanation for that? Is it caused by the matrix data in the 3d modellers during export?
[/quote]
No. This has nothing to do with importing or exporting anything. When the artists place a bone, in Maya atleast, it faces along the direction they click (either twards or away from). So, from an ortho perspective (top, front, side), placing all the bones would result in them all facing one direction. Once they've placed some bones, they'll rotate and tweak them while they assign constraints and controllers. They rotate stuff till some axis properly represents the joint, but that axis isn't the same for any particular limb.


If you look at your second image, if that were in standard bind pose, almost all the bones would be facing backwards-ish or up-ish. This is almost exactly what I see in our models at work. [/quote]
I don't understand this too (btw bind pose is "rest pose"?)
[/quote]
I've always heard of it as "bind pose", and tones of google hits show models in what i meant by "standard bind pose". The human figure making a cross shape with his body straight up and down, legs slightly spread and arms outstretched.


Animators don't use bones to animate. And the bone's don't entierly describe the skeleton in a modeling program. That might be part of your confusion. While the bones alone are enough for a game engine, that just has to skin the verts, the two other things your model importer needs, if available, is a way to import the constraints and controllers. Constraints limit rotation, length, and scale of a particular bone. You can also have IK constraints that the modeling program uses to solve where intermediate joints need to move to, so moving a hand around automatically animates the elbo and shoulder joints. You also have controllers, where the person who rigged the model can specify that "fist controller A, goes 0->1", where 0 corosponds to an open hand, and 1 corosponds to all the proper rotations to make a fist. So, animators can just slide that one controller to modify how open/closed the hand is, without dealing with the ~11 bones in an articulated hand.
Well, then the angles are probably fine.[/quote]
Which brings me to my original question: what can be done to have better rotations without making the new models unusable with the existing animations? I should have asked this earlier: Do bind pose rotations matter (are the animations relative to it)? I know positions do. If I manually rotated the bones in the negative x axis to match the ones in the other side, would the new bones play the old animations correctly?

Open the original model in the original modeling program. Or, draw the skeleton in our game engine. Its the same data on both sides, I'd see the same thing.[/quote]
I are pretty lucky then.
But are you saying you don't have the bones connected in your modeller?
Could you post some demo picture?

Animators don't use bones to animate. And the bone's don't entierly describe the skeleton in a modeling program. That might be part of your confusion. While the bones alone are enough for a game engine...

The format only uses skeletal animation.

This topic is closed to new replies.

Advertisement