+ int major_axis = 0;
+ float largest = -1.0f;
+
+ for( int i=0; i<3; i ++ ){
+ if( fabsf( v0[i] ) > largest ){
+ largest = fabsf( v0[i] );
+ major_axis = i;
+ }
+ }
+
+ v3_zero( v1 );
+ v1[ major_axis ] = 1.0f;
+ rb_tangent_basis( v1, tx, ty );
+
+ float r = (fabsf(v3_dot(tx,v0)) + fabsf(v3_dot(ty,v0))) * 0.25f,
+ l = fabsf(v0[ major_axis ]);
+
+ /* orientation */
+ v3_muls( tx, -1.0f, rp->collider_mtx[0] );
+ v3_muls( v1, -1.0f, rp->collider_mtx[1] );
+ v3_muls( ty, -1.0f, rp->collider_mtx[2] );
+ v3_add( bone->hitbox[0], bone->hitbox[1], rp->collider_mtx[3] );
+ v3_muls( rp->collider_mtx[3], 0.5f, rp->collider_mtx[3] );
+
+ rp->rb.type = k_rb_shape_capsule;
+ rp->rb.inf.capsule.height = l;
+ rp->rb.inf.capsule.radius = r;
+
+ rp->colour = 0xff000000 | (0xff << (major_axis*8));
+ }
+ else
+ vg_fatal_exit_loop( "Invalid bone collider type" );
+
+ m4x3_invert_affine( rp->collider_mtx, rp->inv_collider_mtx );
+
+ /* Position collider into rest */
+ m3x3_q( rp->collider_mtx, rp->rb.q );
+ v3_add( rp->collider_mtx[3], bone->co, rp->rb.co );
+ rp->rb.is_world = 0;
+ rb_init( &rp->rb );
+}
+
+/*
+ * Get parent index in the ragdoll
+ */
+VG_STATIC u32 ragdoll_bone_parent( struct player_ragdoll *rd,
+ struct player_avatar *av, u32 bone_id )
+{
+ for( u32 j=0; j<rd->part_count; j++ )
+ if( rd->parts[ j ].bone_id == bone_id )
+ return j;
+
+ vg_fatal_exit_loop( "Referenced parent bone does not have a rigidbody" );
+ return 0;
+}