The Forum is up for sale: XeNTaX Forum looking for new owner

Bones matrix

Post questions about game models here, or help out others!
Post Reply
MadSquirrel
ultra-n00b
Posts: 6
Joined: Fri Apr 03, 2009 4:16 pm
Has thanked: 1 time
Been thanked: 1 time

Bones matrix

Post by MadSquirrel »

Hi !

I'm trying to understand Firefall models format.
3D models are in bMesh files. The global structure of these files are quite easy to understand (just a bunch of Nb of data / data sections)
Until now, I have the mesh object, and I'm trying to add the bones.

Each bones has a name, parent index, and 2 matrix 4x4. It's the first time I am playing with 3D file structures, and I don't know what to do with these matrix.
Both matrix look "standard" (from what I found on the web) :

Code: Select all

[a b c 0]
[d e f 0]
[g h i 0]
[x y z 1]
(x, y, z) of the first matrix seems to be the coordinates of the head of the bone. What about tail coordinates ? length ? roll ? Does the matrix contains all these parameters ? What is the purpose of the second matrix ?

Can anyone point me in the right direction ? :)

Thanks.

Can't attach sample file ... Will find another way to send it.
fatduck
mega-veteran
mega-veteran
Posts: 315
Joined: Wed Aug 02, 2006 10:07 pm
Has thanked: 10 times
Been thanked: 94 times

Re: Bones matrix

Post by fatduck »

The matrix you are talking here is a combined form of Translation, Rotation and Scale in 3D world.
Look here for detail explanation
No more Fatduck, no more FatImporter, Byebye everyone!
MadSquirrel
ultra-n00b
Posts: 6
Joined: Fri Apr 03, 2009 4:16 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Bones matrix

Post by MadSquirrel »

Thanks for the link, it brings back memories ! :)
It's about 15 years that I didn't "play" with matrix, so I know what is coded inside, but I just don't remember exactly how to use it.

To build my bone, I need head and tail coordinates. I got the head, but how can I get the tail ? I tried all kind of operations with the head vector and the matrix, without success. For "simple" bone chain, like a leg, or spine, I assume the tail of the parent bone should be at the same place as the head of the child. But with all my matrix manipulations, I could not find such result. I probably miss something obvious !

Moreover, why 2 matrix for each bone ?
b0ny
mega-veteran
mega-veteran
Posts: 239
Joined: Sat May 22, 2010 10:10 am
Has thanked: 22 times
Been thanked: 121 times

Re: Bones matrix

Post by b0ny »

are you importing to blender?
as far as i know games usually have node based bones which do not have tails(required by blender), and in blender you have to find how many children a bone have and to decide which bones should be connected. but this messes things even more because the animation for node bones assumes by default that the bones vectors are pointing "down", and when you connect bones you change they're direction in space.

you shouldn't really count on this info. go google for "bones", "import" and "blender", or something like that to find out what is this all about...
MadSquirrel
ultra-n00b
Posts: 6
Joined: Fri Apr 03, 2009 4:16 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Bones matrix

Post by MadSquirrel »

Thanks for the info :)

Yes, I am working with Blender. I am not exactly "importing". I am writing an API to create blender files. So when it's ready, it should be quite easy to add an "export to .blend" function, in 3D viewers programs like Noesis, WowModelViewer, or 3D object converter for example.
I'm at the very begining, so now I can only create a blend file with meshes (from a list of vertex coords, and a list of faces).

Moreover, it's a long time I want to try "3D model reversing". So I decided to kill two birds with one stone, and decrypt Firefall 3D models to test my API. Maybe I was too greedy :) I think I will give up Firefall for now, and test with WoW models. The format is well documented, and I already worked on WowModelViewer a few years ago, so it should be easier for me.

Just for information (maybe it can be useful to someone) :
- About Firefall bones : I didn't understand why they store 2 matrix 4x4 for each bone. Well, I still don't understand, but I found that the second matrix is the first one inverted ! Matrix inverse is a quite fast operation, so why not doing it at runtime ? Why storing both a matrix and its inverted ?
- About Blender bones : I converted a Firefall model (with bones) as blend file. Of course, bones were upside down (except heads on the correct position). I manually corrected a few bones position, and "explored" the resulting blend file. The matrix 4x4 in the blend file has many common values with the Matrix 4x4 of the Firefall file. Only 4 values seems to come from nowhere. This could be the rotation part of the matrix, and so, this could confirm your theory about the change of direction when connecting bones in Blender.

EDIT : A question suddenly comes to my mind : If games usually use node based bones, then only 3 coordinates are needed, to place the bone. So ... why a matrix 4x4 ?
User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 4231
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 1139 times
Been thanked: 2222 times

Re: Bones matrix

Post by shakotay2 »

MadSquirrel wrote:EDIT : A question suddenly comes to my mind : If games usually use node based bones, then only 3 coordinates are needed, to place the bone. So ... why a matrix 4x4 ?
The answer might be: quarternions:
http://www.cprogramming.com/tutorial/3d ... nions.html
Tuts: a) Bigchillghost, viewtopic.php?f=29&t=17889
b) Extracting simple models: http://forum.xentax.com/viewtopic.php?f=29&t=10894
"Quoting the whole thing. Would u ever stop this nonsense?"
MadSquirrel
ultra-n00b
Posts: 6
Joined: Fri Apr 03, 2009 4:16 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Bones matrix

Post by MadSquirrel »

Very interesting website, thanks ! :)
User avatar
Bastien
advanced
Posts: 70
Joined: Sun Apr 15, 2012 1:08 am
Has thanked: 27 times
Been thanked: 13 times

Re: Bones matrix

Post by Bastien »

I had the same problem with blender, "how the hell get the tail position".
Now, did you verify that the first Matrix is the head position of each bone? The first bone is the root bone always and the rest might or might not be given in relative-to-the-parent space.
You can easily check that in blender by creating empties using the matrices provided.
But I read you already could import the bones ?

btw, creating a blend file sounds very interesting, I don't recall any other exporter like that, could be very useful.
MadSquirrel
ultra-n00b
Posts: 6
Joined: Fri Apr 03, 2009 4:16 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Bones matrix

Post by MadSquirrel »

Yes, I "nearly" got the bones. The first matrix give the head position, but each vector in the matrix is normalized, so there is no way to get the tail position from the matrix. But it doesn't matter, only the bone direction is important. So I calculate the tail position from the direction vector (arbitrary, 1/20th of it). All the bones have the same length, but it souldn't be a problem.
Now I just fight with math to get the roll angle of the bones :)
You do not have the required permissions to view the files attached to this post.
User avatar
Bastien
advanced
Posts: 70
Joined: Sun Apr 15, 2012 1:08 am
Has thanked: 27 times
Been thanked: 13 times

Re: Bones matrix

Post by Bastien »

These functions take the translations and give you the roll and tail positions. Since they are node bases, the bones will be pointing forward, not very nice for animation, but it's something.
The official SMD importer for blender deals with making the bones very small and assigning a sphere shape.
Source: BA

I tried it for only one game and worked very well, only thing also is that all bones in blender are assigned in armature space, while many games have the transform matrix in parent space, so you have to multiply the parent matrix by the child matrix to get the world (armature space) matrix. If it has multiple parents, all must be multiplied.

Code:

Code: Select all

import bpy,math,mathutils

def vec_roll_to_mat3(vec, roll):
    target = mathutils.Vector((0,1,0))
    nor = vec.normalized()
    axis = target.cross(nor)
    if axis.dot(axis) > 0.0000000001: # this seems to be the problem for some bones, no idea how to fix
        axis.normalize()
        theta = target.angle(nor)
        bMatrix = mathutils.Matrix.Rotation(theta, 3, axis)
    else:
        updown = 1 if target.dot(nor) > 0 else -1
        bMatrix = mathutils.Matrix.Scale(updown, 3)
        
        # C code:
        #bMatrix[0][0]=updown; bMatrix[1][0]=0.0;    bMatrix[2][0]=0.0;
        #bMatrix[0][1]=0.0;    bMatrix[1][1]=updown; bMatrix[2][1]=0.0;
        #bMatrix[0][2]=0.0;    bMatrix[1][2]=0.0;    bMatrix[2][2]=1.0;
        bMatrix[2][2] = 1.0
        
    rMatrix = mathutils.Matrix.Rotation(roll, 3, nor)
    mat = rMatrix * bMatrix
    return mat

def mat3_to_vec_roll(mat):
    vec = mat.col[1]
    vecmat = vec_roll_to_mat3(mat.col[1], 0)
    vecmatinv = vecmat.inverted()
    rollmat = vecmatinv * mat
    roll = math.atan2(rollmat[0][2], rollmat[2][2])
    return vec, roll

Usage:

Code: Select all

pos = mymatrix.to_translation()
axis, roll = mat3_to_vec_roll(mymatrix.to_3x3())
                
bone = armature.edit_bones.new('name')
bone.head = pos
bone.tail = pos + axis
bone.roll = roll
MadSquirrel
ultra-n00b
Posts: 6
Joined: Fri Apr 03, 2009 4:16 pm
Has thanked: 1 time
Been thanked: 1 time

Re: Bones matrix

Post by MadSquirrel »

I'll try it. Thanks :)
Post Reply