2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
5 #ifndef PLAYER_ANIMATION_H
6 #define PLAYER_ANIMATION_H
9 #include "player_physics_walk.h"
11 VG_STATIC
void player_animate_offboard(void)
13 player_walk_animate( &player_walky
, &player
.mdl
.sk
, NULL
);
16 VG_STATIC
void player_animate(void)
19 struct player_phys
*phys
= &player
.phys
;
20 rb_extrapolate_transform( &player
.phys
.rb
, player
.visual_transform
);
21 v3_muladds( player
.visual_transform
[3], phys
->rb
.up
, -0.2f
,
22 player
.visual_transform
[3] );
26 float substep
= vg_clampf( vg
.accumulator
/ VG_TIMESTEP_FIXED
, 0.0f
, 1.0f
);
27 q_axis_angle( qfake_rot
, phys
->rb
.up
, phys
->siY
*substep
);
28 q_m3x3( qfake_rot
, fake_rot
);
29 m3x3_mul( fake_rot
, player
.visual_transform
, player
.visual_transform
);
31 m4x3_invert_affine( player
.visual_transform
, player
.inv_visual_transform
);
33 if( phys
->controller
== k_player_controller_walk
)
35 player_animate_offboard();
40 v3_muladds( phys
->m
, phys
->a
, VG_TIMESTEP_FIXED
, phys
->m
);
41 v3_lerp( phys
->m
, (v3f
){0.0f
,0.0f
,0.0f
}, 0.1f
, phys
->m
);
43 phys
->m
[0] = vg_clampf( phys
->m
[0], -2.0f
, 2.0f
);
44 phys
->m
[1] = vg_clampf( phys
->m
[1], -2.0f
, 2.0f
);
45 phys
->m
[2] = vg_clampf( phys
->m
[2], -2.0f
, 2.0f
);
46 v3_lerp( phys
->bob
, phys
->m
, 0.2f
, phys
->bob
);
49 float lslip
= fabsf(phys
->slip
);
56 m3x3_mulv( player
.inv_visual_transform
, phys
->bob
, offset
);
58 static float speed_wobble
= 0.0f
, speed_wobble_2
= 0.0f
;
60 float kickspeed
= vg_clampf(v3_length(phys
->rb
.v
)*(1.0f
/40.0f
), 0.0f
, 1.0f
);
61 float kicks
= (vg_randf()-0.5f
)*2.0f
*kickspeed
;
62 float sign
= vg_signf( kicks
);
63 speed_wobble
= vg_lerpf( speed_wobble
, kicks
*kicks
*sign
, 6.0f
*vg
.time_delta
);
64 speed_wobble_2
= vg_lerpf( speed_wobble_2
, speed_wobble
, 2.4f
*vg
.time_delta
);
67 offset
[0] += speed_wobble_2
*3.0f
;
72 offset
[0]=vg_clampf(offset
[0],-0.8f
,0.8f
)*(1.0f
-fabsf(player
.fslide
)*0.9f
);
73 offset
[1]=vg_clampf(offset
[1],-0.5f
,0.0f
);
77 * ===========================================
80 /* scalar blending information */
81 float speed
= v3_length( phys
->rb
.v
);
85 float desired
= vg_clampf( lslip
, 0.0f
, 1.0f
);
86 player
.fslide
= vg_lerpf( player
.fslide
, desired
, 2.4f
*vg
.time_delta
);
89 /* movement information */
91 int iair
= (player_skate
.activity
== k_skate_activity_air
) ||
92 (player_skate
.activity
== k_skate_activity_grind
);
94 float dirz
= phys
->reverse
> 0.0f
? 0.0f
: 1.0f
,
95 dirx
= phys
->slip
< 0.0f
? 0.0f
: 1.0f
,
96 fly
= iair
? 1.0f
: 0.0f
;
98 player
.fdirz
= vg_lerpf( player
.fdirz
, dirz
, 2.4f
*vg
.time_delta
);
99 player
.fdirx
= vg_lerpf( player
.fdirx
, dirx
, 0.6f
*vg
.time_delta
);
100 player
.ffly
= vg_lerpf( player
.ffly
, fly
, 2.4f
*vg
.time_delta
);
103 struct skeleton
*sk
= &player
.mdl
.sk
;
105 mdl_keyframe apose
[32], bpose
[32];
106 mdl_keyframe ground_pose
[32];
108 /* when the player is moving fast he will crouch down a little bit */
109 float stand
= 1.0f
- vg_clampf( speed
* 0.03f
, 0.0f
, 1.0f
);
110 player
.fstand
= vg_lerpf( player
.fstand
, stand
, 6.0f
*vg
.time_delta
);
113 float dir_frame
= player
.fdirz
* (15.0f
/30.0f
),
114 stand_blend
= offset
[1]*-2.0f
;
117 m4x3_mulv( player
.phys
.rb
.to_local
, player
.phys
.cog
, local_cog
);
119 stand_blend
= vg_clampf( 1.0f
-local_cog
[1], 0, 1 );
121 skeleton_sample_anim( sk
, player
.mdl
.anim_stand
, dir_frame
, apose
);
122 skeleton_sample_anim( sk
, player
.mdl
.anim_highg
, dir_frame
, bpose
);
123 skeleton_lerp_pose( sk
, apose
, bpose
, stand_blend
, apose
);
126 float slide_frame
= player
.fdirx
* (15.0f
/30.0f
);
127 skeleton_sample_anim( sk
, player
.mdl
.anim_slide
, slide_frame
, bpose
);
128 skeleton_lerp_pose( sk
, apose
, bpose
, player
.fslide
, apose
);
131 double push_time
= vg
.time
- player
.phys
.start_push
;
133 player
.fpush
= vg_lerpf( player
.fpush
,
134 (vg
.time
- player
.phys
.cur_push
) < 0.125,
135 6.0f
*vg
.time_delta
);
137 float pt
= push_time
+ vg
.accumulator
;
138 if( phys
->reverse
> 0.0f
)
139 skeleton_sample_anim( sk
, player
.mdl
.anim_push
, pt
, bpose
);
141 skeleton_sample_anim( sk
, player
.mdl
.anim_push_reverse
, pt
, bpose
);
143 skeleton_lerp_pose( sk
, apose
, bpose
, player
.fpush
, apose
);
146 float jump_start_frame
= 14.0f
/30.0f
;
148 player
.fjump
= vg_lerpf( player
.fjump
, phys
->jump
, 8.4f
*vg
.time_delta
);
150 float setup_frame
= phys
->jump
* jump_start_frame
,
151 setup_blend
= vg_minf( player
.fjump
, 1.0f
);
153 float jump_frame
= (vg
.time
- player
.jump_time
) + jump_start_frame
;
154 if( jump_frame
>= jump_start_frame
&& jump_frame
<= (40.0f
/30.0f
) )
155 setup_frame
= jump_frame
;
157 struct skeleton_anim
*jump_anim
= phys
->jump_dir
?
158 player
.mdl
.anim_ollie
:
159 player
.mdl
.anim_ollie_reverse
;
161 skeleton_sample_anim_clamped( sk
, jump_anim
, setup_frame
, bpose
);
162 skeleton_lerp_pose( sk
, apose
, bpose
, setup_blend
, ground_pose
);
165 mdl_keyframe air_pose
[32];
167 float target
= -player
.input_js1h
->axis
.value
;
168 player
.fairdir
= vg_lerpf( player
.fairdir
, target
, 2.4f
*vg
.time_delta
);
170 float air_frame
= (player
.fairdir
*0.5f
+0.5f
) * (15.0f
/30.0f
);
172 skeleton_sample_anim( sk
, player
.mdl
.anim_air
, air_frame
, apose
);
174 static v2f grab_choice
;
176 v2f grab_input
= { player
.input_js2h
->axis
.value
,
177 player
.input_js2v
->axis
.value
};
178 v2_add( player
.phys
.grab_mouse_delta
, grab_input
, grab_input
);
179 if( v2_length2( grab_input
) <= 0.001f
)
180 grab_input
[0] = -1.0f
;
182 v2_normalize_clamp( grab_input
);
183 v2_lerp( grab_choice
, grab_input
, 2.4f
*vg
.time_delta
, grab_choice
);
185 float ang
= atan2f( grab_choice
[0], grab_choice
[1] ),
186 ang_unit
= (ang
+VG_PIf
) * (1.0f
/VG_TAUf
),
187 grab_frame
= ang_unit
* (15.0f
/30.0f
);
189 skeleton_sample_anim( sk
, player
.mdl
.anim_grabs
, grab_frame
, bpose
);
190 skeleton_lerp_pose( sk
, apose
, bpose
, phys
->grab
, air_pose
);
193 skeleton_lerp_pose( sk
, ground_pose
, air_pose
, player
.ffly
, apose
);
195 float add_grab_mod
= 1.0f
- player
.ffly
;//*phys->grab;
197 /* additive effects */
199 u32 apply_to
[] = { player
.mdl
.id_hip
,
200 player
.mdl
.id_ik_hand_l
,
201 player
.mdl
.id_ik_hand_r
,
202 player
.mdl
.id_ik_elbow_l
,
203 player
.mdl
.id_ik_elbow_r
};
205 for( int i
=0; i
<vg_list_size(apply_to
); i
++ )
207 apose
[apply_to
[i
]-1].co
[0] += offset
[0]*add_grab_mod
;
208 apose
[apply_to
[i
]-1].co
[2] += offset
[2]*add_grab_mod
;
212 v3_muls( player
.board_offset
, add_grab_mod
, bo
);
214 v3_add( bo
, apose
[ player
.mdl
.id_board
-1 ].co
,
215 apose
[ player
.mdl
.id_board
-1 ].co
);
216 v3_add( bo
, apose
[ player
.mdl
.id_ik_foot_l
-1 ].co
,
217 apose
[ player
.mdl
.id_ik_foot_l
-1 ].co
);
218 v3_add( bo
, apose
[ player
.mdl
.id_ik_foot_r
-1 ].co
,
219 apose
[ player
.mdl
.id_ik_foot_r
-1 ].co
);
222 q_m3x3( player
.board_rotation
, c
);
225 v3_sub( apose
[ player
.mdl
.id_ik_foot_l
-1 ].co
, bo
, d
);
226 m3x3_mulv( c
, d
, d
);
227 v3_add( bo
, d
, apose
[ player
.mdl
.id_ik_foot_l
-1 ].co
);
229 v3_sub( apose
[ player
.mdl
.id_ik_foot_r
-1 ].co
, bo
, d
);
230 m3x3_mulv( c
, d
, d
);
231 v3_add( bo
, d
, apose
[ player
.mdl
.id_ik_foot_r
-1 ].co
);
233 q_mul( player
.board_rotation
, apose
[ player
.mdl
.id_board
-1 ].q
,
234 apose
[ player
.mdl
.id_board
-1 ].q
);
235 q_normalize( apose
[ player
.mdl
.id_board
-1 ].q
);
238 skeleton_apply_pose( &player
.mdl
.sk
, apose
, k_anim_apply_defer_ik
);
239 skeleton_apply_ik_pass( &player
.mdl
.sk
);
240 skeleton_apply_pose( &player
.mdl
.sk
, apose
, k_anim_apply_deffered_only
);
242 v3_copy( player
.mdl
.sk
.final_mtx
[player
.mdl
.id_head
-1][3],
243 player
.mdl
.cam_pos
);
244 skeleton_apply_inverses( &player
.mdl
.sk
);
246 skeleton_apply_transform( &player
.mdl
.sk
, player
.visual_transform
);
247 skeleton_debug( &player
.mdl
.sk
);
251 VG_STATIC
void player_animate_death_cam(void)
255 v3_copy( player
.mdl
.ragdoll
[0].rb
.co
, head_pos
);
257 v3_sub( head_pos
, player
.camera_pos
, delta
);
258 v3_normalize( delta
);
261 v3_muladds( head_pos
, delta
, -2.5f
, follow_pos
);
262 v3_lerp( player
.camera_pos
, follow_pos
, 0.1f
, player
.camera_pos
);
265 * Make sure the camera stays above the ground
267 v3f min_height
= {0.0f
,1.0f
,0.0f
};
270 v3_add( player
.camera_pos
, min_height
, sample
);
272 hit
.dist
= min_height
[1]*2.0f
;
274 if( ray_world( sample
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
275 v3_add( hit
.pos
, min_height
, player
.camera_pos
);
277 if( world
.water
.enabled
)
279 player
.camera_pos
[1] =
280 vg_maxf( world
.water
.height
+ 2.0f
, player
.camera_pos
[1] );
283 player
.angles
[0] = atan2f( delta
[0], -delta
[2] );
284 player
.angles
[1] = -asinf( delta
[1] );
287 VG_STATIC
void player_animate_follow_cam( v3f target
, float dist
, float speed
)
291 v3_sub( target
, player
.camera_pos
, delta
);
292 v3_normalize( delta
);
295 v3_muladds( target
, delta
, -dist
, follow_pos
);
296 v3_lerp( player
.camera_pos
, follow_pos
,
297 speed
* vg
.time_delta
, player
.camera_pos
);
300 * Make sure the camera stays above the ground
302 v3f min_height
= {0.0f
,1.0f
,0.0f
};
305 v3_add( player
.camera_pos
, min_height
, sample
);
307 hit
.dist
= min_height
[1]*2.0f
;
309 if( ray_world( sample
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
310 v3_add( hit
.pos
, min_height
, player
.camera_pos
);
313 if( world
.water
.enabled
)
315 player
.camera_pos
[1] =
316 vg_maxf( world
.water
.height
+ 2.0f
, player
.camera_pos
[1] );
320 player
.angles
[0] = atan2f( delta
[0], -delta
[2] );
321 player
.angles
[1] = -asinf( delta
[1] );
324 VG_STATIC
void player_animate_camera_thirdperson(void)
326 static v3f lerp_cam
= { 0.0f
, 0.0f
, 0.0f
};
329 v3_muladds( player
.rb
.co
, player
.rb
.up
, 1.2f
, target
);
331 player_animate_follow_cam( target
, 1.5f
, 20.0f
);
334 VG_STATIC
void player_animate_camera(void)
336 static v3f lerp_cam
= {0.0f
,0.0f
,0.0f
};
339 int _on_board
= player
.controller
== k_player_controller_skate
;
340 player
.fonboard
= vg_lerpf( player
.fonboard
, _on_board
, vg
.time_delta
);
345 v3f offs
= { -0.4f
, 0.15f
, 0.0f
};
346 v3_lerp( lerp_cam
, player
.mdl
.cam_pos
, 0.8f
, lerp_cam
);
347 v3_add( lerp_cam
, offs
, cam_pos
);
350 v3_lerp( phys
->vl
, phys
->rb
.v
, 0.05f
, phys
->vl
);
352 int _grind
= player_skate
.activity
== k_skate_activity_grind
;
354 player
.fgrind
= vg_lerpf( player
.fgrind
, _grind
, vg
.time_delta
);
356 float yaw
= atan2f( phys
->vl
[0], -phys
->vl
[2] ),
362 phys
->vl
[0]*phys
->vl
[0] + phys
->vl
[2]*phys
->vl
[2]
365 * 0.7f
+ vg_lerpf( 0.30f
, 0.90f
, player
.fgrind
);
367 player
.angles
[0] = yaw
;
368 player
.angles
[1] = vg_lerpf( player
.angles
[1], pitch
, player
.fonboard
);
371 static v2f shake_damp
= {0.0f
,0.0f
};
372 v2f shake
= { vg_randf()-0.5f
, vg_randf()-0.5f
};
373 v2_muls( shake
, v3_length(phys
->rb
.v
)*0.3f
374 * (1.0f
+fabsf(phys
->slip
)), shake
);
376 v2_lerp( shake_damp
, shake
, 0.01f
, shake_damp
);
377 shake_damp
[0] *= 0.2f
;
379 v2_muladds( player
.angles
, shake_damp
, 0.1f
, player
.angles
);
380 m4x3_mulv( player
.visual_transform
, cam_pos
, player
.camera_pos
);
386 float speed
= vg
.time_delta
* k_look_speed
;
387 player
.angles
[0] += vg_get_axis( "lookh" ) * speed
;
388 player
.angles
[1] += vg_get_axis( "lookv" ) * speed
;
390 player
.angles
[1] = vg_clampf( player
.angles
[1],
391 -k_pitch_limit
, k_pitch_limit
);
394 float s
= sinf(player
.angles
[0]) * 0.2f
,
395 c
= -cosf(player
.angles
[0]) * 0.2f
;
396 v3f forward_dir
= { s
,0.15f
,c
};
401 q_axis_angle( rot
, (v3f
){0.0f
,1.0f
,0.0f
},
402 -player
.angles
[0] -VG_PIf
*0.5f
);
404 v3_copy( player
.visual_transform
[3], mtx
[3] );
406 m4x3_mulv( mtx
, player
.mdl
.cam_pos
, cam_pos
);
407 v3_add( cam_pos
, forward_dir
, player
.camera_pos
);
410 v3_lerp( phys
->vl
, phys
->rb
.v
, 18.0f
*vg
.time_delta
, phys
->vl
);
415 #endif /* PLAYER_ANIMATION_H */