27430b444b6eb343e8af6d305c5f780c6b9415b0
[carveJwlIkooP6JGAAIwe30JlM.git] / character.h
1 #ifndef CHARACTER_H
2 #define CHARACTER_H
3
4 #include "vg/vg.h"
5 #include "model.h"
6 #include "ik.h"
7
8 #define FOREACH_PART(FN) \
9 FN( body0 ) \
10 FN( body1 ) \
11 FN( neck ) \
12 FN( head ) \
13 FN( arm_l0 ) \
14 FN( arm_l1 ) \
15 FN( hand_l ) \
16 FN( arm_r0 ) \
17 FN( arm_r1 ) \
18 FN( hand_r ) \
19 FN( leg_l0 ) \
20 FN( leg_l1 ) \
21 FN( foot_l ) \
22 FN( leg_r0 ) \
23 FN( leg_r1 ) \
24 FN( foot_r ) \
25 FN( wheels ) \
26 FN( board ) \
27
28 #define MAKE_ENUM(ENUM) k_chpart_##ENUM,
29 #define MAKE_STRING(STR) #STR,
30 #define ADD_ONE(_) +1
31 #define PART_COUNT FOREACH_PART(ADD_ONE)
32
33 enum character_part
34 {
35 FOREACH_PART( MAKE_ENUM )
36 };
37
38 static const char *character_part_strings[] =
39 {
40 FOREACH_PART( MAKE_STRING )
41 };
42
43
44 struct character
45 {
46 glmesh mesh;
47
48 submodel parts[ PART_COUNT ];
49 m4x3f matrices[ PART_COUNT ];
50
51 /* Auxillary information */
52 v3f offsets[ PART_COUNT ];
53
54 /*
55 * Controls
56 * note: - base nodes of IK structures will be filled automatically
57 * - all positions are in local space to the mroot
58 */
59 struct ik_basic ik_arm_l, ik_arm_r,
60 ik_leg_l, ik_leg_r,
61 ik_body;
62
63 v4f qhead;
64 float rhip, rcollar, /* twist of hip and collar controls,
65 these act in the local +y axis of the part */
66 rfootl, rfootr,
67 rhandl, rhandr;
68
69 v3f ground_normal; /* Feet will be aligned to this */
70 m4x3f mroot;
71 };
72
73 static void character_offset( struct character *ch, enum character_part parent,
74 enum character_part child )
75 {
76 v3_sub( ch->parts[ child ].pivot, ch->parts[ parent ].pivot,
77 ch->offsets[ child ] );
78 }
79
80 static int character_load( struct character *ch, const char *name )
81 {
82 char buf[64];
83
84 snprintf( buf, sizeof(buf)-1, "models/%s.mdl", name );
85 model *src = vg_asset_read( buf );
86
87 if( !src )
88 {
89 vg_error( "Could not open 'models/%s.mdl'", name );
90 return 0;
91 }
92
93 int error_count = 0;
94
95 for( int i=0; i<PART_COUNT; i++ )
96 {
97 snprintf( buf, sizeof(buf)-1, "%s_%s", name, character_part_strings[i] );
98 submodel *sm = submodel_get( src, buf );
99
100 if( !sm )
101 {
102 vg_warn( "Character file does not contain an '_%s' part.\n",
103 character_part_strings[i] );
104 error_count ++;
105
106 memset( &ch->parts[i], 0, sizeof(submodel) );
107 continue;
108 }
109
110 ch->parts[i] = *sm;
111 }
112
113 model_unpack( src, &ch->mesh );
114
115 if( !error_count )
116 vg_success( "Loaded character file '%s' with no errors\n", name );
117
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 );
122
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 );
126
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 );
130
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 );
134
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 );
138
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 ] );
143
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 ] );
148
149 ch->ik_body.l1 = v3_length( ch->offsets[ k_chpart_body1 ] );
150 ch->ik_body.l2 = v3_length( ch->offsets[ k_chpart_neck ] );
151
152 free( src );
153 return 1;
154 }
155
156 static void character_eval( struct character *ch )
157 {
158 m4x3f *mats = ch->matrices;
159 v3f *offs = ch->offsets;
160
161 ik_basic( &ch->ik_body, mats[k_chpart_body0], mats[k_chpart_body1],
162 k_ikY, k_ikX );
163
164 m3x3f temp;
165 v4f body_rotation;
166 /* TODO: Do this directly via m3x3 */
167
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] );
171
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] );
175
176 /* Setup aux */
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 );
181
182 /* IK for arms and legs */
183 ik_basic( &ch->ik_arm_l, mats[k_chpart_arm_l0], mats[k_chpart_arm_l1],
184 k_ikZ, k_ikY );
185 ik_basic( &ch->ik_arm_r, mats[k_chpart_arm_r0], mats[k_chpart_arm_r1],
186 k_iknZ, k_ikY );
187 ik_basic( &ch->ik_leg_l, mats[k_chpart_leg_l0], mats[k_chpart_leg_l1],
188 k_ikY, k_iknX );
189 ik_basic( &ch->ik_leg_r, mats[k_chpart_leg_r0], mats[k_chpart_leg_r1],
190 k_ikY, k_iknX );
191
192 /* Feet */
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] );
199
200 /* Hands */
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] );
207
208 /* Neck / Head */
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] );
212
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]);
215
216 for( int i=0; i<PART_COUNT; i++ )
217 m4x3_mul( ch->mroot, ch->matrices[i], ch->matrices[i] );
218 }
219
220 static void character_testpose( struct character *ch, float t )
221 {
222 /* Body */
223 float *hips = ch->ik_body.base,
224 *collar = ch->ik_body.end,
225 *pole = ch->ik_body.pole;
226
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];
229 hips[2] = 0.0f;
230
231 collar[0] = hips[0];
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;
234
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 );
238
239 /* Legs */
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;
244
245 footl[0] = sinf(t*0.563f);
246 footl[1] = 0.0f;
247 footl[2] = 0.0f;
248
249 footr[0] = 0.0f;
250 footr[1] = 0.0f;
251 footr[2] = cosf(t*0.672f);
252
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 );
256
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 );
260
261 /* Arms */
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;
266
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 );
271
272 /* Other */
273 ch->rhip = sinf(t*0.2f);
274 ch->rcollar = sinf(t*0.35325f);
275 q_identity( ch->qhead );
276
277 m4x3_identity( ch->matrices[k_chpart_board] );
278 m4x3_identity( ch->matrices[k_chpart_wheels] );
279 }
280
281 static void character_draw( struct character *ch, int temp )
282 {
283 mesh_bind( &ch->mesh );
284
285 glEnable( GL_CULL_FACE );
286 glCullFace( GL_BACK );
287
288 for( int i=0; i<PART_COUNT; i++ )
289 {
290 glUniformMatrix4x3fv( temp, 1, GL_FALSE, (float *)ch->matrices[i] );
291 submodel_draw( &ch->parts[i] );
292 }
293 }
294
295 #undef FOREACH_PART
296 #undef MAKE_ENUM
297 #undef MAKE_STRING
298 #undef ADD_ONE
299 #endif