+/*
+ * Copyright 2021-2022 (C) Mount0 Software, Harry Godden - All Rights Reserved
+ */
+
#ifndef PLAYER_H
#define PLAYER_H
/* TODO: eugh */
m3x3f gate_vr_frame, gate_vr_pstep_frame;
+ int on_board_frame, in_air_frame;
v3f a, v_last, m, bob, vl;
fsetup,
walk_timer,
fonboard;
+
+v3f last_step_pos;
+ int step_phase;
}
player =
{
* Player API
*/
+static float *player_get_pos(void)
+{
+ return player.rb.co;
+}
+
/*
* Free camera movement
}
}
}
+
+ player.in_air = len==0?1:0;
v3_zero( player.rb.w );
q_axis_angle( player.rb.q, (v3f){0.0f,1.0f,0.0f}, -player.angles[0] );
v3_muladds( player.rb.v, forward_dir, diff, player.rb.v );
/* TODO move */
- float walk_norm = (float)player.mdl.anim_walk->length / 30.0f,
- run_norm = (float)player.mdl.anim_run->length / 30.0f;
+ float walk_norm = 30.0f/(float)player.mdl.anim_walk->length,
+ run_norm = 30.0f/(float)player.mdl.anim_run->length ;
player.walk_timer += ktimestep * vg_lerpf( walk_norm,run_norm,move_norm );
}
player.jump = 0.0f;
player.jump_time = vg_time;
+
+ audio_lock();
+ audio_player_set_flags( &audio_player_extra, AUDIO_FLAG_SPACIAL_3D );
+ audio_player_set_position( &audio_player_extra, player.rb.co );
+ audio_player_set_vol( &audio_player_extra, 20.0f );
+ audio_player_playclip( &audio_player_extra, &audio_jumps[rand()%4] );
+ audio_unlock();
}
}
else
world_routes_activate_gate( i );
player.rb_gate_frame = player.rb;
+ player.in_air_frame = player.in_air;
+ player.on_board_frame = player.on_board;
+
+ if( !player.on_board )
+ {
+ v3f fwd_dir = {cosf(player.angles[0]),
+ 0.0f,
+ sinf(player.angles[0])};
+ m3x3_mulv( gate->transport, fwd_dir, fwd_dir );
+ player.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] );
+ }
+
m3x3_copy( player.vr, player.gate_vr_frame );
m3x3_copy( player.vr_pstep, player.gate_vr_pstep_frame );
+
+ audio_lock();
+ audio_play_oneshot( &audio_gate_lap, 1.0f );
+ audio_unlock();
break;
}
}
mdl_keyframe apose[32], bpose[32];
struct skeleton *sk = &player.mdl.sk;
- float walk_norm = 30.0f/(float)player.mdl.anim_walk->length,
- run_norm = 30.0f/(float)player.mdl.anim_run->length,
+ float walk_norm = (float)player.mdl.anim_walk->length/30.0f,
+ run_norm = (float)player.mdl.anim_run->length/30.0f,
t = player.walk_timer,
l = vg_get_axis("grabr") * 0.5f + 0.5f;
skeleton_sample_anim( sk, player.mdl.anim_walk, t*walk_norm, apose );
- skeleton_sample_anim( sk, player.mdl.anim_run, t*run_norm, bpose );
+ skeleton_sample_anim( sk, player.mdl.anim_run, t*run_norm, bpose );
skeleton_lerp_pose( sk, apose, bpose, l, apose );
offset[0] = vg_clampf( offset[0], -0.8f, 0.8f );
offset[1] = vg_clampf( offset[1], -0.5f, 0.0f );
- offset[1] = 0.0f;
/*
* Animation blending
skeleton_lerp_pose( sk, ground_pose, air_pose, player.ffly, apose );
- float add_grab_mod = player.ffly * player.grab;
+ float add_grab_mod = 1.0f - player.ffly*player.grab;
/* additive effects */
apose[player.mdl.id_hip-1].co[0] += offset[0]*add_grab_mod;
static void player_camera_update(void)
{
/* Update camera matrices */
- m4x3_identity( player.camera );
- m4x3_rotate_y( player.camera, -player.angles[0] );
- m4x3_rotate_x( player.camera, -player.angles[1] );
+ v4f qyaw, qpitch, qcam;
+ q_axis_angle( qyaw, (v3f){ 0.0f, 1.0f, 0.0f }, -player.angles[0] );
+ q_axis_angle( qpitch, (v3f){ 1.0f, 0.0f, 0.0f }, -player.angles[1] );
+
+ q_mul( qyaw, qpitch, qcam );
+ q_m3x3( qcam, player.camera );
+
v3_copy( player.camera_pos, player.camera[3] );
m4x3_invert_affine( player.camera, player.camera_inverse );
}
*/
static void player_audio(void)
{
+ static int _ding = 0;
+
+ int last = _ding;
+ _ding = glfwGetKey(vg_window, GLFW_KEY_C);
+
+ int trigger_ding = 0;
+ if( _ding && !last )
+ trigger_ding = 1;
+
+ static int _air = 0;
+
+ int l2 = _air;
+ _air = player.in_air;
+
+ static double last_revert = -2000.0;
+
+
+
+
audio_lock();
+
+ double revert_delta = vg_time - last_revert;
+ if( player.on_board && (!_air && l2) && (fabsf(player.slip) > 0.5f) &&
+ (revert_delta > 0.7) )
+ {
+ audio_player_set_position( &audio_player_extra, player.rb.co );
+ audio_player_set_flags( &audio_player_extra, AUDIO_FLAG_SPACIAL_3D );
+ audio_player_set_vol( &audio_player_extra, 2.0f );
+ audio_player_playclip( &audio_player_extra, &audio_lands[rand()%5] );
+
+ last_revert = vg_time;
+ }
static float air = 0.0f;
air = vg_lerpf(air, player.in_air? 1.0f: 0.0f, 5.0f*ktimestep);
float *cam = player.camera[3],
*pos = player.rb.co;
+
+ if( trigger_ding )
+ audio_player_playclip( &audio_player_extra, &audio_ding );
audio_player_set_position( &audio_player0, player.rb.co );
audio_player_set_position( &audio_player1, player.rb.co );
audio_player_set_position( &audio_player2, player.rb.co );
+ audio_player_set_position( &audio_player_gate, world.render_gate_pos );
v3_sub( player.rb.co, player.camera[3], delta );
v3_normalize( delta );
/* Tunnel / occlusion */
audio_sample_occlusion( player.camera[3] );
+
+ int sprite_avail = -1;
+ for( int i=0; i<vg_list_size(ambient_sprites); i++ )
+ {
+ if( !audio_player_is_playing( &ambient_sprites[i] ) )
+ {
+ sprite_avail = i;
+ break;
+ }
+ }
+
+ if( sprite_avail != -1 )
+ {
+ v3f waterpos;
+ enum audio_sprite_type sprite_type =
+ audio_sample_sprite_random( player.rb.co, waterpos );
+
+ if( sprite_type != k_audio_sprite_type_none )
+ {
+ audio_player *avail = &ambient_sprites[ sprite_avail ];
+
+ audio_player_set_vol( avail, 20.0f );
+ audio_player_set_flags( avail, AUDIO_FLAG_SPACIAL_3D );
+ audio_player_set_position( avail, waterpos );
+
+ if( sprite_type == k_audio_sprite_type_grass )
+ {
+ audio_player_playclip( avail, &audio_grass[rand()%4] );
+ }
+ else if( sprite_type == k_audio_sprite_type_water )
+ {
+ audio_player_playclip( avail, &audio_water[rand()%6] );
+ }
+ }
+ }
if( freecam || player.is_dead || !player.on_board )
{
audio_player_set_vol( &audio_player0, 0.0f );
audio_player_set_vol( &audio_player1, 0.0f );
audio_player_set_vol( &audio_player2, 0.0f );
+
+ int walk_phase = 0;
+ if( vg_fractf(player.walk_timer) > 0.5f )
+ walk_phase = 1;
+ else
+ walk_phase = 0;
+
+ if( (player.step_phase != walk_phase) && !player.in_air )
+ {
+ v3_copy( player.rb.co, player.last_step_pos );
+
+ audio_player_set_flags( &audio_player_extra, AUDIO_FLAG_SPACIAL_3D );
+ audio_player_set_position( &audio_player_extra, player.rb.co );
+ audio_player_set_vol( &audio_player_extra, 6.0f );
+ audio_player_playclip( &audio_player_extra,
+ &audio_footsteps[rand()%4] );
+ }
+
+ player.step_phase = walk_phase;
}
else
{
audio_player_set_vol( &audio_player1, vol1 );
audio_player_set_vol( &audio_player2, vol2 );
- float reverb_amt = vol0 * audio_occlusion_current * 1.0f;
+ float reverb_amt = vol0 * audio_occlusion_current * 0.5f;
audio_player_set_pan( &audio_player3, 0.0f );
audio_player_set_vol( &audio_player3, reverb_amt );
}
m3x3_identity( player.gate_vr_pstep_frame );
player.rb_gate_frame = player.rb;
+ player.on_board_frame = player.on_board;
+ player.in_air_frame = player.in_air;
return 1;
}
if( vg_get_axis("grabl")>0.0f)
{
player.rb = player.rb_gate_frame;
+ player.on_board = player.on_board_frame;
+ player.in_air = player.in_air_frame;
m3x3_copy( player.gate_vr_frame, player.vr );
m3x3_copy( player.gate_vr_pstep_frame, player.vr_pstep );
player.is_dead = 0;
player.in_air = 1;
+
+
+ if( !player.on_board )
+ {
+ player.angles[0] = atan2f( -player.rb.forward[2],
+ -player.rb.forward[0] );
+ }
+
m3x3_identity( player.vr );
player.mdl.shoes[0] = 1;