a good point with grinds
authorhgn <hgodden00@gmail.com>
Thu, 30 Mar 2023 19:54:54 +0000 (20:54 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 30 Mar 2023 19:54:54 +0000 (20:54 +0100)
18 files changed:
audio.h
common.h
maps_src/mp_gridmap.mdl
model.h
player_common.c
player_skate.c
player_skate.h
sound_src/metalscrape.ogg [new file with mode: 0644]
sound_src/slidetap.ogg [new file with mode: 0644]
sound_src/tap0.ogg [new file with mode: 0644]
sound_src/tap1.ogg [new file with mode: 0644]
sound_src/tap2.ogg [new file with mode: 0644]
sound_src/tap3.ogg [new file with mode: 0644]
sound_src/woodimpact.ogg [new file with mode: 0644]
sound_src/woodroll0.ogg [new file with mode: 0644]
sound_src/woodroll1.ogg [new file with mode: 0644]
sound_src/woodroll2.ogg [new file with mode: 0644]
sound_src/woodslide.ogg [new file with mode: 0644]

diff --git a/audio.h b/audio.h
index 4f735099fb87fddbb8d6f40524c55bc885b5b664..3504ed21e441432766fec67b5f02a6eba2153952 100644 (file)
--- a/audio.h
+++ b/audio.h
 VG_STATIC float audio_occlusion_current = 0.0f,
              k_audio_occlusion_rate  = 1.0f;
 
-VG_STATIC int   k_audio_debug_soundscape = 0;
+VG_STATIC int k_audio_debug_soundscape = 0;
 
 audio_clip audio_board[] =
 {
    { .path="sound/skate_hpf.ogg" },
    { .path="sound/wheel.ogg" },
    { .path="sound/slide.ogg" },
-   { .path="sound/reverb.ogg" },
-   { .path="sound/grind_loop.ogg" },
    { .path="sound/grind_enter.ogg" },
-   { .path="sound/grind_exit.ogg" }
+   { .path="sound/grind_exit.ogg" },
+   { .path="sound/grind_loop.ogg" },
+   { .path="sound/woodslide.ogg" },
+   { .path="sound/metalscrape.ogg" },
+   { .path="sound/slidetap.ogg" }
+};
+
+audio_clip audio_taps[] =
+{
+   { .path="sound/tap0.ogg" },
+   { .path="sound/tap1.ogg" },
+   { .path="sound/tap2.ogg" },
+   { .path="sound/tap3.ogg" }
 };
 
 audio_clip audio_splash =
@@ -195,6 +205,7 @@ VG_STATIC void audio_init(void)
 #endif
 
    audio_clip_loadn( audio_board, vg_list_size(audio_board), NULL );
+   audio_clip_loadn( audio_taps, vg_list_size(audio_taps), NULL );
    audio_clip_loadn( audio_ambience, vg_list_size(audio_ambience), NULL );
    audio_clip_loadn( &audio_splash, 1, NULL );
    audio_clip_loadn( &audio_gate_pass, 1, NULL );
index 4f854a32899302c647cac57e1e325660388fedbd..9eda6f67ae0e59dfcf76c8fd39b0f26d46d7d8ae 100644 (file)
--- a/common.h
+++ b/common.h
@@ -47,7 +47,7 @@ VG_STATIC float
    k_steer_ground          = 2.5f,
    k_steer_air             = 3.6f,
 
-   k_jump_charge_speed     = (1.0f/1.0f),
+   k_jump_charge_speed     = (1.0f/0.4f),
    k_jump_force            = 5.0f,
 
    k_pitch_limit           = 1.5f,
index 59f176c26c80ebc4ad03f81612eee11ab2b4524a..9e7a5108abcc084b7db2e6fceca5735c1469a926 100644 (file)
Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ
diff --git a/model.h b/model.h
index c92960f04569b11ea2b8e5a6b62776c07e8f59dd..b7e0e96e6f43a512cb52e5282f767ce699ef2d65 100644 (file)
--- a/model.h
+++ b/model.h
@@ -22,7 +22,8 @@ enum mdl_surface_prop
    k_surface_prop_concrete          = 0,
    k_surface_prop_wood              = 1,
    k_surface_prop_grass             = 2,
-   k_surface_prop_tiles             = 3
+   k_surface_prop_tiles             = 3,
+   k_surface_prop_metal             = 4
 };
 
 enum material_flag
index e0343a07aee2fca7ef644f73af9dcfabb7768882..bf049012878a1427e58b125480d5dc14cd51b549 100644 (file)
@@ -69,8 +69,11 @@ VG_STATIC void player__cam_iterate( player_instance *player )
       v3_copy( (v3f){0.0f,1.4f,0.0f}, player->tpv_offset );
    }
    else{
-      v3_copy( (v3f){0.0f,1.8f,0.0f}, player->fpv_viewpoint );
+      v3_copy( (v3f){-0.15f,1.7f,0.0f}, player->fpv_viewpoint );
+#if 0
       v3_copy( (v3f){-0.35f,0.0f,0.0f}, player->fpv_offset );
+#endif
+      v3_copy( (v3f){0.0f,0.0f,0.0f}, player->fpv_offset );
       v3_copy( (v3f){0.0f,1.4f,0.0f}, player->tpv_offset );
       v3_add( TEMP_TPV_EXTRA, player->tpv_offset, player->tpv_offset );
    }
@@ -116,7 +119,7 @@ VG_STATIC void player__cam_iterate( player_instance *player )
 
    /* fov -- simple blend */
    /* FIXME: cl_fov */
-   player->cam.fov = vg_lerpf( 97.0f, 118.0f, player->camera_type_blend );
+   player->cam.fov = vg_lerpf( 97.0f, 128.0f, player->camera_type_blend );
 
    /* 
     * first person camera
index 1f99991b1846841b16540ecef2a2e1cd7df8fd49..446c4bff10a37ba932eb8a808ad6e1c0fd28461d 100644 (file)
@@ -442,7 +442,6 @@ void player__approximate_best_trajectory( player_instance *player )
       q_axis_angle( qbias, player->rb.to_world[1], yaw_bias );
       q_mulv( qbias, launch_v, launch_v );
 
-
       float gravity_bias = vg_lerpf( 0.85f, 1.4f, vt ),
             gravity      = k_gravity * gravity_bias;
       inf->gravity = gravity;
@@ -469,6 +468,13 @@ void player__approximate_best_trajectory( player_instance *player )
          v3f closest;
          if( search_for_grind ){
             if( bh_closest_point( world->geo_bh, co1, closest, 1.0f ) != -1 ){
+
+               float min_dist = 0.75f;
+                     min_dist *= min_dist;
+
+               if( v3_dist2( closest, launch_co ) < min_dist )
+                  search_for_grind = 0;
+
                v3f bound[2];
 
                for( int j=0; j<2; j++ ){
@@ -477,10 +483,9 @@ void player__approximate_best_trajectory( player_instance *player )
                   v3_add( launch_co, bound[j], bound[j] );
                }
 
-               float minh = vg_minf( bound[0][1], bound[1][1] ),
-                     maxh = vg_maxf( bound[0][1], bound[1][1] );
-
-               vg_info( "%f [%f:%f]\n", closest[1], minh, maxh );
+               float limh = vg_minf( 2.0f, t ),
+                     minh = vg_minf( bound[0][1], bound[1][1] )-limh,
+                     maxh = vg_maxf( bound[0][1], bound[1][1] )+limh;
 
                if( (closest[1] < minh) || (closest[1] > maxh) ){
                   search_for_grind = 0;
@@ -496,6 +501,7 @@ void player__approximate_best_trajectory( player_instance *player )
             v3_muladds( ve, basis[1], -gravity * t, ve );
 
             if( skate_grind_scansq( player, closest, ve, 0.5f, &grind ) ){
+
                /* check alignment */
                v2f v0 = { v3_dot( ve, basis[0] ), 
                           v3_dot( ve, basis[2] ) },
@@ -507,7 +513,14 @@ void player__approximate_best_trajectory( player_instance *player )
 
                float a = v2_dot( v0, v1 );
 
-               if( a >= cosf( VG_PIf * 0.185f ) ){
+               float a_min = cosf( VG_PIf * 0.185f );
+               if( s->grind_cooldown )
+                  a_min = cosf( VG_PIf * 0.05f );
+
+               /* check speed */
+               if( (fabsf(v3_dot( ve, grind.dir ))>=k_grind_axel_min_vel) &&
+                   (a >= a_min) )
+               {
                   grind_located = 1;
                   grind_located_gravity = inf->gravity;
 
@@ -530,7 +543,10 @@ void player__approximate_best_trajectory( player_instance *player )
          float t1;
          v3f n;
 
-         int idx = spherecast_world( world, co0, co1, k_board_radius, &t1, n );
+         float scan_radius = k_board_radius;
+               scan_radius *= vg_clampf( t, 0.02f, 1.0f );
+
+         int idx = spherecast_world( world, co0, co1, scan_radius, &t1, n );
          if( idx != -1 ){
             v3f co;
             v3_lerp( co0, co1, t1, co );
@@ -926,11 +942,8 @@ VG_STATIC void skate_apply_friction_model( player_instance *player )
    s->state.slip = slip;
    s->state.reverse = -vg_signf(vel[2]);
 
-   float S = (float)s->grind_cooldown * (1.0f/20.0f);
-         S = vg_minf( S, 1.0f );
-
-   vel[0] += vg_cfrictf( vel[0], S * k_friction_lat * k_rb_delta );
-   vel[2] += vg_cfrictf( vel[2], S * k_friction_resistance * k_rb_delta );
+   vel[0] += vg_cfrictf( vel[0], k_friction_lat * k_rb_delta );
+   vel[2] += vg_cfrictf( vel[2], k_friction_resistance * k_rb_delta );
 
    /* Pushing additive force */
 
@@ -1001,8 +1014,8 @@ VG_STATIC void skate_apply_jump_model( player_instance *player )
          v3_normalize( jumpdir );
       }else{
          v3_copy( s->state.up_dir, jumpdir );
+         s->grind_cooldown = 30;
          s->state.activity = k_skate_activity_ground;
-         s->grind_cooldown = 0;
 
          float tilt  = player->input_js1h->axis.value * 0.3f;
                tilt *= vg_signf(v3_dot( player->rb.v, s->grind_dir ));
@@ -1011,12 +1024,15 @@ VG_STATIC void skate_apply_jump_model( player_instance *player )
          q_axis_angle( qtilt, s->grind_dir, tilt );
          q_mulv( qtilt, jumpdir, jumpdir );
       }
+      s->surface_cooldown = 10;
       
       float force = k_jump_force*s->state.jump_charge;
       v3_muladds( player->rb.v, jumpdir, force, player->rb.v );
       s->state.jump_charge = 0.0f;
       s->state.jump_time = vg.time;
 
+      vg_success( PRINTF_v3f( jumpdir ) );
+
       v2f steer = { player->input_js1h->axis.value,
                     player->input_js1v->axis.value };
       v2_normalize_clamp( steer );
@@ -1115,8 +1131,12 @@ VG_STATIC void skate_integrate( player_instance *player )
          decay_rate_y = 1.0f;
 
    if( s->state.activity >= k_skate_activity_grind_any ){
+#if 0
       decay_rate = 1.0f-vg_lerpf( 3.0f, 20.0f, s->grind_strength ) * k_rb_delta;
       decay_rate_y = decay_rate;
+#endif
+      decay_rate = 1.0f-(40.0f*k_rb_delta);
+      decay_rate_y = 1.0f-(10.0f*k_rb_delta);
    }
 
    float wx = v3_dot( player->rb.w, player->rb.to_world[0] ) * decay_rate,
@@ -1219,24 +1239,23 @@ VG_STATIC void player__skate_post_update( player_instance *player )
       vg_line_pt3( jump->apex, 0.02f, 0xffffffff );
    }
 
-#if 0
-   vg_line_pt3( s->state.apex, 0.030f, 0xff0000ff );
-#endif
-
    audio_lock();
 
    float air   = s->state.activity <= k_skate_activity_air_to_grind? 1.0f: 0.0f,
          speed = v3_length( player->rb.v ),
          attn  = vg_minf( 1.0f, speed*0.1f ),
-         slide = vg_clampf( fabsf(s->state.slip), 0.0f, 1.0f ),
+         slide = vg_clampf( fabsf(s->state.slip), 0.0f, 1.0f );
 
+   if( s->state.activity >= k_skate_activity_grind_any ){
+      slide = 0.0f;
+   }
+
+   float
          vol_main    = sqrtf( (1.0f-air)*attn*(1.0f-slide) * 0.4f ),
          vol_air     = sqrtf(       air *attn * 0.5f ),
          vol_slide   = sqrtf( (1.0f-air)*attn*slide * 0.25f );
 
    const u32 flags = AUDIO_FLAG_SPACIAL_3D|AUDIO_FLAG_LOOP;
-   if( !s->aud_main )
-      s->aud_main = audio_request_channel( &audio_board[0], flags );
 
    if( !s->aud_air )
       s->aud_air = audio_request_channel( &audio_board[1], flags );
@@ -1248,16 +1267,68 @@ VG_STATIC void player__skate_post_update( player_instance *player )
    /* brrrrrrrrrrrt sound for tiles and stuff 
     * --------------------------------------------------------*/
    float sidechain_amt = 0.0f,
-         hz            = speed * 2.0f;
+         hz            = vg_maxf( speed * 2.0f, 2.0f );
 
-   if( s->surface == k_surface_prop_tiles )
+   if( (s->surface == k_surface_prop_tiles) &&
+       (s->state.activity < k_skate_activity_grind_any) )
       sidechain_amt = 1.0f;
    else
       sidechain_amt = 0.0f;
 
    audio_set_lfo_frequency( 0, hz );
    audio_set_lfo_wave( 0, k_lfo_polynomial_bipolar, 
-                        vg_lerpf( 250.0f, 80.0f, attn ) );
+                          vg_lerpf( 250.0f, 80.0f, attn ) );
+
+   if( s->sample_change_cooldown > 0.0f ){
+      s->sample_change_cooldown -= vg.frame_delta;
+   }
+   else{
+      int sample_type = k_skate_sample_concrete;
+
+      if( s->state.activity == k_skate_activity_grind_5050 ){
+         if( s->surface == k_surface_prop_metal )
+            sample_type = k_skate_sample_metal_scrape_generic;
+         else
+            sample_type = k_skate_sample_concrete_scrape_metal;
+      }
+      else if( (s->state.activity == k_skate_activity_grind_back50) ||
+               (s->state.activity == k_skate_activity_grind_front50) ){
+
+         float d = v3_dot( player->rb.to_world[2], s->grind_dir );
+
+         if( s->surface == k_surface_prop_metal ){
+            sample_type = k_skate_sample_metal_scrape_generic;
+         }
+         else{
+            if( d > 0.70710678118654752f )
+               sample_type = k_skate_sample_concrete_scrape_wood;
+            else 
+               sample_type = k_skate_sample_concrete_scrape_metal;
+         }
+      }
+      else if( s->state.activity == k_skate_activity_grind_boardslide ){
+         if( s->surface == k_surface_prop_metal )
+            sample_type = k_skate_sample_metal_scrape_generic;
+         else
+            sample_type = k_skate_sample_concrete_scrape_wood;
+      }
+
+      audio_clip *relevant_samples[] = {
+         &audio_board[0],
+         &audio_board[0], /* TODO? */
+         &audio_board[7],
+         &audio_board[6],
+         &audio_board[5]
+      };
+
+      if( (s->main_sample_type != sample_type) || (!s->aud_main) ){
+         s->aud_main = 
+            audio_channel_crossfade( s->aud_main, relevant_samples[sample_type],
+                                     0.06f, flags );
+         s->sample_change_cooldown = 0.1f;
+         s->main_sample_type = sample_type;
+      }
+   }
 
    if( s->aud_main ){
       s->aud_main->colour = 0x00103efe;
@@ -1930,8 +2001,8 @@ VG_STATIC enum skate_activity skate_availible_grind( player_instance *player )
    struct player_skate *s = &player->_skate;
 
    /* debounces this state manager a little bit */
-   if( s->grind_cooldown < 20 ){
-      s->grind_cooldown ++;
+   if( s->grind_cooldown ){
+      s->grind_cooldown --;
       return k_skate_activity_undefined;
    }
 
@@ -1987,8 +2058,10 @@ VG_STATIC enum skate_activity skate_availible_grind( player_instance *player )
    , new_activity = table[ res_slide << 2 | res_back50 << 1 | res_front50 ];
 
    if(      new_activity == k_skate_activity_undefined ){
-      if( s->state.activity >= k_skate_activity_grind_any )
-         s->grind_cooldown = 5;
+      if( s->state.activity >= k_skate_activity_grind_any ){
+         s->grind_cooldown = 15;
+         s->surface_cooldown = 10;
+      }
    }
    else if( new_activity == k_skate_activity_grind_boardslide ){
       skate_boardslide_apply( player, &inf_slide );
@@ -2086,8 +2159,12 @@ VG_STATIC void player__skate_update( player_instance *player )
 
    v3_zero( s->surface_picture );
 
-   for( int i=0; i<k_wheel_count; i++ )
+   int prev_contacts[2];
+
+   for( int i=0; i<k_wheel_count; i++ ){
       wheels[i].state = k_collider_state_default;
+      prev_contacts[i] = s->wheel_contacts[i];
+   }
 
    /* check if we can enter or continue grind */
    enum skate_activity grindable_activity = skate_availible_grind( player );
@@ -2111,11 +2188,32 @@ VG_STATIC void player__skate_update( player_instance *player )
 
          v3_add( normal, s->surface_picture, s->surface_picture );
          contact_count ++;
+         s->wheel_contacts[i] = 1;
+      }
+      else{
+         s->wheel_contacts[i] = 0;
       }
 
       m3x3_mulv( player->rb.to_local, axel, s->truckv0[i] );
    }
 
+   if( s->surface_cooldown ){
+      s->surface_cooldown --;
+      contact_count = 0;
+   }
+
+   if( (prev_contacts[0]+prev_contacts[1] == 1) && (contact_count == 2) ){
+      audio_lock();
+      for( int i=0; i<2; i++ ){
+         if( !prev_contacts[i] ){
+            v3f co;
+            m4x3_mulv( player->rb.to_world, wheels[i].pos, co );
+            audio_oneshot_3d( &audio_taps[rand()%4], co, 40.0f, 0.75f );
+         }
+      }
+      audio_unlock();
+   }
+
    if( contact_count ){
       s->state.activity = k_skate_activity_ground;
       s->state.gravity_bias = k_gravity;
@@ -2315,13 +2413,15 @@ begin_collision:;
    debug_capsule( mtx, capsule.radius, capsule.height, VG__WHITE );
 
    /* add limits */
-   for( int i=0; i<s->limit_count; i++ ){
-      struct grind_limit *limit = &s->limits[i];
-      rb_ct *ct = &manifold[ manifold_len ++ ];
-      m4x3_mulv( player->rb.to_world, limit->ra, ct->co );
-      m3x3_mulv( player->rb.to_world, limit->n, ct->n );
-      ct->p = limit->p;
-      ct->type = k_contact_type_default;
+   if( s->state.activity >= k_skate_activity_grind_any ){
+      for( int i=0; i<s->limit_count; i++ ){
+         struct grind_limit *limit = &s->limits[i];
+         rb_ct *ct = &manifold[ manifold_len ++ ];
+         m4x3_mulv( player->rb.to_world, limit->ra, ct->co );
+         m3x3_mulv( player->rb.to_world, limit->n, ct->n );
+         ct->p = limit->p;
+         ct->type = k_contact_type_default;
+      }
    }
 
    /* 
@@ -2510,8 +2610,6 @@ VG_STATIC void player__skate_im_gui( player_instance *player )
       "undefined (INVALID)",
       "grind_any (INVALID)",
       "grind_boardslide",
-      "grind_noseslide",
-      "grind_tailslide",
       "grind_back50",
       "grind_front50",
       "grind_5050"
@@ -2981,7 +3079,6 @@ VG_STATIC void player__skate_clear_mechanics( player_instance *player )
 {
    struct player_skate *s = &player->_skate;
    s->state.jump_charge    = 0.0f;
-   s->state.lift_frames    = 0;
    s->state.flip_rate      = 0.0f;
 #if 0
    s->state.steery         = 0.0f;
index 72eb94e678a1cb49247018074ea31f09c0db4b50..9f21115eee71e0f4318873f47eb77f925571ef67 100644 (file)
@@ -19,8 +19,6 @@ struct player_skate
          k_skate_activity_undefined,
          k_skate_activity_grind_any,
          k_skate_activity_grind_boardslide,
-         k_skate_activity_grind_noseslide,
-         k_skate_activity_grind_tailslide,
          k_skate_activity_grind_back50,
          k_skate_activity_grind_front50,
          k_skate_activity_grind_5050
@@ -50,8 +48,6 @@ struct player_skate
       v3f up_dir;
       v3f head_position;
 
-      int lift_frames;
-
       v3f throw_v;
       v3f cog_v, cog;
 
@@ -79,7 +75,7 @@ struct player_skate
    state_gate_storage;
 
 
-   /* animation */
+   /* animation /audio */
    struct skeleton_anim *anim_stand, *anim_highg, *anim_slide,
                         *anim_air, *anim_grind, *anim_grind_jump,
                         *anim_push,  *anim_push_reverse,
@@ -108,6 +104,18 @@ struct player_skate
    audio_channel *aud_main, *aud_slide, *aud_air;
    enum mdl_surface_prop surface, audio_surface;
 
+   int wheel_contacts[2];
+   float sample_change_cooldown;
+
+   enum {
+      k_skate_sample_concrete,
+      k_skate_sample_wood,
+      k_skate_sample_concrete_scrape_metal,
+      k_skate_sample_concrete_scrape_wood,
+      k_skate_sample_metal_scrape_generic
+   }
+   main_sample_type;
+
    /*
     * Physics 
     * ----------------------------------------------------
@@ -151,7 +159,8 @@ struct player_skate
        grind_vec,
        grind_dir;
 
-   u32 grind_cooldown;
+   u32 grind_cooldown,
+       surface_cooldown;
 
    float grind_strength;
 
diff --git a/sound_src/metalscrape.ogg b/sound_src/metalscrape.ogg
new file mode 100644 (file)
index 0000000..64f8b39
Binary files /dev/null and b/sound_src/metalscrape.ogg differ
diff --git a/sound_src/slidetap.ogg b/sound_src/slidetap.ogg
new file mode 100644 (file)
index 0000000..34cceab
Binary files /dev/null and b/sound_src/slidetap.ogg differ
diff --git a/sound_src/tap0.ogg b/sound_src/tap0.ogg
new file mode 100644 (file)
index 0000000..5ca8205
Binary files /dev/null and b/sound_src/tap0.ogg differ
diff --git a/sound_src/tap1.ogg b/sound_src/tap1.ogg
new file mode 100644 (file)
index 0000000..da5f612
Binary files /dev/null and b/sound_src/tap1.ogg differ
diff --git a/sound_src/tap2.ogg b/sound_src/tap2.ogg
new file mode 100644 (file)
index 0000000..a259644
Binary files /dev/null and b/sound_src/tap2.ogg differ
diff --git a/sound_src/tap3.ogg b/sound_src/tap3.ogg
new file mode 100644 (file)
index 0000000..ebf9664
Binary files /dev/null and b/sound_src/tap3.ogg differ
diff --git a/sound_src/woodimpact.ogg b/sound_src/woodimpact.ogg
new file mode 100644 (file)
index 0000000..439ec31
Binary files /dev/null and b/sound_src/woodimpact.ogg differ
diff --git a/sound_src/woodroll0.ogg b/sound_src/woodroll0.ogg
new file mode 100644 (file)
index 0000000..3e204e2
Binary files /dev/null and b/sound_src/woodroll0.ogg differ
diff --git a/sound_src/woodroll1.ogg b/sound_src/woodroll1.ogg
new file mode 100644 (file)
index 0000000..d05a9fa
Binary files /dev/null and b/sound_src/woodroll1.ogg differ
diff --git a/sound_src/woodroll2.ogg b/sound_src/woodroll2.ogg
new file mode 100644 (file)
index 0000000..060e842
Binary files /dev/null and b/sound_src/woodroll2.ogg differ
diff --git a/sound_src/woodslide.ogg b/sound_src/woodslide.ogg
new file mode 100644 (file)
index 0000000..9946a6b
Binary files /dev/null and b/sound_src/woodslide.ogg differ