sitting down
authorhgn <hgodden00@gmail.com>
Thu, 2 Nov 2023 23:07:05 +0000 (23:07 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 2 Nov 2023 23:07:05 +0000 (23:07 +0000)
input.h
models_src/ch_none.mdl
player_render.c
player_render.h
player_walk.c
player_walk.h

diff --git a/input.h b/input.h
index 1fc945fdd3870d9badccd25f61a30f28dcdb3eef..7e1e6aa4f0afc84f6d16197ce1af1d9344b6dcc8 100644 (file)
--- a/input.h
+++ b/input.h
@@ -15,6 +15,7 @@ enum sr_bind{
    k_srbind_trick0,
    k_srbind_trick1,
    k_srbind_trick2,
+   k_srbind_sit,
    k_srbind_use,
    k_srbind_reset,
    k_srbind_camera,
@@ -123,7 +124,8 @@ static const char *button_display_string( enum sr_bind button )
     [k_srbind_mopen]  = controller_glyph( SDL_CONTROLLER_BUTTON_GUIDE ),
 [k_srbind_replay_play]= controller_glyph( SDL_CONTROLLER_BUTTON_X ),
 [k_srbind_replay_freecam]=controller_glyph(SDL_CONTROLLER_BUTTON_Y ),
-[k_srbind_replay_resume]=controller_glyph( SDL_CONTROLLER_BUTTON_A )
+[k_srbind_replay_resume]=controller_glyph( SDL_CONTROLLER_BUTTON_A ),
+   [k_srbind_sit]     = controller_glyph( SDL_CONTROLLER_BUTTON_B )
    };
 
    const char *keyboard_table[ k_srbind_max ] = {
@@ -148,6 +150,7 @@ static const char *button_display_string( enum sr_bind button )
 [k_srbind_replay_play]= KEYBOARD_GLYPH( "G" ),
 [k_srbind_replay_freecam] = KEYBOARD_GLYPH( "F" ),
 [k_srbind_replay_resume]= "\xa1",
+    [k_srbind_sit]    = KEYBOARD_GLYPH( "Z" )
    };
 
    if( vg_input.display_input_method == k_input_method_controller )
@@ -311,6 +314,7 @@ static void skaterift_preupdate_inputs(void)
    setbtn( k_srbind_replay_play, vg_getkey(SDLK_g) );
    setbtn( k_srbind_replay_freecam, vg_getkey(SDLK_f) );
    setbtn( k_srbind_replay_resume, vg_getkey(SDLK_SPACE) );
+   setbtn( k_srbind_sit, vg_getkey(SDLK_z) );
 
    /* axis
     * --------------------------------------------*/
@@ -371,6 +375,7 @@ static void skaterift_preupdate_inputs(void)
       setbtn( k_srbind_replay_resume, buttons[ SDL_CONTROLLER_BUTTON_A ] );
       setbtn( k_srbind_replay_play, buttons[ SDL_CONTROLLER_BUTTON_X ] );
       setbtn( k_srbind_replay_freecam, buttons[ SDL_CONTROLLER_BUTTON_Y ] );
+      setbtn( k_srbind_sit, buttons[ SDL_CONTROLLER_BUTTON_B ] );
 
       float *axis = controller->axises;
       float *steer = srinput.joystick_states[ k_srjoystick_steer ][0],
index ff975bc7dbe06e64c8e912ed397254daf6f8283a..f399b772a4ec6515c53b779ac12985f829194e68 100644 (file)
Binary files a/models_src/ch_none.mdl and b/models_src/ch_none.mdl differ
index 13aa5516ddc883d2d3df44fa4a51fbb794f6c02b..92aecbe5635578f0f72706d5d49e1d1fb8ecae0b 100644 (file)
@@ -25,6 +25,7 @@ static void player_avatar_load( struct player_avatar *av, const char *path ){
    skeleton_setup( sk, vg_mem.rtmemory, &av->meta );
 
    av->id_hip        = skeleton_bone_id( sk, "hips" );
+   av->id_chest      = skeleton_bone_id( sk, "chest" );
    av->id_ik_hand_l  = skeleton_bone_id( sk, "hand.IK.L" );
    av->id_ik_hand_r  = skeleton_bone_id( sk, "hand.IK.R" );
    av->id_ik_elbow_l = skeleton_bone_id( sk, "elbow.L" );
index bbb9630068f6b3871e42a932a448127614234317..4ea095cb5088059edc2da4eec01d55176d3b3543 100644 (file)
@@ -12,6 +12,7 @@ struct player_avatar
    struct skeleton sk;
 
    u32 id_hip,
+       id_chest,
        id_ik_hand_l,
        id_ik_hand_r,
        id_ik_elbow_l,
index 40b836c26db55a85b065922e51d7f2f2da5287a6..99dee8ee7186d27fd9927a02244da3ec61b17603 100644 (file)
@@ -384,6 +384,32 @@ static void player_walk_custom_filter( world_instance *world,
 
 static void player__walk_update(void){
    struct player_walk *w = &player_walk;
+
+   v2f steer;
+   joystick_state( k_srjoystick_steer, steer );
+
+   if( w->state.activity == k_walk_activity_sit ){
+      if( w->state.sit_t < 1.0f )
+         w->state.sit_t += vg.time_delta;
+      else {
+         w->state.sit_t = 1.0f;
+
+         if( button_down(k_srbind_sit) || (v2_length2(steer)>0.2f) ||
+             button_down(k_srbind_jump) ){
+            w->state.activity = k_walk_activity_sit_up;
+         }
+      }
+      return;
+   }
+   else if( w->state.activity == k_walk_activity_sit_up ){
+      if( w->state.sit_t > 0.0f ){
+         w->state.sit_t -= vg.time_delta;
+         return;
+      }
+   }
+   else
+      w->state.sit_t = 0.0f;
+
    v3_copy( localplayer.rb.co, w->state.prev_pos );
    v3_zero( localplayer.rb.w );
 
@@ -419,8 +445,6 @@ static void player__walk_update(void){
    m3x3_mulv( localplayer.basis, forward_dir, forward_dir );
    m3x3_mulv( localplayer.basis, right_dir,   right_dir );
 
-   v2f steer;
-   joystick_state( k_srjoystick_steer, steer );
 
    w->move_speed = localplayer.immobile? 0.0f: v2_length( steer );
 
@@ -470,6 +494,11 @@ static void player__walk_update(void){
    if( w->state.activity == k_walk_activity_ground ){
       v3_normalize( surface_avg );
 
+      if( button_down(k_srbind_sit) ){
+         w->state.activity = k_walk_activity_sit;
+         return;
+      }
+
       v3f tx, ty;
       v3_tangent_basis( surface_avg, tx, ty );
 
@@ -746,6 +775,7 @@ static void player__walk_animate(void){
       w->state.walk_timer = 0.0f;
    animator->walk_timer = w->state.walk_timer;
 
+
    if( !localplayer.immobile )
       rb_extrapolate( &localplayer.rb, animator->root_co, animator->root_q );
    else{
@@ -754,6 +784,24 @@ static void player__walk_animate(void){
    }
 
    f32 walk_yaw = player_get_heading_yaw();
+
+   /* sitting */
+   animator->sit_t = w->state.sit_t;
+
+   {
+      f32 head_yaw = localplayer.angles[0] + VG_PIf,
+          y = vg_angle_diff( head_yaw, -walk_yaw ),
+          mp = VG_PIf / 4.0f,
+          p = vg_clampf( localplayer.angles[1], -mp, mp );
+
+      if( fabsf(y) > VG_PIf/1.7f ){
+         y = 0.0f;
+         p = 0.0f;
+      }
+      animator->yaw = vg_lerpf( animator->yaw, y, vg.time_delta*2.0f );
+      animator->pitch = vg_lerpf( animator->pitch, p, vg.time_delta*2.8f );
+   }
+
    if( w->state.outro_type ){
       struct player_avatar *av = localplayer.playeravatar;
       struct skeleton_anim *anim = 
@@ -839,6 +887,28 @@ static void player__walk_pose( void *_animator, player_pose *pose ){
    skeleton_sample_anim( sk, w->anim_jump, vg.time*0.6f, bpose );
    skeleton_lerp_pose( sk, apose, bpose, animator->fly, apose );
 
+   /* sit */
+   if( animator->sit_t > 0.0f ){
+      f32 sit_norm = (f32)(w->anim_sit->length-1)/30.0f,
+                st = vg_minf( 1.0f, animator->sit_t );
+      skeleton_sample_anim( sk, w->anim_sit, st*sit_norm, bpose );
+
+      v4f qy,qp;
+      f32 *qh = bpose[av->id_head-1].q;
+      q_axis_angle( qy, (v3f){0.0f,1.0f,0.0f}, animator->yaw*0.5f*st );
+      q_axis_angle( qp, (v3f){0.0f,0.0f,1.0f}, animator->pitch*st );
+      q_mul( qy, qh, qh );
+      q_mul( qh, qp, qh );
+      q_normalize( qh );
+
+      qh = bpose[av->id_chest-1].q;
+      q_axis_angle( qy, (v3f){0.0f,1.0f,0.0f}, animator->yaw*0.5f*st );
+      q_mul( qy, qh, qh );
+      q_normalize( qh );
+
+      skeleton_lerp_pose( sk, apose, bpose, vg_minf(1.0f,st*10.0f), apose );
+   }
+
    if( animator->outro_type ){
       struct skeleton_anim *anim = player_walk_outro_anim(animator->outro_type);
       
@@ -899,7 +969,9 @@ static void player__walk_im_gui(void){
                            (const char *[]){ "k_walk_activity_air",
                                              "k_walk_activity_ground",
                                              "k_walk_activity_sleep",
-                                             "k_walk_activity_lockedmove" }
+                                             "k_walk_activity_lockedmove",
+                                             "k_walk_activity_sit",
+                                             "k_walk_activity_sit_up" }
                                              [w->state.activity] );
    player__debugtext( 1, "surface: %s\n",
                            (const char *[]){ "concrete",
@@ -931,6 +1003,7 @@ static void player__walk_bind(void){
    w->anim_jump_to_air  = skeleton_get_anim( sk, "jump_to_air" );
    w->anim_drop_in      = skeleton_get_anim( sk, "drop_in" );
    w->anim_intro        = skeleton_get_anim( sk, "into_skate" );
+   w->anim_sit          = skeleton_get_anim( sk, "sit" );
 }
 
 static void player__walk_transition(void){
index a03e9a721d190fe6903849c8f764a9890457b6dc..80cf5a9918e581f6c867768d85a709e1125f1af9 100644 (file)
@@ -24,7 +24,9 @@ struct player_walk{
          k_walk_activity_air,
          k_walk_activity_ground,
          k_walk_activity_sleep,
-         k_walk_activity_lockedmove
+         k_walk_activity_lockedmove,
+         k_walk_activity_sit,
+         k_walk_activity_sit_up
       }
       activity;
 
@@ -41,6 +43,7 @@ struct player_walk{
       f64 jump_input_time;
 
       f32 walk_timer;
+      f32 sit_t;
       int step_phase;
    }
    state;
@@ -49,7 +52,8 @@ struct player_walk{
 
    enum mdl_surface_prop surface;
    struct skeleton_anim *anim_walk, *anim_run, *anim_idle, *anim_jump,
-                        *anim_jump_to_air, *anim_drop_in, *anim_intro;
+                        *anim_jump_to_air, *anim_drop_in, *anim_intro,
+                        *anim_sit;
 
    struct player_walk_animator {
       v3f root_co;
@@ -58,12 +62,13 @@ struct player_walk{
           run,
           walk;
 
-      f32 walk_timer;
+      f32 walk_timer, yaw, pitch;
 
       v3f foot_anchor;
       enum walk_outro outro_type;
       f32 outro_t,
-          commit_t;
+          commit_t,
+          sit_t;
    }
    animator;
 }