small compression
[carveJwlIkooP6JGAAIwe30JlM.git] / player_walk.c
index ad58c7317617e21aea774d125d0c2dd6a007e5e7..7d09f15e7095708b0b9287b651067da4256856fd 100644 (file)
@@ -50,7 +50,7 @@ static void player_walk_generic_to_skate( enum skate_activity init, f32 yaw ){
    v3_copy( v, player_skate.state.cog_v );
    v3_copy( v, localplayer.rb.v );
 
-   player__begin_holdout();
+   player__begin_holdout( (v3f){0.0f,0.0f,0.0f} );
    player__skate_reset_animator();
    player__skate_clear_mechanics();
    rb_update_transform( &localplayer.rb );
@@ -67,7 +67,7 @@ static void player_walk_drop_in_to_skate(void){
    player_skate.state.activity_prev = k_skate_activity_ground;
    player_skate.state.activity = k_skate_activity_ground;
 
-   player__begin_holdout();
+   player__begin_holdout( (v3f){0.0f,0.0f,0.0f} );
    player__skate_clear_mechanics();
    player__skate_reset_animator();
 
@@ -228,6 +228,9 @@ static int player_walk_scan_for_drop_in(void){
 static struct skeleton_anim *player_walk_outro_anim( enum walk_outro type ){
    struct player_walk *w = &player_walk;
 
+   if( type >= k_walk_outro_max )
+      return NULL;
+
    return (struct skeleton_anim *[]){ 
             [k_walk_outro_none]        = NULL,
             [k_walk_outro_jump_to_air] = w->anim_jump_to_air,
@@ -282,7 +285,7 @@ static void player__walk_pre_update(void){
                localplayer.immobile = 1;
 
                struct player_avatar *av = localplayer.playeravatar;
-               m4x3_mulv( av->sk.final_mtx[ av->id_ik_foot_r ], 
+               m4x3_mulv( localplayer.final_mtx[ av->id_ik_foot_r ], 
                           av->sk.bones[ av->id_ik_foot_r ].co, 
                           w->state.drop_in_foot_anchor );
             }
@@ -384,6 +387,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 +448,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 +497,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 );
 
@@ -617,9 +649,9 @@ static void player__walk_update(void){
       }
    }
 
-   ent_gate *gate = 
-      world_intersect_gates( world, localplayer.rb.co, w->state.prev_pos );
-   if( gate ){
+   u32 id = world_intersect_gates(world, localplayer.rb.co, w->state.prev_pos);
+   if( id ){
+      ent_gate *gate = mdl_arritm( &world->ent_gate, mdl_entity_id_id(id) );
       m4x3_mulv( gate->transport, localplayer.rb.co, localplayer.rb.co );
       m3x3_mulv( gate->transport, localplayer.rb.v,  localplayer.rb.v );
 
@@ -628,7 +660,7 @@ static void player__walk_update(void){
       q_mul( transport_rotation, localplayer.rb.q, localplayer.rb.q );
 
       rb_update_transform( &localplayer.rb );
-      player__pass_gate( gate );
+      player__pass_gate( id );
    }
    rb_update_transform( &localplayer.rb );
 }
@@ -746,6 +778,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 +787,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 ),
+          p = vg_clampf( localplayer.angles[1], 
+                           -k_sit_pitch_limit, k_sit_pitch_limit );
+
+      if( fabsf(y) > k_sit_yaw_limit ){
+         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,8 +890,35 @@ 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);
+
+      if( !anim ){
+         skeleton_copy_pose( sk, apose, pose->keyframes );
+         return;
+      }
       
       f32 outro_length = (f32)anim->length / anim->rate,
           outro_time = animator->outro_t*outro_length;
@@ -899,7 +977,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 +1011,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){
@@ -962,4 +1043,31 @@ static void player__walk_reset( ent_spawn *rp ){
    w->state.outro_start_time = 0.0;
 }
 
+static void player__walk_animator_exchange( bitpack_ctx *ctx, void *data ){
+   struct player_walk_animator *animator = data;
+
+   bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->root_co );
+   bitpack_qquat( ctx, animator->root_q );
+   bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->fly );
+   bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->run );
+   bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->walk );
+   bitpack_qf32( ctx, 16, 0.0f, 120.0f, &animator->walk_timer );
+
+   for( int i=0; i<1; i++ ){ /* without this you get a warning from gcc. lol */
+      bitpack_bytes( ctx, 8, &animator->outro_type );
+      if( animator->outro_type ){
+         bitpack_bytes( ctx, sizeof(animator->foot_anchor), 
+                        animator->foot_anchor );
+         bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->outro_t );
+         bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->commit_t );
+      }
+   }
+
+   u32 code = bitpack_qf32( ctx, 8, 0.0f, 1.0f, &animator->sit_t );
+   if( code ){
+      bitpack_qf32( ctx, 8, -k_sit_yaw_limit, k_sit_yaw_limit, &animator->yaw );
+      bitpack_qf32( ctx, 8, -k_sit_pitch_limit, k_sit_pitch_limit, 
+                     &animator->pitch );
+   }
+}
 #endif /* PLAYER_DEVICE_WALK_H */