update helpers/location to 'frosted' ui
[carveJwlIkooP6JGAAIwe30JlM.git] / player_dead.c
index b6312cb5273835dfbbdfc204c8157125e85a0cee..72eba265f443c92512051b77b485e41b6e15b030 100644 (file)
-#ifndef PLAYER_DEAD_C
-#define PLAYER_DEAD_C
+#include "skaterift.h"
+#include "player_dead.h"
+#include "gui.h"
 
-#include "player.h"
+struct player_dead player_dead;
+struct player_subsystem_interface player_subsystem_dead = {
+   .update = player__dead_update,
+   .post_update = player__dead_post_update,
+   .animate = player__dead_animate,
+   .pose = player__dead_pose,
+   .post_animate = player__dead_post_animate,
+   .im_gui = player__dead_im_gui,
+   .bind = player__dead_bind,
 
-VG_STATIC void player__dead_update      ( player_instance *player )
+   .animator_data = &player_dead.animator,
+   .animator_size = sizeof(player_dead.animator),
+   .network_animator_exchange = player__dead_animator_exchange,
+   .name = "Dead"
+};
+
+void player__dead_update(void)
 {
-   player_ragdoll_iter( &player->ragdoll );
-}
+   player_ragdoll_iter( &localplayer.ragdoll );
 
-VG_STATIC void player__dead_animate    ( player_instance *player ){
-   /* nothing here */
+   world_instance *world = world_current_instance();
+   world_water_player_safe( world, 0.2f );
 }
 
-VG_STATIC void player__dead_pose        ( player_instance *player ){
-   player_pose *pose = &player->pose;
-   v3_zero( pose->root_co );
-   q_identity( pose->root_q );
+void player__dead_post_update(void){
+   struct ragdoll_part *part = 
+      &localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
+   struct player_dead *d = &player_dead;
+
+   v3f ext_co;
+   v4f ext_q;
+   rb_extrapolate( &part->rb, ext_co, ext_q );
+
+   v3_lerp( d->co_lpf, ext_co, vg.time_frame_delta*4.0f, d->co_lpf );
+   v3_lerp( d->v_lpf,  part->rb.v,  vg.time_frame_delta*4.0f, d->v_lpf );
+   v3_lerp( d->w_lpf,  part->rb.w,  vg.time_frame_delta*4.0f, d->w_lpf );
    
-   for( int i=0; i<vg_list_size(pose->keyframes); i ++ ){
-      /* FUUUUTUUREEEE: squangle the rigidbodies back into OK keyframes */
-      v3_zero( pose->keyframes[i].co );
-      v3_fill( pose->keyframes[i].s, 1.0f );
-      q_identity( pose->keyframes[i].q );
+   v3_copy( d->co_lpf, localplayer.rb.co );
+   v3_zero( localplayer.rb.v );
+   v3_zero( localplayer.rb.w );
+
+   if( (skaterift.activity == k_skaterift_default) && 
+         button_down(k_srbind_dead_respawn) ){
+      ent_spawn *spawn = world_find_closest_spawn( 
+            world_current_instance(), localplayer.rb.co );
+
+      if( spawn ){
+         v3_copy( spawn->transform.co, localplayer.rb.co );
+         player__reset();
+         srinput.state = k_input_state_resume;
+      }
+      else {
+         vg_error( "No spawns!\n" );
+      }
    }
 }
 
-VG_STATIC void player__dead_post_animate( player_instance *player ){
-   struct player_avatar *av = player->playeravatar;
-   struct player_dead   *d  = &player->_dead;
+void player__dead_animate(void){
+   struct player_dead *d = &player_dead;
+   struct player_dead_animator *animator = &d->animator;
+   struct player_ragdoll *rd = &localplayer.ragdoll;
+   struct skeleton *sk = &localplayer.skeleton;
 
-   copy_ragdoll_pose_to_avatar( &player->ragdoll, player->playeravatar );
-   player->cam_velocity_influence = 1.0f;
+   m4x3f transforms[ 32 ];
 
-   struct ragdoll_part *part = &player->ragdoll.parts[ av->id_hip-1 ];
+   /* root transform */
+   q_m3x3( localplayer.rb.q, transforms[0] );
+   v3_copy( localplayer.rb.co, transforms[0][3] );
 
-   v3f ext_co;
-   v4f ext_q;
-   rb_extrapolate( &part->obj.rb, ext_co, ext_q );
+   v4_copy( localplayer.rb.q, animator->transforms[0].q );
+   v3_copy( localplayer.rb.co, animator->transforms[0].co );
 
-   v3_lerp( d->co_lpf, ext_co, vg.time_frame_delta*4.0f, d->co_lpf );
-   v3_lerp( d->v_lpf,  part->obj.rb.v,  vg.time_frame_delta*4.0f, d->v_lpf );
-   v3_lerp( d->w_lpf,  part->obj.rb.w,  vg.time_frame_delta*4.0f, d->w_lpf );
-   
-   v3_copy( d->co_lpf, player->rb.co );
-   v3_zero( player->rb.v );
-   v3_zero( player->rb.w );
+   /* colliders with bones transforms */
+   for( int i=0; i<rd->part_count; i++ ){
+      struct ragdoll_part *part = &rd->parts[i];
+
+      m4x3f mtx;
+
+      v4f q_int;
+      v3f co_int;
+
+      float substep = vg.time_fixed_extrapolate;
+      v3_lerp( part->prev_co, part->rb.co, substep, co_int );
+      q_nlerp( part->prev_q, part->rb.q, substep, q_int );
+      v4_copy( part->rb.q, q_int );
+
+      q_m3x3( q_int, mtx );
+      v3_copy( co_int, mtx[3] );
+
+      m4x3_mul( mtx, part->inv_collider_mtx, transforms[part->bone_id] );
+   }
+
+   /* bones without colliders transforms */
+   for( u32 i=1; i<sk->bone_count; i++ ){
+      struct skeleton_bone *sb = &sk->bones[i];
+
+      if( sb->parent && !sb->collider ){
+         v3f delta;
+         v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, delta );
+
+         m4x3f posemtx;
+         m3x3_identity( posemtx );
+         v3_copy( delta, posemtx[3] );
+
+         /* final matrix */
+         m4x3_mul( transforms[sb->parent], posemtx, transforms[i] );
+      }
+   }
+
+   /* measurements */
+   for( u32 i=1; i<sk->bone_count; i++ ){
+      struct skeleton_bone *sb = &sk->bones[i];
+
+      v3_zero( animator->transforms[i].co );
+      q_identity( animator->transforms[i].q );
+
+      m4x3f parent, inverse, local;
+      m3x3_identity( parent );
+      v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, parent[3] );
+      m4x3_mul( transforms[ sb->parent ], parent, parent );
+      m4x3_invert_affine( parent, inverse );
+
+      v3f _s;
+      m4x3_mul( inverse, transforms[i], local );
+      m4x3_decompose( local, animator->transforms[i].co, 
+                             animator->transforms[i].q, _s );
+   }
 }
 
-VG_STATIC void player__dead_im_gui      ( player_instance *player ){
+void player__dead_pose( void *_animator, player_pose *pose )
+{
+   struct player_dead_animator *animator = _animator;
+   struct player_ragdoll *rd = &localplayer.ragdoll;
+   struct skeleton *sk = &localplayer.skeleton;
+
+   pose->type = k_player_pose_type_fk_2;
+   pose->board.lean = 0.0f;
+
+   v3_copy( animator->transforms[0].co, pose->root_co );
+   v4_copy( animator->transforms[0].q, pose->root_q );
+
+   for( u32 i=1; i<sk->bone_count; i++ ){
+      v3_copy( animator->transforms[i].co, pose->keyframes[i-1].co );
+      v4_copy( animator->transforms[i].q, pose->keyframes[i-1].q );
+      v3_fill( pose->keyframes[i-1].s, 1.0f );
+   }
+}
 
+void player__dead_post_animate(void)
+{
+   localplayer.cam_velocity_influence = 1.0f;
 }
 
-VG_STATIC void player__dead_transition  ( player_instance *player ){
-   player->subsystem = k_player_subsystem_dead;
-   copy_avatar_pose_to_ragdoll( player->playeravatar, &player->ragdoll, 
-                                player->rb.v );
-
-   struct player_avatar *av = player->playeravatar;
-   struct ragdoll_part *part = &player->ragdoll.parts[ av->id_hip-1 ];
-   struct player_dead   *d  = &player->_dead;
-   v3_copy( part->obj.rb.co, d->co_lpf );
-   v3_copy( part->obj.rb.v,  d->v_lpf );
-   v3_copy( part->obj.rb.w,  d->w_lpf );
+void player__dead_im_gui(void)
+{
 }
 
-#endif /* PLAYER_DEAD_C */
+void player__dead_transition( enum player_die_type type )
+{
+   if( localplayer.subsystem == k_player_subsystem_dead )
+      return;
+
+   localplayer.subsystem = k_player_subsystem_dead;
+   copy_localplayer_to_ragdoll( &localplayer.ragdoll, type );
+
+   struct ragdoll_part *part = 
+      &localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
+   v3_copy( part->rb.co, player_dead.co_lpf );
+   v3_copy( part->rb.v,  player_dead.v_lpf );
+   v3_copy( part->rb.w,  player_dead.w_lpf );
+
+   gui_helper_clear();
+   vg_str str;
+
+   struct gui_helper *h;
+   if( (h = gui_new_helper(input_button_list[k_srbind_reset], &str) )){
+      vg_strcat( &str, "Rewind" );
+
+      if( world_static.active_instance == k_world_purpose_hub )
+         h->greyed = 1;
+   }
+
+   if( gui_new_helper(input_button_list[k_srbind_dead_respawn], &str ))
+      vg_strcat( &str, "Spawn" );
+}
+
+void player__dead_animator_exchange( bitpack_ctx *ctx, void *data )
+{
+   struct player_dead_animator *animator = data;
+
+   for( u32 i=0; i<localplayer.skeleton.bone_count; i ++ ){
+      bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->transforms[i].co );
+      bitpack_qquat( ctx, animator->transforms[i].q );
+   }
+}
+
+void player__dead_bind(void)
+{
+   struct skeleton *sk = &localplayer.skeleton;
+   player_dead.anim_bail = skeleton_get_anim( sk, "pose_bail_ball" );
+}