chaos caused by async
[carveJwlIkooP6JGAAIwe30JlM.git] / player_render.c
1 #ifndef PLAYER_RENDER_C
2 #define PLAYER_RENDER_C
3
4 #include "player.h"
5 #include "player_render.h"
6 #include "camera.h"
7 #include "player_model.h"
8
9 #include "shaders/model_character_view.h"
10 #include "shaders/model_board_view.h"
11
12 VG_STATIC void player_avatar_load( struct player_avatar *av, const char *path )
13 {
14 mdl_open( &av->meta, path, vg_mem.rtmemory );
15 mdl_load_metadata_block( &av->meta, vg_mem.rtmemory );
16 mdl_load_animation_block( &av->meta, vg_mem.rtmemory );
17 mdl_close( &av->meta );
18
19 struct skeleton *sk = &av->sk;
20 skeleton_setup( sk, vg_mem.rtmemory, &av->meta );
21
22 av->id_hip = skeleton_bone_id( sk, "hips" );
23 av->id_ik_hand_l = skeleton_bone_id( sk, "hand.IK.L" );
24 av->id_ik_hand_r = skeleton_bone_id( sk, "hand.IK.R" );
25 av->id_ik_elbow_l = skeleton_bone_id( sk, "elbow.L" );
26 av->id_ik_elbow_r = skeleton_bone_id( sk, "elbow.R" );
27 av->id_head = skeleton_bone_id( sk, "head" );
28 av->id_ik_foot_l = skeleton_bone_id( sk, "foot.IK.L" );
29 av->id_ik_foot_r = skeleton_bone_id( sk, "foot.IK.R" );
30 av->id_board = skeleton_bone_id( sk, "board" );
31 av->id_wheel_l = skeleton_bone_id( sk, "wheel.L" );
32 av->id_wheel_r = skeleton_bone_id( sk, "wheel.R" );
33 av->id_ik_knee_l = skeleton_bone_id( sk, "knee.L" );
34 av->id_ik_knee_r = skeleton_bone_id( sk, "knee.R" );
35 }
36
37 /* TODO: Standard model load */
38
39 VG_STATIC void player_model_load( struct player_model *mdl, const char *path )
40 {
41 vg_linear_clear( vg_mem.scratch );
42
43 mdl_context ctx;
44 mdl_open( &ctx, path, vg_mem.scratch );
45 mdl_load_metadata_block( &ctx, vg_mem.scratch );
46
47 if( !mdl_arrcount( &ctx.textures ) )
48 vg_fatal_error( "No texture in player model" );
49
50 mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 );
51 void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
52 mdl_fread_pack_file( &ctx, &tex0->file, data );
53
54 vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
55 VG_TEX2D_NEAREST|VG_TEX2D_CLAMP,
56 &mdl->texture );
57
58 mdl_async_load_glmesh( &ctx, &mdl->mesh );
59 mdl_close( &ctx );
60 }
61
62 VG_STATIC void player_board_load( struct player_board *mdl, const char *path )
63 {
64 vg_linear_clear( vg_mem.scratch );
65
66 mdl_context ctx;
67 mdl_open( &ctx, path, vg_mem.scratch );
68 mdl_load_metadata_block( &ctx, vg_mem.scratch );
69
70 mdl_array_ptr markers;
71 mdl_load_array( &ctx, &markers, "ent_marker", vg_mem.scratch );
72
73 if( !mdl_arrcount( &ctx.textures ) )
74 vg_fatal_error( "No texture in board model" );
75
76 mdl_texture *tex0 = mdl_arritm( &ctx.textures, 0 );
77 void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
78 mdl_fread_pack_file( &ctx, &tex0->file, data );
79
80 vg_tex2d_load_qoi_async( data, tex0->file.pack_size,
81 VG_TEX2D_CLAMP|VG_TEX2D_NEAREST,
82 &mdl->texture );
83
84 mdl_async_load_glmesh( &ctx, &mdl->mesh );
85 mdl_close( &ctx );
86
87 for( int i=0; i<4; i++ )
88 mdl->wheels[i].indice_count = 0;
89 for( int i=0; i<2; i++ )
90 mdl->trucks[i].indice_count = 0;
91 mdl->board.indice_count = 0;
92
93 for( u32 i=0; i<mdl_arrcount(&ctx.meshs); i++ ){
94 mdl_mesh *mesh = mdl_arritm( &ctx.meshs, i );
95
96 vg_info( "[%u]=%u:%u\n", mesh->entity_id,
97 mdl_entity_id_type( mesh->entity_id ),
98 mdl_entity_id_id( mesh->entity_id ) );
99
100 if( mdl_entity_id_type( mesh->entity_id ) != k_ent_marker )
101 continue;
102
103 u32 index = mdl_entity_id_id( mesh->entity_id );
104 ent_marker *marker = mdl_arritm( &markers, index );
105
106 mdl_submesh *sm0 = mdl_arritm( &ctx.submeshs, mesh->submesh_start );
107
108 const char *alias = mdl_pstr( &ctx, marker->pstr_alias );
109 u32 lr = marker->transform.co[0] > 0.0f? 1: 0,
110 fb = marker->transform.co[2] > 0.0f? 0: 1;
111
112 if( !strcmp( alias, "wheel" ) ){
113 u32 id = fb<<1 | lr;
114 mdl->wheels[ id ] = *sm0;
115 v3_copy( marker->transform.co, mdl->wheel_positions[ id ] );
116 }
117 else if( !strcmp( alias, "board" ) ){
118 mdl->board = *sm0;
119 v3_copy( marker->transform.co, mdl->board_position );
120 }
121 else if( !strcmp( alias, "truck" ) ){
122 mdl->trucks[ fb ] = *sm0;
123 v3_copy( marker->transform.co, mdl->truck_positions[ fb ] );
124 }
125 }
126 }
127
128 VG_STATIC void player__pre_render( player_instance *player )
129 {
130 if( _player_animate[ player->subsystem ] ){
131 player_animation res;
132 _player_animate[ player->subsystem ]( player, &res );
133
134 m4x3f transform;
135 q_m3x3( res.root_q, transform );
136 v3_copy( res.root_co, transform[3] );
137
138 struct skeleton *sk = &player->playeravatar->sk;
139
140 if( player->holdout_time > 0.0f ){
141 skeleton_lerp_pose( sk, res.pose, player->holdout_pose,
142 player->holdout_time, res.pose );
143 player->holdout_time -= vg.time_frame_delta * 2.0f;
144 }
145
146 skeleton_apply_pose( sk, res.pose, k_anim_apply_defer_ik );
147 skeleton_apply_ik_pass( sk );
148 skeleton_apply_pose( sk, res.pose, k_anim_apply_deffered_only );
149 skeleton_apply_inverses( sk );
150 skeleton_apply_transform( sk, transform );
151
152 skeleton_debug( sk );
153 }
154
155 if( _player_post_animate[ player->subsystem ] )
156 _player_post_animate[ player->subsystem ]( player );
157
158 struct player_avatar *av = player->playeravatar;
159
160 v3f vp0 = {0.0f,0.1f, player->playerboard->truck_positions[0][2]},
161 vp1 = {0.0f,0.1f, player->playerboard->truck_positions[1][2]};
162
163 struct ub_world_lighting *ubo = &get_active_world()->ub_lighting;
164 m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp0, ubo->g_board_0 );
165 m4x3_mulv( av->sk.final_mtx[ av->id_board ], vp1, ubo->g_board_1 );
166
167 if( player->rewinding ){
168 if( player->rewind_time <= 0.0f ){
169 double taken = vg.time - player->rewind_start;
170 vg_success( "Rewind took (rt, pt, tl): %f, %f, %f\n",
171 taken, player->rewind_predicted_time,
172 player->rewind_total_length );
173
174 player->rewinding = 0;
175 player->rewind_length = 1;
176 player->rewind_total_length = 0.0f;
177 player->rewind_accum = 0.0f;
178 world_global.sky_target_rate = 1.0;
179 world_global.time = world_global.last_use;
180 }
181 else{
182 world_global.sky_target_rate = -100.0;
183
184 float budget = vg.time_delta,
185 overall_length = player->rewind_length;
186
187 for( int i=0; (i<10)&&(player->rewind_time>0.0f)&&(budget>0.0f); i++ ){
188 /* Interpolate frames */
189 int i0 = floorf( player->rewind_time ),
190 i1 = VG_MIN( i0+1, player->rewind_length-1 );
191
192 struct rewind_frame *fr = &player->rewind_buffer[i0],
193 *fr1 = &player->rewind_buffer[i1];
194
195 float dist = vg_maxf( v3_dist( fr->pos, fr1->pos ), 0.001f ),
196 subl = vg_fractf( player->rewind_time ) + 0.001f,
197
198 sramp = 3.0f-(1.0f/(0.4f+0.4f*player->rewind_time)),
199 speed = sramp*28.0f + 0.5f*player->rewind_time,
200 mod = speed * (budget / dist),
201
202 advl = vg_minf( mod, subl ),
203 advt = (advl / mod) * budget;
204
205 player->dist_accum += speed * advt;
206 player->rewind_time -= advl;
207 budget -= advt;
208 }
209
210 player->rewind_time = vg_maxf( 0.0f, player->rewind_time );
211
212 float current_time = vg.time - player->rewind_start,
213 remaining = player->rewind_predicted_time - current_time;
214
215 if( player->rewind_sound_wait ){
216 if( player->rewind_predicted_time >= 6.5f ){
217 if( remaining <= 6.5f ){
218 audio_lock();
219 audio_oneshot( &audio_rewind[3], 1.0f, 0.0f );
220 audio_unlock();
221 player->rewind_sound_wait = 0;
222 }
223 }
224 else if( player->rewind_predicted_time >= 2.5f ){
225 if( remaining <= 2.5f ){
226 audio_lock();
227 audio_oneshot( &audio_rewind[2], 1.0f, 0.0f );
228 audio_unlock();
229 player->rewind_sound_wait = 0;
230 }
231 }
232 else if( player->rewind_predicted_time >= 1.5f ){
233 if( remaining <= 1.5f ){
234 audio_lock();
235 audio_oneshot( &audio_rewind[1], 1.0f, 0.0f );
236 audio_unlock();
237 player->rewind_sound_wait = 0;
238 }
239 }
240 }
241
242 int i0 = floorf( player->rewind_time ),
243 i1 = VG_MIN( i0+1, player->rewind_length-1 );
244
245 struct rewind_frame *fr = &player->rewind_buffer[i0],
246 *fr1 = &player->rewind_buffer[i1];
247
248 float sub = vg_fractf(player->rewind_time);
249
250 v3_lerp( fr->pos, fr1->pos, sub, player->cam_override_pos );
251 player->cam_override_angles[0] =
252 vg_alerpf( fr->ang[0], fr1->ang[0], sub );
253 player->cam_override_angles[1] =
254 vg_lerpf ( fr->ang[1], fr1->ang[1], sub );
255
256 float blend = player->rewind_time * 0.25f;
257 player->cam_override_strength = vg_clampf( blend, 0.0f, 1.0f );
258 }
259 }
260 else player->cam_override_strength = 0.0f;
261
262 player__cam_iterate( player );
263 }
264
265 PLAYER_API void player__render( camera *cam, player_instance *player )
266 {
267 shader_model_character_view_use();
268
269 glActiveTexture( GL_TEXTURE0 );
270 glBindTexture( GL_TEXTURE_2D, player->playermodel->texture );
271 shader_model_character_view_uTexMain( 0 );
272 shader_model_character_view_uCamera( cam->transform[3] );
273 shader_model_character_view_uPv( cam->mtx.pv );
274 shader_model_character_view_uTexSceneDepth( 1 );
275 render_fb_bind_texture( gpipeline.fb_main, 2, 1 );
276 v3f inverse;
277 render_fb_inverse_ratio( gpipeline.fb_main, inverse );
278 inverse[2] = main_camera.farz-main_camera.nearz;
279
280 shader_model_character_view_uInverseRatioDepth( inverse );
281 render_fb_inverse_ratio( NULL, inverse );
282 inverse[2] = cam->farz-cam->nearz;
283 shader_model_character_view_uInverseRatioMain( inverse );
284
285 world_instance *world = get_active_world();
286 world_link_lighting_ub( world, _shader_model_character_view.id );
287 world_bind_position_texture( world, _shader_model_character_view.id,
288 _uniform_model_character_view_g_world_depth, 2 );
289 world_bind_light_array( world, _shader_model_character_view.id,
290 _uniform_model_character_view_uLightsArray, 3 );
291 world_bind_light_index( world, _shader_model_character_view.id,
292 _uniform_model_character_view_uLightsIndex, 4 );
293
294 glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms,
295 player->playeravatar->sk.bone_count,
296 0,
297 (float *)player->playeravatar->sk.final_mtx );
298
299 mesh_bind( &player->playermodel->mesh );
300 mesh_draw( &player->playermodel->mesh );
301
302 /* draw skateboard */
303 shader_model_board_view_use();
304 glActiveTexture( GL_TEXTURE0 );
305 glBindTexture( GL_TEXTURE_2D, player->playerboard->texture );
306 shader_model_board_view_uTexMain( 0 );
307 shader_model_board_view_uCamera( cam->transform[3] );
308 shader_model_board_view_uPv( cam->mtx.pv );
309 shader_model_board_view_uTexSceneDepth( 1 );
310
311 render_fb_inverse_ratio( gpipeline.fb_main, inverse );
312 inverse[2] = main_camera.farz-main_camera.nearz;
313
314 shader_model_board_view_uInverseRatioDepth( inverse );
315 render_fb_inverse_ratio( NULL, inverse );
316 inverse[2] = cam->farz-cam->nearz;
317 shader_model_board_view_uInverseRatioMain( inverse );
318
319 world_link_lighting_ub( world, _shader_model_board_view.id );
320 world_bind_position_texture( world, _shader_model_board_view.id,
321 _uniform_model_board_view_g_world_depth, 2 );
322 world_bind_light_array( world, _shader_model_board_view.id,
323 _uniform_model_board_view_uLightsArray, 3 );
324 world_bind_light_index( world, _shader_model_board_view.id,
325 _uniform_model_board_view_uLightsIndex, 4 );
326
327 m4x3f root;
328 m4x3_copy( player->playeravatar->sk.final_mtx[player->playeravatar->id_board]
329 , root );
330
331 struct player_board *board = player->playerboard;
332 mesh_bind( &board->mesh );
333
334 if( board->board.indice_count ){
335 m4x3f mlocal;
336 m3x3_identity( mlocal );
337 v3_copy( board->board_position, mlocal[3] );
338 m4x3_mul( root, mlocal, mlocal );
339
340 shader_model_board_view_uMdl( mlocal );
341 mdl_draw_submesh( &board->board );
342 }
343
344 for( int i=0; i<2; i++ ){
345 if( !board->trucks[i].indice_count )
346 continue;
347
348 m4x3f mlocal;
349 m3x3_identity( mlocal );
350 v3_copy( board->truck_positions[i], mlocal[3] );
351 m4x3_mul( root, mlocal, mlocal );
352
353 shader_model_board_view_uMdl( mlocal );
354 mdl_draw_submesh( &board->trucks[i] );
355 }
356
357 for( int i=0; i<4; i++ ){
358 if( !board->wheels[i].indice_count )
359 continue;
360
361 m4x3f mlocal;
362 m3x3_identity( mlocal );
363 v3_copy( board->wheel_positions[i], mlocal[3] );
364 m4x3_mul( root, mlocal, mlocal );
365
366 shader_model_board_view_uMdl( mlocal );
367 mdl_draw_submesh( &board->wheels[i] );
368 }
369 }
370
371 #endif /* PLAYER_RENDER_C */