27430b444b6eb343e8af6d305c5f780c6b9415b0
8 #define FOREACH_PART(FN) \
28 #define MAKE_ENUM(ENUM) k_chpart_##ENUM,
29 #define MAKE_STRING(STR) #STR,
31 #define PART_COUNT FOREACH_PART(ADD_ONE)
35 FOREACH_PART( MAKE_ENUM
)
38 static const char *character_part_strings
[] =
40 FOREACH_PART( MAKE_STRING
)
48 submodel parts
[ PART_COUNT
];
49 m4x3f matrices
[ PART_COUNT
];
51 /* Auxillary information */
52 v3f offsets
[ PART_COUNT
];
56 * note: - base nodes of IK structures will be filled automatically
57 * - all positions are in local space to the mroot
59 struct ik_basic ik_arm_l
, ik_arm_r
,
64 float rhip
, rcollar
, /* twist of hip and collar controls,
65 these act in the local +y axis of the part */
69 v3f ground_normal
; /* Feet will be aligned to this */
73 static void character_offset( struct character
*ch
, enum character_part parent
,
74 enum character_part child
)
76 v3_sub( ch
->parts
[ child
].pivot
, ch
->parts
[ parent
].pivot
,
77 ch
->offsets
[ child
] );
80 static int character_load( struct character
*ch
, const char *name
)
84 snprintf( buf
, sizeof(buf
)-1, "models/%s.mdl", name
);
85 model
*src
= vg_asset_read( buf
);
89 vg_error( "Could not open 'models/%s.mdl'", name
);
95 for( int i
=0; i
<PART_COUNT
; i
++ )
97 snprintf( buf
, sizeof(buf
)-1, "%s_%s", name
, character_part_strings
[i
] );
98 submodel
*sm
= submodel_get( src
, buf
);
102 vg_warn( "Character file does not contain an '_%s' part.\n",
103 character_part_strings
[i
] );
106 memset( &ch
->parts
[i
], 0, sizeof(submodel
) );
113 model_unpack( src
, &ch
->mesh
);
116 vg_success( "Loaded character file '%s' with no errors\n", name
);
118 /* Create the offsets */
119 character_offset( ch
, k_chpart_body0
, k_chpart_body1
);
120 character_offset( ch
, k_chpart_body1
, k_chpart_neck
);
121 character_offset( ch
, k_chpart_neck
, k_chpart_head
);
123 character_offset( ch
, k_chpart_body1
, k_chpart_arm_l0
);
124 character_offset( ch
, k_chpart_arm_l0
, k_chpart_arm_l1
);
125 character_offset( ch
, k_chpart_arm_l1
, k_chpart_hand_l
);
127 character_offset( ch
, k_chpart_body1
, k_chpart_arm_r0
);
128 character_offset( ch
, k_chpart_arm_r0
, k_chpart_arm_r1
);
129 character_offset( ch
, k_chpart_arm_r1
, k_chpart_hand_r
);
131 character_offset( ch
, k_chpart_body0
, k_chpart_leg_l0
);
132 character_offset( ch
, k_chpart_leg_l0
, k_chpart_leg_l1
);
133 character_offset( ch
, k_chpart_leg_l1
, k_chpart_foot_l
);
135 character_offset( ch
, k_chpart_body0
, k_chpart_leg_r0
);
136 character_offset( ch
, k_chpart_leg_r0
, k_chpart_leg_r1
);
137 character_offset( ch
, k_chpart_leg_r1
, k_chpart_foot_r
);
139 ch
->ik_arm_l
.l1
= v3_length( ch
->offsets
[ k_chpart_arm_l1
] );
140 ch
->ik_arm_l
.l2
= v3_length( ch
->offsets
[ k_chpart_hand_l
] );
141 ch
->ik_arm_r
.l1
= v3_length( ch
->offsets
[ k_chpart_arm_r1
] );
142 ch
->ik_arm_r
.l2
= v3_length( ch
->offsets
[ k_chpart_hand_r
] );
144 ch
->ik_leg_l
.l1
= v3_length( ch
->offsets
[ k_chpart_leg_l1
] );
145 ch
->ik_leg_l
.l2
= v3_length( ch
->offsets
[ k_chpart_foot_l
] );
146 ch
->ik_leg_r
.l1
= v3_length( ch
->offsets
[ k_chpart_leg_r1
] );
147 ch
->ik_leg_r
.l2
= v3_length( ch
->offsets
[ k_chpart_foot_r
] );
149 ch
->ik_body
.l1
= v3_length( ch
->offsets
[ k_chpart_body1
] );
150 ch
->ik_body
.l2
= v3_length( ch
->offsets
[ k_chpart_neck
] );
156 static void character_eval( struct character
*ch
)
158 m4x3f
*mats
= ch
->matrices
;
159 v3f
*offs
= ch
->offsets
;
161 ik_basic( &ch
->ik_body
, mats
[k_chpart_body0
], mats
[k_chpart_body1
],
166 /* TODO: Do this directly via m3x3 */
168 q_axis_angle( body_rotation
, (v3f
){0.0f
,1.0f
,0.0f
}, ch
->rhip
);
169 q_m3x3( body_rotation
, temp
);
170 m3x3_mul( mats
[k_chpart_body0
], temp
, mats
[k_chpart_body0
] );
172 q_axis_angle( body_rotation
, (v3f
){0.0f
,1.0f
,0.0f
}, ch
->rcollar
);
173 q_m3x3( body_rotation
, temp
);
174 m3x3_mul( mats
[k_chpart_body1
], temp
, mats
[k_chpart_body1
] );
177 m4x3_mulv( mats
[k_chpart_body0
], offs
[k_chpart_leg_l0
], ch
->ik_leg_l
.base
);
178 m4x3_mulv( mats
[k_chpart_body0
], offs
[k_chpart_leg_r0
], ch
->ik_leg_r
.base
);
179 m4x3_mulv( mats
[k_chpart_body1
], offs
[k_chpart_arm_l0
], ch
->ik_arm_l
.base
);
180 m4x3_mulv( mats
[k_chpart_body1
], offs
[k_chpart_arm_r0
], ch
->ik_arm_r
.base
);
182 /* IK for arms and legs */
183 ik_basic( &ch
->ik_arm_l
, mats
[k_chpart_arm_l0
], mats
[k_chpart_arm_l1
],
185 ik_basic( &ch
->ik_arm_r
, mats
[k_chpart_arm_r0
], mats
[k_chpart_arm_r1
],
187 ik_basic( &ch
->ik_leg_l
, mats
[k_chpart_leg_l0
], mats
[k_chpart_leg_l1
],
189 ik_basic( &ch
->ik_leg_r
, mats
[k_chpart_leg_r0
], mats
[k_chpart_leg_r1
],
193 m3x3_copy( mats
[k_chpart_leg_l1
], mats
[k_chpart_foot_l
] );
194 m3x3_copy( mats
[k_chpart_leg_r1
], mats
[k_chpart_foot_r
] );
195 m4x3_mulv( mats
[k_chpart_leg_l1
], offs
[k_chpart_foot_l
],
196 mats
[k_chpart_foot_l
][3] );
197 m4x3_mulv( mats
[k_chpart_leg_r1
], offs
[k_chpart_foot_r
],
198 mats
[k_chpart_foot_r
][3] );
201 m3x3_copy( mats
[k_chpart_arm_l1
], mats
[k_chpart_hand_l
] );
202 m3x3_copy( mats
[k_chpart_arm_r1
], mats
[k_chpart_hand_r
] );
203 m4x3_mulv( mats
[k_chpart_arm_l1
], offs
[k_chpart_hand_l
],
204 mats
[k_chpart_hand_l
][3] );
205 m4x3_mulv( mats
[k_chpart_arm_r1
], offs
[k_chpart_hand_r
],
206 mats
[k_chpart_hand_r
][3] );
209 m3x3_copy( mats
[k_chpart_body1
], mats
[k_chpart_neck
] );
210 m4x3_mulv( mats
[k_chpart_body1
], offs
[k_chpart_neck
],
211 mats
[k_chpart_neck
][3] );
213 m3x3_copy( mats
[k_chpart_neck
], mats
[k_chpart_head
] );
214 m4x3_mulv( mats
[k_chpart_neck
], offs
[k_chpart_head
], mats
[k_chpart_head
][3]);
216 for( int i
=0; i
<PART_COUNT
; i
++ )
217 m4x3_mul( ch
->mroot
, ch
->matrices
[i
], ch
->matrices
[i
] );
220 static void character_testpose( struct character
*ch
, float t
)
223 float *hips
= ch
->ik_body
.base
,
224 *collar
= ch
->ik_body
.end
,
225 *pole
= ch
->ik_body
.pole
;
227 hips
[0] = cosf(t
*1.325f
)*0.25f
;
228 hips
[1] = (sinf(t
)*0.2f
+0.6f
) * ch
->parts
[ k_chpart_body0
].pivot
[1];
232 collar
[1] = hips
[1] + (ch
->ik_body
.l1
+ch
->ik_body
.l2
)*(sinf(t
)*0.05f
+0.94f
);
233 collar
[2] = hips
[2] + cosf(t
*0.42f
)*0.01f
;
235 v3_add( hips
, collar
, pole
);
236 v3_muls( pole
, 0.5f
, pole
);
237 v3_add( pole
, (v3f
){ 1.0f
, 0.0f
, 0.0f
}, pole
);
240 float *footl
= ch
->ik_leg_l
.end
,
241 *footr
= ch
->ik_leg_r
.end
,
242 *polel
= ch
->ik_leg_l
.pole
,
243 *poler
= ch
->ik_leg_r
.pole
;
245 footl
[0] = sinf(t
*0.563f
);
251 footr
[2] = cosf(t
*0.672f
);
253 v3_add( hips
, footl
, polel
);
254 v3_muls( polel
, 0.4f
, polel
);
255 v3_add( polel
, (v3f
){ -1.0f
,0.0f
,0.0f
}, polel
);
257 v3_add( hips
, footr
, poler
);
258 v3_muls( poler
, 0.4f
, poler
);
259 v3_add( poler
, (v3f
){ -1.0f
,0.0f
,0.0f
}, poler
);
262 float *arml
= ch
->ik_arm_l
.end
,
263 *armr
= ch
->ik_arm_r
.end
;
264 polel
= ch
->ik_arm_l
.pole
;
265 poler
= ch
->ik_arm_r
.pole
;
267 v3_copy( (v3f
){ 0.0f
, 0.0f
, 1.0f
}, arml
);
268 v3_copy( (v3f
){ 0.0f
, 0.0f
,-1.0f
}, armr
);
269 v3_copy( (v3f
){ 1.0f
, 1.0f
, 0.5f
}, polel
);
270 v3_copy( (v3f
){ 1.0f
, 1.0f
,-0.5f
}, poler
);
273 ch
->rhip
= sinf(t
*0.2f
);
274 ch
->rcollar
= sinf(t
*0.35325f
);
275 q_identity( ch
->qhead
);
277 m4x3_identity( ch
->matrices
[k_chpart_board
] );
278 m4x3_identity( ch
->matrices
[k_chpart_wheels
] );
281 static void character_draw( struct character
*ch
, int temp
)
283 mesh_bind( &ch
->mesh
);
285 glEnable( GL_CULL_FACE
);
286 glCullFace( GL_BACK
);
288 for( int i
=0; i
<PART_COUNT
; i
++ )
290 glUniformMatrix4x3fv( temp
, 1, GL_FALSE
, (float *)ch
->matrices
[i
] );
291 submodel_draw( &ch
->parts
[i
] );