19 m4x3f
*final_transforms
;
23 u32 lower
, upper
, target
, pole
;
31 struct mdl_keyframe
*anim_data
;
39 bindable_count
; /* TODO: try to place IK last in the rig from export
40 so that we dont always upload transforms for
41 useless cpu IK bones. */
44 static void skeleton_apply_frame( m4x3f transform
,
45 struct skeleton
*skele
,
46 struct skeleton_anim
*anim
,
49 float animtime
= time
*anim
->rate
;
51 u32 frame
= ((u32
)animtime
) % anim
->length
,
52 next
= (frame
+1) % anim
->length
;
54 float t
= vg_fractf( animtime
);
56 mdl_keyframe
*base
= anim
->anim_data
+ (skele
->bone_count
-1)*frame
,
57 *nbase
= anim
->anim_data
+ (skele
->bone_count
-1)*next
;
59 m4x3_copy( transform
, skele
->final_transforms
[0] );
61 for( int i
=1; i
<skele
->bone_count
; i
++ )
63 struct skeleton_bone
*sb
= &skele
->bones
[i
];
69 v3_sub( skele
->bones
[i
].co
, skele
->bones
[sb
->parent
].co
, temp_delta
);
72 mdl_keyframe
*kf
= base
+i
-1,
79 v3_lerp( kf
->co
, nkf
->co
, t
, co
);
80 q_nlerp( kf
->q
, nkf
->q
, t
, q
);
81 v3_lerp( kf
->s
, nkf
->s
, t
, s
);
84 v3_copy( co
, posemtx
[3] );
85 v3_add( temp_delta
, posemtx
[3], posemtx
[3] );
88 m4x3_mul( skele
->final_transforms
[ sb
->parent
], posemtx
,
89 skele
->final_transforms
[i
] );
92 /* armature space -> bone space matrix ( for verts ) */
93 for( int i
=1; i
<skele
->bone_count
; i
++ )
96 m3x3_identity( abmtx
);
97 v3_negate( skele
->bones
[i
].co
, abmtx
[3] );
98 m4x3_mul( skele
->final_transforms
[i
], abmtx
,
99 skele
->final_transforms
[i
] );
104 * Get transformed position of bone
106 static void skeleton_bone_posepos( struct skeleton
*skele
, u32 id
, v3f co
)
108 m4x3_mulv( skele
->final_transforms
[id
], skele
->bones
[id
].co
, co
);
112 * creates the reference inverse matrix for an IK bone, as it has an initial
113 * intrisic rotation based on the direction that the IK is setup..
115 static void skeleton_inverse_for_ik( struct skeleton
*skele
,
117 u32 id
, m4x3f inverse
)
119 v3_copy( ivaxis
, inverse
[0] );
120 v3_copy( skele
->bones
[id
].end
, inverse
[1] );
121 v3_normalize( inverse
[1] );
122 v3_cross( inverse
[0], inverse
[1], inverse
[2] );
123 v3_copy( skele
->bones
[id
].co
, inverse
[3] );
124 m4x3_invert_affine( inverse
, inverse
);
128 * Apply all IK modifiers (2 bone ik reference from blender is supported)
130 static void skeleton_apply_ik_pass( struct skeleton
*skele
)
132 for( int i
=0; i
<skele
->ik_count
; i
++ )
134 struct skeleton_ik
*ik
= &skele
->ik
[i
];
136 v3f v0
, /* base -> target */
137 v1
, /* base -> pole */
144 skeleton_bone_posepos( skele
, ik
->lower
, co_base
);
145 skeleton_bone_posepos( skele
, ik
->target
, co_target
);
146 skeleton_bone_posepos( skele
, ik
->pole
, co_pole
);
148 v3_sub( co_target
, co_base
, v0
);
149 v3_sub( co_pole
, co_base
, v1
);
150 v3_cross( v0
, v1
, vaxis
);
151 v3_normalize( vaxis
);
153 v3_cross( vaxis
, v0
, v1
);
155 /* localize problem into [x:v0,y:v1] 2d plane */
156 v2f base
= { v3_dot( v0
, co_base
), v3_dot( v1
, co_base
) },
157 end
= { v3_dot( v0
, co_target
), v3_dot( v1
, co_target
) },
160 /* Compute angles (basic trig)*/
162 v2_sub( end
, base
, delta
);
165 l1
= v3_length( skele
->bones
[ik
->lower
].end
),
166 l2
= v3_length( skele
->bones
[ik
->upper
].end
),
167 d
= vg_clampf( v2_length(delta
), fabsf(l1
- l2
), l1
+l2
-0.00001f
),
168 c
= acosf( (l1
*l1
+ d
*d
- l2
*l2
) / (2.0f
*l1
*d
) ),
169 rot
= atan2f( delta
[1], delta
[0] ) + c
- VG_PIf
/2.0f
;
171 knee
[0] = sinf(-rot
) * l1
;
172 knee
[1] = cosf(-rot
) * l1
;
174 m4x3_identity( skele
->final_transforms
[ik
->lower
] );
175 m4x3_identity( skele
->final_transforms
[ik
->upper
] );
177 /* inverse matrix axis '(^axis,^bone,...)[base] */
179 v3f iv0
, iv1
, ivaxis
;
180 v3_sub( skele
->bones
[ik
->target
].co
, skele
->bones
[ik
->lower
].co
, iv0
);
181 v3_sub( skele
->bones
[ik
->pole
].co
, skele
->bones
[ik
->lower
].co
, iv1
);
182 v3_cross( iv0
, iv1
, ivaxis
);
183 v3_normalize( ivaxis
);
185 skeleton_inverse_for_ik( skele
, ivaxis
, ik
->lower
, inverse
);
187 /* create rotation matrix */
189 v3_muladds( co_base
, v0
, knee
[0], co_knee
);
190 v3_muladds( co_knee
, v1
, knee
[1], co_knee
);
191 vg_line( co_base
, co_knee
, 0xff00ff00 );
194 v3_copy( vaxis
, transform
[0] );
195 v3_muls( v0
, knee
[0], transform
[1] );
196 v3_muladds( transform
[1], v1
, knee
[1], transform
[1] );
197 v3_normalize( transform
[1] );
198 v3_cross( transform
[0], transform
[1], transform
[2] );
199 v3_copy( co_base
, transform
[3] );
201 m4x3_mul( transform
, inverse
, skele
->final_transforms
[ik
->lower
] );
203 /* 'upper' or knee bone */
204 skeleton_inverse_for_ik( skele
, ivaxis
, ik
->upper
, inverse
);
206 v3_copy( vaxis
, transform
[0] );
207 v3_sub( co_target
, co_knee
, transform
[1] );
208 v3_normalize( transform
[1] );
209 v3_cross( transform
[0], transform
[1], transform
[2] );
210 v3_copy( co_knee
, transform
[3] );
212 m4x3_mul( transform
, inverse
, skele
->final_transforms
[ik
->upper
] );
216 static struct skeleton_anim
*skeleton_get_anim( struct skeleton
*skele
,
219 for( int i
=0; i
<skele
->anim_count
; i
++ )
221 struct skeleton_anim
*anim
= &skele
->anims
[i
];
223 if( !strcmp( anim
->name
, name
) )
230 /* Setup an animated skeleton from model */
231 static int skeleton_setup( struct skeleton
*skele
, mdl_header
*mdl
)
233 u32 bone_count
= 1, skeleton_root
= 0, ik_count
= 0;
234 skele
->bone_count
= 0;
236 skele
->final_transforms
= NULL
;
239 struct classtype_skeleton
*inf
= NULL
;
241 for( u32 i
=0; i
<mdl
->node_count
; i
++ )
243 mdl_node
*pnode
= mdl_node_from_id( mdl
, i
);
245 if( pnode
->classtype
== k_classtype_skeleton
)
247 inf
= mdl_get_entdata( mdl
, pnode
);
248 if( skele
->bone_count
)
250 vg_error( "Multiple skeletons in model file\n" );
254 skele
->bone_count
= inf
->channels
;
255 skele
->ik_count
= inf
->ik_count
;
256 skele
->bones
= malloc(sizeof(struct skeleton_bone
)*skele
->bone_count
);
257 skele
->ik
= malloc(sizeof(struct skeleton_ik
)*skele
->ik_count
);
260 else if( skele
->bone_count
)
262 int is_ik
= pnode
->classtype
== k_classtype_ik_bone
,
263 is_bone
= (pnode
->classtype
== k_classtype_bone
) || is_ik
;
267 if( bone_count
== skele
->bone_count
)
269 vg_error( "too many bones (%u/%u) @%s!\n",
270 bone_count
, skele
->bone_count
,
271 mdl_pstr( mdl
, pnode
->pstr_name
));
276 struct skeleton_bone
*sb
= &skele
->bones
[bone_count
];
278 v3_copy( pnode
->co
, sb
->co
);
279 v3_copy( pnode
->s
, sb
->end
);
280 sb
->parent
= pnode
->parent
-skeleton_root
;
284 struct classtype_ik_bone
*ik_inf
= mdl_get_entdata( mdl
, pnode
);
285 sb
->deform
= ik_inf
->deform
;
286 sb
->ik
= 1; /* TODO: place into new IK array */
287 skele
->bones
[ sb
->parent
].ik
= 1;
289 if( ik_count
== skele
->ik_count
)
291 vg_error( "Too many ik bones, corrupt model file\n" );
295 struct skeleton_ik
*ik
= &skele
->ik
[ ik_count
++ ];
296 ik
->upper
= bone_count
;
297 ik
->lower
= sb
->parent
;
298 ik
->target
= ik_inf
->target
;
299 ik
->pole
= ik_inf
->pole
;
303 struct classtype_bone
*bone_inf
= mdl_get_entdata( mdl
, pnode
);
304 sb
->deform
= bone_inf
->deform
;
319 vg_error( "No skeleton in model\n" );
323 if( bone_count
!= skele
->bone_count
)
325 vg_error( "Loaded %u bones out of %u\n", bone_count
, skele
->bone_count
);
329 if( ik_count
!= skele
->ik_count
)
331 vg_error( "Loaded %u ik bones out of %u\n", ik_count
, skele
->ik_count
);
335 /* fill in implicit root bone */
336 v3_zero( skele
->bones
[0].co
);
337 v3_copy( (v3f
){0.0f
,1.0f
,0.0f
}, skele
->bones
[0].end
);
338 skele
->bones
[0].parent
= 0xffffffff;
340 skele
->final_transforms
= malloc( sizeof(m4x3f
) * skele
->bone_count
);
341 skele
->anim_count
= inf
->anim_count
;
342 skele
->anims
= malloc( sizeof(struct skeleton_anim
) * inf
->anim_count
);
344 for( int i
=0; i
<inf
->anim_count
; i
++ )
346 mdl_animation
*anim
=
347 mdl_animation_from_id( mdl
, inf
->anim_start
+i
);
349 skele
->anims
[i
].rate
= anim
->rate
;
350 skele
->anims
[i
].length
= anim
->length
;
351 strncpy( skele
->anims
[i
].name
, mdl_pstr(mdl
, anim
->pstr_name
), 32 );
353 u32 total_keyframes
= (skele
->bone_count
-1)*anim
->length
;
354 size_t block_size
= sizeof(mdl_keyframe
) * total_keyframes
;
355 mdl_keyframe
*dst
= malloc( block_size
);
357 skele
->anims
[i
].anim_data
= dst
;
358 memcpy( dst
, mdl_get_animdata( mdl
, anim
), block_size
);
361 vg_success( "Loaded skeleton with %u bones\n", skele
->bone_count
);
365 free( skele
->bones
);
370 static void skeleton_debug( struct skeleton
*skele
)
372 for( int i
=0; i
<skele
->bone_count
; i
++ )
374 struct skeleton_bone
*sb
= &skele
->bones
[i
];
377 v3_copy( sb
->co
, p0
);
378 v3_add( p0
, sb
->end
, p1
);
379 //vg_line( p0, p1, 0xffffffff );
381 m4x3_mulv( skele
->final_transforms
[i
], p0
, p0
);
382 m4x3_mulv( skele
->final_transforms
[i
], p1
, p1
);
388 vg_line( p0
, p1
, 0xff0000ff );
392 vg_line( p0
, p1
, 0xffcccccc );
396 vg_line( p0
, p1
, 0xff00ffff );
400 #endif /* SKELETON_H */