Skip to content

Adding bone support to CRF

Stan Bobovych edited this page Jan 11, 2016 · 22 revisions
Joint count 33
0x1be9L
Bone id: 0
Joint id: 0
Matrix: 
(-2.264936966867026e-07, 1.3430886838250444e-06, -1.0)
(1.0, -7.549759573066694e-08, -2.264937961626856e-07)
(-7.549790126404332e-08, -1.0, -1.3430886838250444e-06)
(-8.838932037353516, 6.673181474070589e-07, 2.0019633666379377e-06)
Parent: 4294967295
Skeleton index: 0
Unknown: 39, 7

0x1c29L
Bone id: 1
Joint id: 1
Matrix: 
(1.1602712675085058e-06, -2.8182357709738426e-06, -1.0)
(0.9999997019767761, -0.0007963934913277626, 1.1625153319982928e-06)
(-0.0007963934331201017, -0.9999996423721313, 2.8173108148621395e-06)
(-10.143797874450684, 0.30066409707069397, -1.0689792361517902e-05)
Parent: 0
Skeleton index: 3
Unknown: 11, 18

0x1c69L
Bone id: 2
Joint id: 2
Matrix: 
(1.1602712675085058e-06, -2.8182357709738426e-06, -1.0)
(0.9999997019767761, -0.0007963934913277626, 1.1625153319982928e-06)
(-0.0007963934331201017, -0.9999996423721313, 2.8173108148621395e-06)
(-12.329859733581543, 0.30260133743286133, -1.0695164746721275e-05)
Parent: 1
Skeleton index: 4
Unknown: 14, 16

0x1ca9L
Bone id: 3
Joint id: 3
Matrix: 
(1.159144062512496e-06, -2.8409156129782787e-06, -1.0)
(0.9997830390930176, -0.020830880850553513, 1.2180713611087413e-06)
(-0.020830878987908363, -0.9997829794883728, 2.816153255480458e-06)
(-14.753691673278809, 0.5991267561912537, -1.1517274288053159e-05)
Parent: 2
Skeleton index: 24
Unknown: 54, 23

0x1ce9L
Bone id: 4
Joint id: 4
Matrix: 
(1.1499529364300543e-06, -2.9470515983121004e-06, -1.0)
(0.9948524236679077, -0.1013341024518013, 1.4426702819037018e-06)
(-0.1013341099023819, -0.9948524832725525, 2.815351990648196e-06)
(-15.684134483337402, 1.869166612625122, -1.5425055607920513e-05)
Parent: 3
Skeleton index: 7
Unknown: 27, 26
....
Bone count 33
ID: 0, Name: Bone01_Pelvis, Children: [1], Unknown: 70, 27, 154, 4
ID: 21, Name: Bone01_R_Finger1, Children: [22], Unknown: 51, 178, 159, 23
ID: 9, Name: Bone01_L_Finger0, Children: [10], Unknown: 214, 202, 131, 37
ID: 1, Name: Bone01_Spine, Children: [2, 25, 29], Unknown: 17, 244, 75, 62
ID: 2, Name: Bone01_Spine1, Children: [3], Unknown: 171, 147, 74, 76
ID: 15, Name: Bone01_R_Clavicle, Children: [16], Unknown: 24, 232, 152, 86
ID: 30, Name: Bone01_R_Calf, Children: [31], Unknown: 196, 164, 225, 89
ID: 4, Name: Bone01_Head, Children: [], Unknown: 183, 108, 161, 93
ID: 18, Name: Bone01_R_Hand, Children: [19, 21, 23], Unknown: 165, 130, 152, 96
ID: 11, Name: Bone01_L_Finger1, Children: [12], Unknown: 92, 15, 125, 100
ID: 8, Name: Bone01_L_Hand, Children: [9, 11, 13], Unknown: 243, 139, 68, 111
ID: 26, Name: Bone01_L_Calf, Children: [27], Unknown: 208, 43, 157, 115
....

those matrices are the world transforms of the bind pose for each joint

In Blender:

from bpy_extras.io_utils import axis_conversion
import mathutils

m = mathutils.Matrix(crf_joint.matrix)
m = m.inverted().transposed()

joint matrix 1

rot = axis_conversion(from_forward='-Z', from_up='Y').to_4x4()
m = rot * m

joint matrix 2

Lastly, the matrix needs to be flipped across the x axis.

rot = axis_conversion(from_forward='-Z', from_up='Y').to_4x4()
m = rot * m
m[0][3] = -m[0][3] # flip across x axis

Using this information, it's possible to create an armature.
joint matrix 2

CRF has a list of joints and their relationships, not bones. Blender does not support bones of length 0. The matrices are just translations for each joint in world coordinates. Show join positions as spheres. Create bones between joints. Terminating joints, like fingers, create a bone that has same direction as parent bone.

Next, blendweights for each vertex are needed.
Hands, buffer0 layout code in PIX:

/* Specify buffer layout with type/name pairs, e.g. "float3 position;"
   HLSL Base types: bool, byte, short, int, half, float, double
   HLSL Vector Types: float3, vector<uint,3>, float3x3, matrix<xshort,2,2>
   Modifiers for byte/short/int: s=signed, u=unsigned, x=unsigned hex */

float3 positions;
xbyte4 diffuse;
xbyte4 specular;
short2 texcoord0;
short2 texcoord1;
ubyte4 unknown;

Hands, buffer1 layout code in PIX:

/* Specify buffer layout with type/name pairs, e.g. "float3 position;"
   HLSL Base types: bool, byte, short, int, half, float, double
   HLSL Vector Types: float3, vector<uint,3>, float3x3, matrix<xshort,2,2>
   Modifiers for byte/short/int: s=signed, u=unsigned, x=unsigned hex */

ubyte4 blendweight;
byte4 blendindices;

Some skinned meshes, such as helmets, hair, etc, have 3 streams. First stream has the vertex position, normals, UVs and perhaps blendweights (though they do not add up to 1), second stream is some unknown stream made of 2 floats for each vertex, and the third stream is 4 blendindices that are 0.
Stream with declaration 0xc has blend index/weights.

Models have a mapping table that map blendindices to bone IDs.

Skeleton:
	Mesh: 0, map of blendindices to bones (7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24)
	Mesh: 1, map of blendindices to bones (0, 1, 2, 3, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19)

skinned bone

CAF animation
First byte may be 2x the number of joints in model. Offset 0x34 is possible joint count.