2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
8 #define PLAYER_REWIND_FRAMES 60*4
17 k_walkspeed
= 20.0f
, /* no longer used */
19 k_board_radius
= 0.3f
,
20 k_board_length
= 0.45f
,
21 k_board_allowance
= 0.04f
,
22 //k_friction_lat = 8.8f,
23 k_friction_lat
= 12.0f
,
24 k_friction_resistance
= 0.01f
,
25 k_max_push_speed
= 16.0f
,
27 k_push_cycle_rate
= 8.0f
,
28 k_steer_ground
= 2.5f
,
30 k_steer_air_lerp
= 0.3f
,
33 k_walk_downforce
= 8.0f
,
34 k_jump_charge_speed
= (1.0f
/1.0f
),
38 k_walk_accel
= 150.0f
,
39 k_walk_friction
= 8.0f
;
41 static int freecam
= 0;
42 static int walk_grid_iterations
= 1;
43 static float fc_speed
= 10.0f
;
46 * -----------------------------------------------------------------------------
48 * -----------------------------------------------------------------------------
54 rigidbody collide_front
, collide_back
;
58 rigidbody rb
, rb_gate_frame
;
59 float iY
, siY
; /* Yaw inertia */
61 v3f a
, v_last
, m
, bob
, vl
;
64 float vswitch
, slip
, slip_last
,
67 float grab
, jump
, pushing
, push_time
;
69 int in_air
, on_board
, jump_charge
, jump_dir
;
76 m4x3f visual_transform
,
79 int is_dead
, death_tick_allowance
, rewinding
;
82 v3f land_target_log
[22];
83 u32 land_target_colours
[22];
86 v3f handl_target
, handr_target
,
92 v3f camera_pos
, smooth_localcam
;
101 u32 rewind_incrementer
,
128 struct skeleton_anim
*anim_stand
,
132 *anim_push
, *anim_push_reverse
,
133 *anim_ollie
, *anim_ollie_reverse
,
134 *anim_grabs
, *anim_stop
,
135 *anim_walk
, *anim_run
, *anim_idle
,
167 .collide_front
= { .type
= k_rb_shape_sphere
, .inf
.sphere
.radius
= 0.3f
},
168 .collide_back
= { .type
= k_rb_shape_sphere
, .inf
.sphere
.radius
= 0.3f
}
174 static float *player_get_pos(void);
175 static void player_kill(void);
176 static float *player_cam_pos(void);
177 static void player_save_frame(void);
178 static void player_restore_frame(void);
179 static void player_save_rewind_frame(void);
184 #include "player_physics.h"
185 #include "player_ragdoll.h"
186 #include "player_model.h"
187 #include "player_animation.h"
188 #include "player_audio.h"
191 * -----------------------------------------------------------------------------
193 * -----------------------------------------------------------------------------
196 static void player_init(void) /* 1 */
198 rb_init( &player
.phys
.rb
);
199 rb_init( &player
.collide_front
);
200 rb_init( &player
.collide_back
);
202 vg_convar_push( (struct vg_convar
){
203 .name
= "walk_speed",
204 .data
= &k_walkspeed
,
205 .data_type
= k_convar_dtype_f32
,
206 .opt_f32
= { .clamp
= 0 },
210 vg_convar_push( (struct vg_convar
){
213 .data_type
= k_convar_dtype_f32
,
214 .opt_f32
= { .clamp
= 0 },
218 vg_convar_push( (struct vg_convar
){
219 .name
= "walk_accel",
220 .data
= &k_walk_accel
,
221 .data_type
= k_convar_dtype_f32
,
222 .opt_f32
= { .clamp
= 0 },
226 vg_convar_push( (struct vg_convar
){
229 .data_type
= k_convar_dtype_i32
,
230 .opt_i32
= { .min
=0, .max
=1, .clamp
=1 },
234 vg_convar_push( (struct vg_convar
){
237 .data_type
= k_convar_dtype_f32
,
238 .opt_f32
= { .clamp
= 0 },
242 vg_function_push( (struct vg_cmd
){
244 .function
= reset_player
247 player
.rewind_length
= 0;
248 player
.rewind_buffer
= vg_alloc( sizeof(struct rewind_frame
)
249 * PLAYER_REWIND_FRAMES
);
252 vg_loader_highwater( player_model_init
, player_model_free
, NULL
);
255 static void player_save_rewind_frame(void)
257 if( player
.rewind_length
< PLAYER_REWIND_FRAMES
)
259 struct rewind_frame
*fr
=
260 &player
.rewind_buffer
[ player
.rewind_length
++ ];
262 v2_copy( player
.angles
, fr
->ang
);
263 v3_copy( player
.camera_pos
, fr
->pos
);
265 player
.rewind_incrementer
= 0;
269 /* Deal with input etc */
270 static void player_update_pre(void)
272 struct player_phys
*phys
= &player
.phys
;
274 if( player
.rewinding
)
279 if( vg_get_button_down( "reset" ) )
281 player
.rewinding
= 1;
282 player
.rewind_time
= (float)player
.rewind_length
- 0.0001f
;
283 player_save_rewind_frame();
286 player
.death_tick_allowance
= 30;
287 player_restore_frame();
289 if( !phys
->on_board
)
291 player
.angles
[0] = atan2f( -phys
->rb
.forward
[2],
292 -phys
->rb
.forward
[0] );
295 player
.mdl
.shoes
[0] = 1;
296 player
.mdl
.shoes
[1] = 1;
298 world_routes_notify_reset();
300 /* apply 1 frame of movement */
304 if( vg_get_button_down( "switchmode" ) )
306 phys
->on_board
^= 0x1;
310 v3_muladds( phys
->rb
.v
, phys
->rb
.forward
, 0.2f
, phys
->rb
.v
);
315 static void player_update_fixed(void) /* 2 */
317 if( player
.rewinding
)
320 if( player
.death_tick_allowance
)
321 player
.death_tick_allowance
--;
323 struct player_phys
*phys
= &player
.phys
;
327 player_ragdoll_iter();
331 player
.rewind_incrementer
++;
333 if( player
.rewind_incrementer
> (u32
)(0.25/VG_TIMESTEP_FIXED
) )
335 player_save_rewind_frame();
342 static void player_update_post(void)
344 for( int i
=0; i
<player
.land_log_count
; i
++ )
345 vg_line_cross( player
.land_target_log
[i
],
346 player
.land_target_colours
[i
], 0.25f
);
350 player_debug_ragdoll();
353 player_animate_death_cam();
360 player_animate_camera();
367 /* CAMERA POSITIONING: LAYER 0 */
368 v2_copy( player
.angles
, camera_angles
);
369 v3_copy( player
.camera_pos
, camera_pos
);
371 if( player
.rewinding
)
373 if( player
.rewind_time
<= 0.0f
)
375 player
.rewinding
= 0;
376 player
.rewind_length
= 1;
380 assert( player
.rewind_length
> 0 );
385 float budget
= vg
.time_delta
,
386 overall_length
= player
.rewind_length
*0.25f
;
388 for( int i
=0; (i
<10)&&(player
.rewind_time
>0.0f
)&&(budget
>0.0f
); i
++ )
390 /* Interpolate frames */
391 int i0
= floorf( player
.rewind_time
),
392 i1
= VG_MIN( i0
+1, player
.rewind_length
-1 );
394 struct rewind_frame
*fr
= &player
.rewind_buffer
[i0
],
395 *fr1
= &player
.rewind_buffer
[i1
];
397 float dist
= vg_maxf( v3_dist( fr
->pos
, fr1
->pos
), 0.001f
),
398 subl
= vg_fractf( player
.rewind_time
) + 0.001f
,
401 speed
=sqrtf(player
.rewind_time
*player
.rewind_time
+11.0f
)*3.0f
,
403 speed
= (3.0f
-(1.0f
/(0.4f
+0.4f
*player
.rewind_time
)))*28.0f
,
405 mod
= speed
* (budget
/ dist
),
407 advl
= vg_minf( mod
, subl
),
408 advt
= (advl
/ mod
) * budget
;
410 player
.rewind_time
-= advl
;
414 player
.rewind_time
= vg_maxf( 0.0f
, player
.rewind_time
);
416 int i0
= floorf( player
.rewind_time
),
417 i1
= VG_MIN( i0
+1, player
.rewind_length
-1 );
419 struct rewind_frame
*fr
= &player
.rewind_buffer
[i0
],
420 *fr1
= &player
.rewind_buffer
[i1
];
422 float sub
= vg_fractf(player
.rewind_time
);
424 v3_lerp( fr
->pos
, fr1
->pos
, sub
, override_pos
);
425 override_angles
[0] = vg_alerpf( fr
->ang
[0], fr1
->ang
[0], sub
);
426 override_angles
[1] = vg_lerpf ( fr
->ang
[1], fr1
->ang
[1], sub
);
428 /* CAMERA POSITIONING: LAYER 1 */
429 float blend
= (4.0f
-player
.rewind_time
) * 0.25f
,
430 c
= vg_clampf( blend
, 0.0f
, 1.0f
);
432 camera_angles
[0] = vg_alerpf(override_angles
[0], player
.angles
[0], c
);
433 camera_angles
[1] = vg_lerpf (override_angles
[1], player
.angles
[1], c
);
434 v3_lerp( override_pos
, player
.camera_pos
, c
, camera_pos
);
442 static void draw_player( m4x3f cam
)
445 player_model_copy_ragdoll();
447 shader_viewchar_use();
448 vg_tex2d_bind( &tex_characters
, 0 );
449 shader_viewchar_uTexMain( 0 );
450 shader_viewchar_uCamera( cam
[3] );
451 shader_viewchar_uPv( vg
.pv
);
452 shader_link_standard_ub( _shader_viewchar
.id
, 2 );
453 glUniformMatrix4x3fv( _uniform_viewchar_uTransforms
,
454 player
.mdl
.sk
.bone_count
,
456 (float *)player
.mdl
.sk
.final_mtx
);
458 mesh_bind( &player
.mdl
.mesh
);
459 mesh_draw( &player
.mdl
.mesh
);
463 * -----------------------------------------------------------------------------
465 * -----------------------------------------------------------------------------
468 static float *player_get_pos(void)
470 return player
.phys
.rb
.co
;
473 static void player_kill(void)
475 if( player
.death_tick_allowance
== 0 )
478 player_ragdoll_copy_model( player
.phys
.rb
.v
);
482 static float *player_cam_pos(void)
484 return player
.camera_pos
;
488 #endif /* PLAYER_H */