fix regression with gate flipping
[carveJwlIkooP6JGAAIwe30JlM.git] / player_dead.c
1 #include "skaterift.h"
2 #include "player_dead.h"
3 #include "gui.h"
4
5 struct player_dead player_dead;
6 struct player_subsystem_interface player_subsystem_dead = {
7 .update = player__dead_update,
8 .post_update = player__dead_post_update,
9 .animate = player__dead_animate,
10 .pose = player__dead_pose,
11 .post_animate = player__dead_post_animate,
12 .im_gui = player__dead_im_gui,
13 .bind = player__dead_bind,
14
15 .animator_data = &player_dead.animator,
16 .animator_size = sizeof(player_dead.animator),
17 .network_animator_exchange = player__dead_animator_exchange,
18 .name = "Dead"
19 };
20
21 void player__dead_update(void){
22 player_ragdoll_iter( &localplayer.ragdoll );
23 }
24
25 void player__dead_post_update(void){
26 struct ragdoll_part *part =
27 &localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
28 struct player_dead *d = &player_dead;
29
30 v3f ext_co;
31 v4f ext_q;
32 rb_extrapolate( &part->rb, ext_co, ext_q );
33
34 v3_lerp( d->co_lpf, ext_co, vg.time_frame_delta*4.0f, d->co_lpf );
35 v3_lerp( d->v_lpf, part->rb.v, vg.time_frame_delta*4.0f, d->v_lpf );
36 v3_lerp( d->w_lpf, part->rb.w, vg.time_frame_delta*4.0f, d->w_lpf );
37
38 v3_copy( d->co_lpf, localplayer.rb.co );
39 v3_zero( localplayer.rb.v );
40 v3_zero( localplayer.rb.w );
41
42 if( (skaterift.activity == k_skaterift_default) &&
43 button_down(k_srbind_dead_respawn) ){
44 ent_spawn *spawn = world_find_closest_spawn(
45 world_current_instance(), localplayer.rb.co );
46
47 if( spawn ){
48 v3_copy( spawn->transform.co, localplayer.rb.co );
49 player__reset();
50 srinput.state = k_input_state_resume;
51 }
52 else {
53 vg_error( "No spawns!\n" );
54 }
55 }
56 }
57
58 void player__dead_animate(void){
59 struct player_dead *d = &player_dead;
60 struct player_dead_animator *animator = &d->animator;
61 struct player_ragdoll *rd = &localplayer.ragdoll;
62 struct skeleton *sk = &localplayer.skeleton;
63
64 m4x3f transforms[ 32 ];
65
66 /* root transform */
67 q_m3x3( localplayer.rb.q, transforms[0] );
68 v3_copy( localplayer.rb.co, transforms[0][3] );
69
70 v4_copy( localplayer.rb.q, animator->transforms[0].q );
71 v3_copy( localplayer.rb.co, animator->transforms[0].co );
72
73 /* colliders with bones transforms */
74 for( int i=0; i<rd->part_count; i++ ){
75 struct ragdoll_part *part = &rd->parts[i];
76
77 m4x3f mtx;
78
79 v4f q_int;
80 v3f co_int;
81
82 float substep = vg.time_fixed_extrapolate;
83 v3_lerp( part->prev_co, part->rb.co, substep, co_int );
84 q_nlerp( part->prev_q, part->rb.q, substep, q_int );
85 v4_copy( part->rb.q, q_int );
86
87 q_m3x3( q_int, mtx );
88 v3_copy( co_int, mtx[3] );
89
90 m4x3_mul( mtx, part->inv_collider_mtx, transforms[part->bone_id] );
91 }
92
93 /* bones without colliders transforms */
94 for( u32 i=1; i<sk->bone_count; i++ ){
95 struct skeleton_bone *sb = &sk->bones[i];
96
97 if( sb->parent && !sb->collider ){
98 v3f delta;
99 v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, delta );
100
101 m4x3f posemtx;
102 m3x3_identity( posemtx );
103 v3_copy( delta, posemtx[3] );
104
105 /* final matrix */
106 m4x3_mul( transforms[sb->parent], posemtx, transforms[i] );
107 }
108 }
109
110 /* measurements */
111 for( u32 i=1; i<sk->bone_count; i++ ){
112 struct skeleton_bone *sb = &sk->bones[i];
113
114 v3_zero( animator->transforms[i].co );
115 q_identity( animator->transforms[i].q );
116
117 m4x3f parent, inverse, local;
118 m3x3_identity( parent );
119 v3_sub( sk->bones[i].co, sk->bones[sb->parent].co, parent[3] );
120 m4x3_mul( transforms[ sb->parent ], parent, parent );
121 m4x3_invert_affine( parent, inverse );
122
123 v3f _s;
124 m4x3_mul( inverse, transforms[i], local );
125 m4x3_decompose( local, animator->transforms[i].co,
126 animator->transforms[i].q, _s );
127 }
128 }
129
130 void player__dead_pose( void *_animator, player_pose *pose )
131 {
132 struct player_dead_animator *animator = _animator;
133 struct player_ragdoll *rd = &localplayer.ragdoll;
134 struct skeleton *sk = &localplayer.skeleton;
135
136 pose->type = k_player_pose_type_fk_2;
137 pose->board.lean = 0.0f;
138
139 v3_copy( animator->transforms[0].co, pose->root_co );
140 v4_copy( animator->transforms[0].q, pose->root_q );
141
142 for( u32 i=1; i<sk->bone_count; i++ ){
143 v3_copy( animator->transforms[i].co, pose->keyframes[i-1].co );
144 v4_copy( animator->transforms[i].q, pose->keyframes[i-1].q );
145 v3_fill( pose->keyframes[i-1].s, 1.0f );
146 }
147 }
148
149 void player__dead_post_animate(void)
150 {
151 localplayer.cam_velocity_influence = 1.0f;
152 }
153
154 void player__dead_im_gui(void)
155 {
156 }
157
158 void player__dead_transition( enum player_die_type type )
159 {
160 localplayer.subsystem = k_player_subsystem_dead;
161 copy_localplayer_to_ragdoll( &localplayer.ragdoll, type );
162
163 struct ragdoll_part *part =
164 &localplayer.ragdoll.parts[ localplayer.id_hip-1 ];
165 v3_copy( part->rb.co, player_dead.co_lpf );
166 v3_copy( part->rb.v, player_dead.v_lpf );
167 v3_copy( part->rb.w, player_dead.w_lpf );
168
169 gui_helper_clear();
170 vg_str str;
171
172 struct gui_helper *h;
173 if( (h = gui_new_helper(input_button_list[k_srbind_reset], &str) )){
174 vg_strcat( &str, "rewind" );
175
176 if( world_static.active_instance == k_world_purpose_hub )
177 h->greyed = 1;
178 }
179
180 if( gui_new_helper(input_button_list[k_srbind_dead_respawn], &str ))
181 vg_strcat( &str, "spawn" );
182 }
183
184 void player__dead_animator_exchange( bitpack_ctx *ctx, void *data )
185 {
186 struct player_dead_animator *animator = data;
187
188 for( u32 i=0; i<localplayer.skeleton.bone_count; i ++ ){
189 bitpack_qv3f( ctx, 24, -1024.0f, 1024.0f, animator->transforms[i].co );
190 bitpack_qquat( ctx, animator->transforms[i].q );
191 }
192 }
193
194 void player__dead_bind(void)
195 {
196 struct skeleton *sk = &localplayer.skeleton;
197 player_dead.anim_bail = skeleton_get_anim( sk, "pose_bail_ball" );
198 }