6 #include "player_model.h"
9 void player__debugtext( int size
, const char *fmt
, ... )
14 va_start( args
, fmt
);
15 vsnprintf( buffer
, 1024, fmt
, args
);
18 ui_text( vg_uictx
.cursor
, buffer
, size
, k_text_align_right
);
19 vg_uictx
.cursor
[1] += 14*size
;
26 void player__create( player_instance
*inst
)
28 static int only_once
= 0;
29 assert( only_once
== 0 );
32 inst
->input_js1h
= vg_create_named_input( "steer-h", k_input_type_axis
);
33 inst
->input_js1v
= vg_create_named_input( "steer-v", k_input_type_axis
);
34 inst
->input_grab
= vg_create_named_input( "grab", k_input_type_axis_norm
);
35 inst
->input_js2h
= vg_create_named_input( "grab-h", k_input_type_axis
);
36 inst
->input_js2v
= vg_create_named_input( "grab-v", k_input_type_axis
);
37 inst
->input_jump
= vg_create_named_input( "jump", k_input_type_button
);
38 inst
->input_push
= vg_create_named_input( "push", k_input_type_button
);
39 inst
->input_walk
= vg_create_named_input( "walk", k_input_type_button
);
40 inst
->input_walkh
= vg_create_named_input( "walk-h", k_input_type_axis
);
41 inst
->input_walkv
= vg_create_named_input( "walk-v", k_input_type_axis
);
42 inst
->input_use
= vg_create_named_input( "use", k_input_type_button
);
43 inst
->input_reset
= vg_create_named_input( "reset", k_input_type_button
);
44 inst
->input_camera
=vg_create_named_input( "camera", k_input_type_button
);
45 inst
->input_trick0
=vg_create_named_input( "trick0", k_input_type_button
);
46 inst
->input_trick1
=vg_create_named_input( "trick1", k_input_type_button
);
47 inst
->input_trick2
=vg_create_named_input( "trick2", k_input_type_button
);
49 const char *default_cfg
[] =
51 "bind steer-h gp-ls-h",
55 "bind steer-v gp-ls-v",
61 "bind grab-h gp-rs-h",
62 "bind grab-v gp-rs-v",
71 "bind trick2 gp-x", /* keyboard: m0 + m1 */
79 "bind walk-h gp-ls-h",
80 "bind walk-v -gp-ls-v",
95 for( int i
=0; i
<vg_list_size(default_cfg
); i
++ )
96 vg_execute_console_input(default_cfg
[i
]);
98 v3_zero( inst
->rb
.co
);
99 v3_zero( inst
->rb
.w
);
100 v3_zero( inst
->rb
.v
);
101 q_identity( inst
->rb
.q
);
102 m4x3_identity( inst
->rb
.to_world
);
103 m4x3_identity( inst
->rb
.to_local
);
105 inst
->rewind_length
= 0;
106 inst
->rewind_buffer
=
107 vg_linear_alloc( vg_mem
.rtmemory
,
108 sizeof(struct rewind_frame
) * PLAYER_REWIND_FRAMES
);
116 void player__use_avatar( player_instance
*player
, struct player_avatar
*av
)
118 player
->playeravatar
= av
;
119 player_setup_ragdoll_from_avatar( &player
->ragdoll
, av
);
123 void player__use_mesh( player_instance
*player
, glmesh
*mesh
)
125 player
->playermesh
= mesh
;
129 void player__use_texture( player_instance
*player
, vg_tex2d
*tex
)
131 player
->playertex
= tex
;
135 void player__bind( player_instance
*player
)
137 for( u32 i
=0; i
<vg_list_size(_player_bind
); i
++ ){
138 if( _player_bind
[i
] )
139 _player_bind
[i
]( player
);
145 * ----------------------------------------------------------------------------
148 VG_STATIC
void player_save_rewind_frame( player_instance
*player
)
150 if( player
->rewind_length
< PLAYER_REWIND_FRAMES
){
151 struct rewind_frame
*fr
=
152 &player
->rewind_buffer
[ player
->rewind_length
++ ];
154 v2_copy( player
->cam
.angles
, fr
->ang
);
155 v3_copy( player
->cam
.pos
, fr
->pos
);
157 if( player
->rewind_length
>= 2 ){
158 player
->rewind_total_length
+=
159 v3_dist( player
->rewind_buffer
[player
->rewind_length
-1].pos
,
160 player
->rewind_buffer
[player
->rewind_length
-2].pos
);
166 void player__pre_update( player_instance
*player
)
168 if( player
->rewinding
){
172 if( vg_input_button_down( player
->input_reset
) ){
173 double delta
= world_global
.time
- world_global
.last_use
;
175 if( (delta
<= RESET_MAX_TIME
) && (world_global
.last_use
!= 0.0) ){
176 player
->rewinding
= 1;
177 player
->rewind_sound_wait
= 1;
178 player
->rewind_time
= (double)player
->rewind_length
- 0.0001;
179 player_save_rewind_frame( player
);
182 audio_oneshot( &audio_rewind
[0], 1.0f
, 0.0f
);
185 /* based on testing. DONT CHANGE!
187 * time taken: y = (x^(4/5)) * 74.5
188 * inverse : x = (2/149)^(4/5) * y^(4/5)
191 float constant
= powf( 2.0f
/149.0f
, 4.0f
/5.0f
),
192 curve
= powf( player
->rewind_total_length
, 4.0f
/5.0f
);
194 player
->rewind_predicted_time
= constant
* curve
;
195 player
->rewind_start
= vg
.time
;
196 player
->subsystem
= player
->subsystem_gate
;
197 player
->rb
= player
->rb_gate_storage
;
198 v3_copy( player
->angles_storage
, player
->angles
);
200 if( _player_restore
[ player
->subsystem
] )
201 _player_restore
[ player
->subsystem
]( player
);
204 if( player
->subsystem
== k_player_subsystem_dead
){
205 __respawn( 0, NULL
);
210 audio_oneshot( &audio_rewind
[4], 1.0f
, 0.0f
);
216 if( vg_input_button_down( player
->input_camera
) ){
217 if( player
->camera_mode
== k_cam_firstperson
)
218 player
->camera_mode
= k_cam_thirdperson
;
220 player
->camera_mode
= k_cam_firstperson
;
223 if( _player_pre_update
[ player
->subsystem
] )
224 _player_pre_update
[ player
->subsystem
]( player
);
228 void player__update( player_instance
*player
)
230 if( player
->rewinding
)
233 if( _player_update
[ player
->subsystem
] )
234 _player_update
[ player
->subsystem
]( player
);
238 void player__post_update( player_instance
*player
)
240 if( player
->rewinding
)
243 if( _player_post_update
[ player
->subsystem
] )
244 _player_post_update
[ player
->subsystem
]( player
);
246 if((player
->subsystem
!= k_player_subsystem_dead
) && !player
->gate_waiting
){
247 player
->rewind_accum
+= vg
.frame_delta
;
249 if( player
->rewind_accum
> 0.25f
){
250 player
->rewind_accum
-= 0.25f
;
251 player_save_rewind_frame( player
);
256 VG_STATIC
void player_apply_transport_to_cam( m4x3f transport
)
258 /* FIXME: Applies to main_camera directly! */
260 /* Pre-emptively edit the camera matrices so that the motion vectors
264 m4x3_invert_affine( transport
, transport_i
);
265 m4x3_expand( transport_i
, transport_4
);
266 m4x4_mul( main_camera
.mtx
.pv
, transport_4
, main_camera
.mtx
.pv
);
267 m4x4_mul( main_camera
.mtx
.v
, transport_4
, main_camera
.mtx
.v
);
269 /* we want the regular transform here no the inversion */
270 m4x3_expand( transport
, transport_4
);
271 m4x4_mul( gate_camera
.mtx
.pv
, transport_4
, gate_camera
.mtx
.pv
);
272 m4x4_mul( gate_camera
.mtx
.v
, transport_4
, gate_camera
.mtx
.v
);
275 __attribute__ ((deprecated
))
276 VG_STATIC
void gate_rotate_angles( ent_gate
*gate
, v3f angles
, v3f d
)
278 v3_copy( angles
, d
);
281 v3f fwd_dir
= { cosf(angles
[0]),
284 m3x3_mulv( gate
->transport
, fwd_dir
, fwd_dir
);
286 v3_copy( angles
, d
);
287 d
[0] = atan2f( fwd_dir
[2], fwd_dir
[0] );
291 * Applies gate transport to a player_interface
294 void player__pass_gate( player_instance
*player
, ent_gate
*gate
)
296 world_routes_fracture( get_active_world(), gate
,
297 player
->rb
.co
, player
->rb
.v
);
299 player
->gate_waiting
= gate
;
300 world_routes_activate_entry_gate( get_active_world(), gate
);
302 m4x3_mulv( gate
->transport
, player
->tpv_lpf
, player
->tpv_lpf
);
303 m3x3_mulv( gate
->transport
, player
->cam_velocity_smooth
,
304 player
->cam_velocity_smooth
);
306 m3x3_copy( player
->basis
, player
->basis_gate
);
309 m3x3_q( gate
->transport
, q
);
310 q_mul( q
, player
->qbasis
, player
->qbasis
);
311 q_normalize( player
->qbasis
);
312 q_m3x3( player
->qbasis
, player
->basis
);
313 m3x3_transpose( player
->basis
, player
->invbasis
);
315 player
->subsystem_gate
= player
->subsystem
;
316 player
->rb_gate_storage
= player
->rb
;
317 v3_copy( player
->angles
, player
->angles_storage
);
318 player
->rewind_length
= 0;
319 player
->rewind_total_length
= 0.0f
;
320 player
->rewind_gate
= gate
;
321 player
->rewind_accum
= 0.0f
;
323 m4x3_mulv( gate
->transport
, player
->cam
.pos
, player
->cam
.pos
);
324 player_save_rewind_frame( player
);
326 if( gate
->type
== k_gate_type_nonlocal
)
327 world_global
.active_world
= gate
->target
;
329 world_global
.in_volume
= 0;
332 audio_oneshot( &audio_gate_pass
, 1.0f
, 0.0f
);
336 VG_STATIC
void player__pre_render( player_instance
*player
)
338 if( _player_animate
[ player
->subsystem
] ){
339 player_animation res
;
340 _player_animate
[ player
->subsystem
]( player
, &res
);
343 q_m3x3( res
.root_q
, transform
);
344 v3_copy( res
.root_co
, transform
[3] );
346 struct skeleton
*sk
= &player
->playeravatar
->sk
;
348 if( player
->holdout_time
> 0.0f
){
349 skeleton_lerp_pose( sk
, res
.pose
, player
->holdout_pose
,
350 player
->holdout_time
, res
.pose
);
351 player
->holdout_time
-= vg
.frame_delta
* 2.0f
;
354 skeleton_apply_pose( sk
, res
.pose
, k_anim_apply_defer_ik
);
355 skeleton_apply_ik_pass( sk
);
356 skeleton_apply_pose( sk
, res
.pose
, k_anim_apply_deffered_only
);
357 skeleton_apply_inverses( sk
);
358 skeleton_apply_transform( sk
, transform
);
360 skeleton_debug( sk
);
363 if( _player_post_animate
[ player
->subsystem
] )
364 _player_post_animate
[ player
->subsystem
]( player
);
366 struct player_avatar
*av
= player
->playeravatar
;
367 v3f vp0
= {0.0f
,0.1f
, 0.55f
},
368 vp1
= {0.0f
,0.1f
,-0.55f
};
370 struct ub_world_lighting
*ubo
= &get_active_world()->ub_lighting
;
371 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_board
], vp0
, ubo
->g_board_0
);
372 m4x3_mulv( av
->sk
.final_mtx
[ av
->id_board
], vp1
, ubo
->g_board_1
);
374 if( player
->rewinding
){
375 if( player
->rewind_time
<= 0.0f
){
376 double taken
= vg
.time
- player
->rewind_start
;
377 vg_success( "Rewind took (rt, pt, tl): %f, %f, %f\n",
378 taken
, player
->rewind_predicted_time
,
379 player
->rewind_total_length
);
381 player
->rewinding
= 0;
382 player
->rewind_length
= 1;
383 player
->rewind_total_length
= 0.0f
;
384 player
->rewind_accum
= 0.0f
;
385 world_global
.sky_target_rate
= 1.0;
386 world_global
.time
= world_global
.last_use
;
389 world_global
.sky_target_rate
= -100.0;
391 float budget
= vg
.time_delta
,
392 overall_length
= player
->rewind_length
;
394 for( int i
=0; (i
<10)&&(player
->rewind_time
>0.0f
)&&(budget
>0.0f
); i
++ ){
395 /* Interpolate frames */
396 int i0
= floorf( player
->rewind_time
),
397 i1
= VG_MIN( i0
+1, player
->rewind_length
-1 );
399 struct rewind_frame
*fr
= &player
->rewind_buffer
[i0
],
400 *fr1
= &player
->rewind_buffer
[i1
];
402 float dist
= vg_maxf( v3_dist( fr
->pos
, fr1
->pos
), 0.001f
),
403 subl
= vg_fractf( player
->rewind_time
) + 0.001f
,
405 sramp
= 3.0f
-(1.0f
/(0.4f
+0.4f
*player
->rewind_time
)),
406 speed
= sramp
*28.0f
+ 0.5f
*player
->rewind_time
,
407 mod
= speed
* (budget
/ dist
),
409 advl
= vg_minf( mod
, subl
),
410 advt
= (advl
/ mod
) * budget
;
412 player
->dist_accum
+= speed
* advt
;
413 player
->rewind_time
-= advl
;
417 player
->rewind_time
= vg_maxf( 0.0f
, player
->rewind_time
);
419 float current_time
= vg
.time
- player
->rewind_start
,
420 remaining
= player
->rewind_predicted_time
- current_time
;
422 if( player
->rewind_sound_wait
){
423 if( player
->rewind_predicted_time
>= 6.5f
){
424 if( remaining
<= 6.5f
){
426 audio_oneshot( &audio_rewind
[3], 1.0f
, 0.0f
);
428 player
->rewind_sound_wait
= 0;
431 else if( player
->rewind_predicted_time
>= 2.5f
){
432 if( remaining
<= 2.5f
){
434 audio_oneshot( &audio_rewind
[2], 1.0f
, 0.0f
);
436 player
->rewind_sound_wait
= 0;
439 else if( player
->rewind_predicted_time
>= 1.5f
){
440 if( remaining
<= 1.5f
){
442 audio_oneshot( &audio_rewind
[1], 1.0f
, 0.0f
);
444 player
->rewind_sound_wait
= 0;
449 int i0
= floorf( player
->rewind_time
),
450 i1
= VG_MIN( i0
+1, player
->rewind_length
-1 );
452 struct rewind_frame
*fr
= &player
->rewind_buffer
[i0
],
453 *fr1
= &player
->rewind_buffer
[i1
];
455 float sub
= vg_fractf(player
->rewind_time
);
457 v3_lerp( fr
->pos
, fr1
->pos
, sub
, player
->cam_override_pos
);
458 player
->cam_override_angles
[0] =
459 vg_alerpf( fr
->ang
[0], fr1
->ang
[0], sub
);
460 player
->cam_override_angles
[1] =
461 vg_lerpf ( fr
->ang
[1], fr1
->ang
[1], sub
);
463 float blend
= player
->rewind_time
* 0.25f
;
464 player
->cam_override_strength
= vg_clampf( blend
, 0.0f
, 1.0f
);
467 else player
->cam_override_strength
= 0.0f
;
469 player__cam_iterate( player
);
472 PLAYER_API
void player__render( camera
*cam
, player_instance
*player
)
474 shader_model_character_view_use();
475 vg_tex2d_bind( player
->playertex
, 0 );
476 shader_model_character_view_uTexMain( 0 );
477 shader_model_character_view_uCamera( cam
->transform
[3] );
478 shader_model_character_view_uPv( cam
->mtx
.pv
);
480 world_instance
*world
= get_active_world();
481 world_link_lighting_ub( world
, _shader_model_character_view
.id
);
482 world_bind_position_texture( world
, _shader_model_character_view
.id
,
483 _uniform_model_character_view_g_world_depth
, 2 );
484 world_bind_light_array( world
, _shader_model_character_view
.id
,
485 _uniform_model_character_view_uLightsArray
, 3 );
486 world_bind_light_index( world
, _shader_model_character_view
.id
,
487 _uniform_model_character_view_uLightsIndex
, 4 );
489 glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms
,
490 player
->playeravatar
->sk
.bone_count
,
492 (float *)player
->playeravatar
->sk
.final_mtx
);
494 mesh_bind( player
->playermesh
);
495 mesh_draw( player
->playermesh
);
498 PLAYER_API
void player__im_gui( player_instance
*player
)
500 vg_uictx
.cursor
[0] = vg
.window_x
- 200;
501 vg_uictx
.cursor
[1] = 0;
502 vg_uictx
.cursor
[2] = 200;
503 vg_uictx
.cursor
[3] = 200;
505 struct ui_vert
*b
= ui_fill_rect( vg_uictx
.cursor
, 0x70000000 );
507 vg_uictx
.cursor
[0] = vg
.window_x
;
509 player__debugtext( 1, "angles: " PRINTF_v3f( player
->cam
.angles
) );
510 player__debugtext( 1, "basis: " PRINTF_v4f( player
->qbasis
) );
512 if( _player_im_gui
[ player
->subsystem
] )
513 _player_im_gui
[ player
->subsystem
]( player
);
515 b
[2].co
[1] = vg_uictx
.cursor
[1];
516 b
[3].co
[1] = vg_uictx
.cursor
[1];
519 PLAYER_API
void player__spawn( player_instance
*player
,
522 v3_copy( rp
->transform
.co
, player
->rb
.co
);
523 v3_zero( player
->rb
.v
);
524 v3_zero( player
->rb
.w
);
525 q_identity( player
->rb
.q
);
526 rb_update_transform( &player
->rb
);
528 q_identity( player
->qbasis
);
529 m3x3_identity( player
->basis
);
530 m3x3_identity( player
->invbasis
);
532 player
->subsystem
= k_player_subsystem_walk
;
533 player
->viewable_world
= get_active_world();
534 player
->gate_waiting
= NULL
;
536 if( _player_reset
[ player
->subsystem
] )
537 _player_reset
[ player
->subsystem
]( player
, rp
);
541 PLAYER_API
void player__kill( player_instance
*player
)
546 #endif /* PLAYER_C */