X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=player_walk.c;h=692a296acd525e4f32e6652dd7cc1ec9eaf9aa31;hb=eb203257efcfe324217de9e733cc6c1371b99de6;hp=fbae15d4e1dc12b1c18bb21094d0dcdf645c89b6;hpb=34a8df54eb962f3ad2e036355041f5bc5cabe5a0;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/player_walk.c b/player_walk.c index fbae15d..692a296 100644 --- a/player_walk.c +++ b/player_walk.c @@ -361,6 +361,8 @@ VG_STATIC void player__walk_update( player_instance *player ) struct player_walk *w = &player->_walk; v3_copy( player->rb.co, w->state.prev_pos ); + enum walk_activity prev_state = w->state.activity; + if( w->state.activity == k_walk_activity_immobile ) return; @@ -392,11 +394,11 @@ VG_STATIC void player__walk_update( player_instance *player ) v2_normalize_clamp( walk ); w->move_speed = v2_length( walk ); + world_instance *world = get_active_world(); /* * Collision detection */ - world_instance *world = get_active_world(); len = rb_capsule__scene( mtx, &w->collider, NULL, &world->rb_geo.inf.scene, manifold ); @@ -408,17 +410,21 @@ VG_STATIC void player__walk_update( player_instance *player ) if( w->state.activity != k_walk_activity_lockedmove ) w->state.activity = k_walk_activity_air; - for( int i=0; isurface = k_surface_prop_concrete; + + for( int i=0; in ) ) - { + if( player_walk_normal_standable( player, ct->n ) ){ if( w->state.activity != k_walk_activity_lockedmove ) w->state.activity = k_walk_activity_ground; v3_add( surface_avg, ct->n, surface_avg ); + + struct world_surface *surf = world_contact_surface( world, ct ); + if( surf->info.surface_prop > w->surface ) + w->surface = surf->info.surface_prop; } rb_prepare_contact( ct, k_rb_delta ); @@ -432,15 +438,13 @@ VG_STATIC void player__walk_update( player_instance *player ) v3_muls( right_dir, walk[0], movedir ); v3_muladds( movedir, forward_dir, walk[1], movedir ); - if( w->state.activity == k_walk_activity_ground ) - { + if( w->state.activity == k_walk_activity_ground ){ v3_normalize( surface_avg ); v3f tx, ty; rb_tangent_basis( surface_avg, tx, ty ); - if( v2_length2(walk) > 0.001f ) - { + if( v2_length2(walk) > 0.001f ){ /* clip movement to the surface */ float d = v3_dot(surface_avg,movedir); v3_muladds( movedir, surface_avg, -d, movedir ); @@ -450,30 +454,25 @@ VG_STATIC void player__walk_update( player_instance *player ) nominal_speed = k_walkspeed; /* jump */ - if( player->input_jump->button.value ) - { + if( player->input_jump->button.value ){ + float d = v3_dot( player->basis[1], player->rb.v ); + v3_muladds( player->rb.v, player->basis[1], -d, player->rb.v ); v3_muladds( player->rb.v, player->basis[1], 5.0f, player->rb.v ); w->state.activity = k_walk_activity_air; + prev_state = k_walk_activity_air; accel_speed = k_walk_air_accel; nominal_speed = k_airspeed; } - else - { + else{ player_friction( player->rb.v ); - - struct world_material *surface_mat = - world_contact_material( world, manifold); - w->surface = surface_mat->info.surface_prop; } } - else - { + else{ accel_speed = k_walk_air_accel; nominal_speed = k_airspeed; } - if( v2_length2(walk) > 0.001f ) - { + if( v2_length2(walk) > 0.001f ){ player_accelerate( player->rb.v, movedir, nominal_speed, accel_speed ); v3_normalize( movedir ); } @@ -481,10 +480,8 @@ VG_STATIC void player__walk_update( player_instance *player ) /* * Resolve velocity constraints */ - for( int j=0; j<5; j++ ) - { - for( int i=0; irb.co, player->rb.co ); - - /* TODO: Stepping...... - * - * ideas; walkgrid style steps - */ -#if 0 - if( w->state.activity == k_walk_activity_ground ) - { - /* step */ + /* stepping */ + if( w->state.activity == k_walk_activity_ground|| + prev_state == k_walk_activity_ground ){ float max_dist = 0.4f; v3f pa, pb; v3_copy( player->rb.co, pa ); - pa[1] += w->collider.radius + max_dist; - - v3_muladds( pa, (v3f){0.0f,1.0f,0.0f}, -max_dist * 2.0f, pb ); + v3_muladds( pa, player->basis[1], w->collider.radius + max_dist, pa ); + v3_muladds( pa, player->basis[1], -max_dist * 2.0f, pb ); vg_line( pa, pb, 0xff000000 ); v3f n; float t; - if( spherecast_world( pa, pb, w->collider.radius, &t, n ) != -1 ) - { - if( player_walk_normal_standable( n ) ) - { + if( spherecast_world( world, pa, pb, w->collider.radius, &t, n ) != -1 ){ + if( player_walk_normal_standable( player, n ) ){ v3_lerp( pa, pb, t, player->rb.co ); - player->rb.co[1] -= w->collider.radius; + v3_muladds( player->rb.co, player->basis[1], + -w->collider.radius - k_penetration_slop, + player->rb.co ); + w->state.activity = k_walk_activity_ground; + + float d = -v3_dot(n,player->rb.v), + g = -k_gravity * k_rb_delta; + v3_muladds( player->rb.v, n, d, player->rb.v ); + v3_muladds( player->rb.v, player->basis[1], g, player->rb.v ); } } } -#endif + /* + * Depenetrate + */ + v3f dt; + rb_depenetrate( manifold, len, dt ); + v3_add( dt, player->rb.co, player->rb.co ); /* integrate */ - if( w->state.activity == k_walk_activity_air ) - { + if( w->state.activity == k_walk_activity_air ){ v3_muladds( player->rb.v, player->basis[1], -k_gravity*k_rb_delta, player->rb.v ); } @@ -564,13 +558,11 @@ VG_STATIC void player__walk_update( player_instance *player ) float movedist = v3_length( movedelta ); - if( movedist > 0.3f ) - { + if( movedist > 0.3f ){ float t, sr = w->collider.radius-0.04f; v3f n; - if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n ) != -1 ) - { + if( spherecast_world( world, lwr_prev, lwr_now, sr, &t, n ) != -1 ){ v3_lerp( lwr_prev, lwr_now, vg_maxf(0.01f,t), player->rb.co ); player->rb.co[1] -= w->collider.radius; rb_update_transform( &player->rb ); @@ -580,10 +572,9 @@ VG_STATIC void player__walk_update( player_instance *player ) } } - struct gate_hit hit; - if( world_intersect_gates(world, player->rb.co, w->state.prev_pos, &hit) ) - { - teleport_gate *gate = hit.gate; + ent_gate *gate = + world_intersect_gates( world, player->rb.co, w->state.prev_pos ); + if( gate ){ m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); @@ -594,10 +585,16 @@ VG_STATIC void player__walk_update( player_instance *player ) rb_update_transform( &player->rb ); w->state_gate_storage = w->state; - player__pass_gate( player, &hit ); + player__pass_gate( player, gate ); } } +VG_STATIC void player__walk_restore( player_instance *player ) +{ + struct player_walk *w = &player->_walk; + w->state = w->state_gate_storage; +} + VG_STATIC void player__walk_post_update( player_instance *player ) { struct player_walk *w = &player->_walk; @@ -643,6 +640,40 @@ VG_STATIC void player__walk_post_update( player_instance *player ) v3_add( player->rb.co, p1, p1 ); vg_line( player->rb.co, p1, VG__PINK ); + + + int walk_phase = 0; + if( vg_fractf(w->walk_timer) > 0.5f ) + walk_phase = 1; + else + walk_phase = 0; + + if( (w->step_phase != walk_phase) && + (w->state.activity == k_walk_activity_ground ) ) + { + audio_lock(); + if( w->surface == k_surface_prop_concrete ){ + audio_oneshot_3d( + &audio_footsteps[rand()%vg_list_size(audio_footsteps)], + player->rb.co, 40.0f, 1.0f + ); + } + else if( w->surface == k_surface_prop_grass ){ + audio_oneshot_3d( + &audio_footsteps_grass[rand()%vg_list_size(audio_footsteps_grass)], + player->rb.co, 40.0f, 1.0f + ); + } + else if( w->surface == k_surface_prop_wood ){ + audio_oneshot_3d( + &audio_footsteps_wood[rand()%vg_list_size(audio_footsteps_wood)], + player->rb.co, 40.0f, 1.0f + ); + } + audio_unlock(); + } + + w->step_phase = walk_phase; } VG_STATIC void player__walk_animate( player_instance *player, @@ -669,8 +700,7 @@ VG_STATIC void player__walk_animate( player_instance *player, player_pose apose, bpose; - if( w->move_speed > 0.025f ) - { + if( w->move_speed > 0.025f ){ /* TODO move */ float walk_norm = 30.0f/(float)w->anim_walk->length, run_norm = 30.0f/(float)w->anim_run->length, @@ -678,8 +708,7 @@ VG_STATIC void player__walk_animate( player_instance *player, w->walk_timer += walk_adv * vg.time_delta; } - else - { + else{ w->walk_timer = 0.0f; } @@ -708,8 +737,7 @@ VG_STATIC void player__walk_animate( player_instance *player, float walk_yaw = player_get_heading_yaw( player ); - if( w->state.outro_anim ) - { + if( w->state.outro_anim ){ struct player_avatar *av = player->playeravatar; float outro_length = (float)w->state.outro_anim->length / w->state.outro_anim->rate, @@ -721,8 +749,7 @@ VG_STATIC void player__walk_animate( player_instance *player, outro_time, bpose ); skeleton_lerp_pose( sk, apose, bpose, outro_t * 10.0f, dest->pose ); - if( w->state.outro_type == k_walk_outro_drop_in ) - { + if( w->state.outro_type == k_walk_outro_drop_in ){ float inv_rate = 1.0f / w->state.outro_anim->rate, anim_frames = w->state.outro_anim->length * inv_rate, step_frames = 12.0f * inv_rate, @@ -754,8 +781,7 @@ VG_STATIC void player__walk_animate( player_instance *player, /* the drop in bit */ - if( step_t >= 1.0f ) - { + if( step_t >= 1.0f ){ v4f final_q; player_walk_drop_in_overhang_transform( player, dop_t, player->rb.co, final_q ); @@ -770,8 +796,7 @@ VG_STATIC void player__walk_animate( player_instance *player, } return; } - else - { + else{ v3_muladds( dest->root_co, player->rb.to_world[1], -0.1f * outro_t, dest->root_co ); @@ -779,8 +804,7 @@ VG_STATIC void player__walk_animate( player_instance *player, player->holdout_time = 1.0f; } } - else - { + else{ skeleton_copy_pose( sk, apose, dest->pose ); } @@ -827,9 +851,15 @@ VG_STATIC void player__walk_im_gui( player_instance *player ) "k_walk_activity_immobile", "k_walk_activity_lockedmove" } [w->state.activity] ); - - if( w->state.outro_anim ) - { + player__debugtext( 1, "surface: %s\n", + (const char *[]){ "concrete", + "wood", + "grass", + "tiles", + "metal" } + [w->surface] ); + + if( w->state.outro_anim ){ float outro_length = (float)w->state.outro_anim->length / w->state.outro_anim->rate, outro_time = vg.time - w->state.outro_start_time; @@ -868,4 +898,13 @@ VG_STATIC void player__walk_transition( player_instance *player, v3f angles ) rb_update_transform( &player->rb ); } +VG_STATIC void player__walk_reset( player_instance *player, ent_spawn *rp ) +{ + struct player_walk *w = &player->_walk; + w->state.activity = k_walk_activity_air; + w->state.outro_type = k_walk_outro_none; + w->state.outro_anim = NULL; + w->state.outro_start_time = 0.0; +} + #endif /* PLAYER_DEVICE_WALK_H */