1 #ifndef PLAYER_ANIMATION_H
2 #define PLAYER_ANIMATION_H
6 static void player_animate_offboard(void)
8 mdl_keyframe apose
[32], bpose
[32];
9 struct skeleton
*sk
= &player
.mdl
.sk
;
11 float walk_norm
= (float)player
.mdl
.anim_walk
->length
/30.0f
,
12 run_norm
= (float)player
.mdl
.anim_run
->length
/30.0f
,
13 t
= player
.walk_timer
,
14 l
= vg_get_axis("grabr") * 0.5f
+ 0.5f
;
16 skeleton_sample_anim( sk
, player
.mdl
.anim_walk
, t
*walk_norm
, apose
);
17 skeleton_sample_anim( sk
, player
.mdl
.anim_run
, t
*run_norm
, bpose
);
19 skeleton_lerp_pose( sk
, apose
, bpose
, l
, apose
);
21 float idle_walk
= vg_minf( l
* 10.0f
, 1.0f
);
23 skeleton_sample_anim( sk
, player
.mdl
.anim_idle
, vg_time
*0.1f
, bpose
);
24 skeleton_lerp_pose( sk
, apose
, bpose
, 1.0f
-idle_walk
, apose
);
26 skeleton_apply_pose( &player
.mdl
.sk
, apose
, k_anim_apply_defer_ik
);
27 skeleton_apply_ik_pass( &player
.mdl
.sk
);
28 skeleton_apply_pose( &player
.mdl
.sk
, apose
, k_anim_apply_deffered_only
);
30 v3_copy( player
.mdl
.sk
.final_mtx
[player
.mdl
.id_head
-1][3],
33 skeleton_apply_inverses( &player
.mdl
.sk
);
37 q_axis_angle( rot
, (v3f
){0.0f
,1.0f
,0.0f
}, -player
.angles
[0] - VG_PIf
*0.5f
);
39 v3_copy( player
.rb
.to_world
[3], mtx
[3] );
41 skeleton_apply_transform( &player
.mdl
.sk
, mtx
);
42 skeleton_debug( &player
.mdl
.sk
);
45 static void player_animate(void)
47 if( !player
.on_board
)
49 player_animate_offboard();
54 v3_sub( player
.rb
.v
, player
.v_last
, player
.a
);
55 v3_copy( player
.rb
.v
, player
.v_last
);
57 v3_add( player
.m
, player
.a
, player
.m
);
58 v3_lerp( player
.m
, (v3f
){0.0f
,0.0f
,0.0f
}, 0.1f
, player
.m
);
60 player
.m
[0] = vg_clampf( player
.m
[0], -2.0f
, 2.0f
);
61 player
.m
[1] = vg_clampf( player
.m
[1], -2.0f
, 2.0f
);
62 player
.m
[2] = vg_clampf( player
.m
[2], -2.0f
, 2.0f
);
63 v3_lerp( player
.bob
, player
.m
, 0.2f
, player
.bob
);
66 float lslip
= fabsf(player
.slip
);
73 m3x3_mulv( player
.rb
.to_local
, player
.bob
, offset
);
75 static float speed_wobble
= 0.0f
, speed_wobble_2
= 0.0f
;
77 float kickspeed
= vg_clampf(v3_length(player
.rb
.v
)*(1.0f
/40.0f
), 0.0f
, 1.0f
);
78 float kicks
= (vg_randf()-0.5f
)*2.0f
*kickspeed
;
79 float sign
= vg_signf( kicks
);
80 speed_wobble
= vg_lerpf( speed_wobble
, kicks
*kicks
*sign
, 0.1f
);
81 speed_wobble_2
= vg_lerpf( speed_wobble_2
, speed_wobble
, 0.04f
);
84 offset
[0] += speed_wobble_2
*3.0f
;
89 offset
[0] = vg_clampf( offset
[0], -0.8f
, 0.8f
);
90 offset
[1] = vg_clampf( offset
[1], -0.5f
, 0.0f
);
94 * ===========================================
97 /* scalar blending information */
98 float speed
= v3_length( player
.rb
.v
);
102 float desired
= vg_clampf( lslip
, 0.0f
, 1.0f
);
103 player
.fslide
= vg_lerpf( player
.fslide
, desired
, 0.04f
);
106 /* movement information */
108 float dirz
= player
.reverse
> 0.0f
? 0.0f
: 1.0f
,
109 dirx
= player
.slip
< 0.0f
? 0.0f
: 1.0f
,
110 fly
= player
.in_air
? 1.0f
: 0.0f
;
112 player
.fdirz
= vg_lerpf( player
.fdirz
, dirz
, 0.04f
);
113 player
.fdirx
= vg_lerpf( player
.fdirx
, dirx
, 0.01f
);
114 player
.ffly
= vg_lerpf( player
.ffly
, fly
, 0.04f
);
117 struct skeleton
*sk
= &player
.mdl
.sk
;
119 mdl_keyframe apose
[32], bpose
[32];
120 mdl_keyframe ground_pose
[32];
122 /* when the player is moving fast he will crouch down a little bit */
123 float stand
= 1.0f
- vg_clampf( speed
* 0.03f
, 0.0f
, 1.0f
);
124 player
.fstand
= vg_lerpf( player
.fstand
, stand
, 0.1f
);
127 float dir_frame
= player
.fdirz
* (15.0f
/30.0f
),
128 stand_blend
= offset
[1]*-2.0f
;
130 skeleton_sample_anim( sk
, player
.mdl
.anim_stand
, dir_frame
, apose
);
131 skeleton_sample_anim( sk
, player
.mdl
.anim_highg
, dir_frame
, bpose
);
132 skeleton_lerp_pose( sk
, apose
, bpose
, stand_blend
, apose
);
135 float slide_frame
= player
.fdirx
* (15.0f
/30.0f
);
136 skeleton_sample_anim( sk
, player
.mdl
.anim_slide
, slide_frame
, bpose
);
137 skeleton_lerp_pose( sk
, apose
, bpose
, player
.fslide
, apose
);
140 player
.fpush
= vg_lerpf( player
.fpush
, player
.pushing
, 0.1f
);
142 float pt
= player
.push_time
;
143 if( player
.reverse
> 0.0f
)
144 skeleton_sample_anim( sk
, player
.mdl
.anim_push
, pt
, bpose
);
146 skeleton_sample_anim( sk
, player
.mdl
.anim_push_reverse
, pt
, bpose
);
148 skeleton_lerp_pose( sk
, apose
, bpose
, player
.fpush
, apose
);
151 float jump_start_frame
= 14.0f
/30.0f
;
152 float setup_frame
= player
.jump
* jump_start_frame
,
153 setup_blend
= vg_minf( player
.jump
*5.0f
, 1.0f
);
155 float jump_frame
= (vg_time
- player
.jump_time
) + jump_start_frame
;
156 if( jump_frame
>= jump_start_frame
&& jump_frame
<= (40.0f
/30.0f
) )
157 setup_frame
= jump_frame
;
159 struct skeleton_anim
*jump_anim
= player
.jump_dir
?
160 player
.mdl
.anim_ollie
:
161 player
.mdl
.anim_ollie_reverse
;
163 skeleton_sample_anim_clamped( sk
, jump_anim
, setup_frame
, bpose
);
164 skeleton_lerp_pose( sk
, apose
, bpose
, setup_blend
, ground_pose
);
167 mdl_keyframe air_pose
[32];
169 float target
= -vg_get_axis("horizontal");
170 player
.fairdir
= vg_lerpf( player
.fairdir
, target
, 0.04f
);
172 float air_frame
= (player
.fairdir
*0.5f
+0.5f
) * (15.0f
/30.0f
);
174 skeleton_sample_anim( sk
, player
.mdl
.anim_air
, air_frame
, apose
);
176 static v2f grab_choice
;
177 v2_lerp( grab_choice
, (v2f
){ vg_get_axis("h1"), vg_get_axis("v1") },
178 0.04f
, grab_choice
);
180 float ang
= atan2f( grab_choice
[0], grab_choice
[1] ),
181 ang_unit
= (ang
+VG_PIf
) * (1.0f
/VG_TAUf
),
182 grab_frame
= ang_unit
* (15.0f
/30.0f
);
184 skeleton_sample_anim( sk
, player
.mdl
.anim_grabs
, grab_frame
, bpose
);
185 skeleton_lerp_pose( sk
, apose
, bpose
, player
.grab
, air_pose
);
188 skeleton_lerp_pose( sk
, ground_pose
, air_pose
, player
.ffly
, apose
);
190 float add_grab_mod
= 1.0f
- player
.ffly
*player
.grab
;
192 /* additive effects */
193 apose
[player
.mdl
.id_hip
-1].co
[0] += offset
[0]*add_grab_mod
;
194 apose
[player
.mdl
.id_hip
-1].co
[2] += offset
[2]*add_grab_mod
;
195 apose
[player
.mdl
.id_ik_hand_l
-1].co
[0] += offset
[0]*add_grab_mod
;
196 apose
[player
.mdl
.id_ik_hand_l
-1].co
[2] += offset
[2]*add_grab_mod
;
197 apose
[player
.mdl
.id_ik_hand_r
-1].co
[0] += offset
[0]*add_grab_mod
;
198 apose
[player
.mdl
.id_ik_hand_r
-1].co
[2] += offset
[2]*add_grab_mod
;
199 apose
[player
.mdl
.id_ik_elbow_l
-1].co
[0] += offset
[0]*add_grab_mod
;
200 apose
[player
.mdl
.id_ik_elbow_l
-1].co
[2] += offset
[2]*add_grab_mod
;
201 apose
[player
.mdl
.id_ik_elbow_r
-1].co
[0] += offset
[0]*add_grab_mod
;
202 apose
[player
.mdl
.id_ik_elbow_r
-1].co
[2] += offset
[2]*add_grab_mod
;
204 skeleton_apply_pose( &player
.mdl
.sk
, apose
, k_anim_apply_defer_ik
);
205 skeleton_apply_ik_pass( &player
.mdl
.sk
);
206 skeleton_apply_pose( &player
.mdl
.sk
, apose
, k_anim_apply_deffered_only
);
208 v3_copy( player
.mdl
.sk
.final_mtx
[player
.mdl
.id_head
-1][3],
209 player
.mdl
.cam_pos
);
210 skeleton_apply_inverses( &player
.mdl
.sk
);
211 skeleton_apply_transform( &player
.mdl
.sk
, player
.rb
.to_world
);
213 skeleton_debug( &player
.mdl
.sk
);
216 static void player_animate_death_cam(void)
220 v3_copy( player
.mdl
.ragdoll
[0].rb
.co
, head_pos
);
222 v3_sub( head_pos
, player
.camera_pos
, delta
);
223 v3_normalize( delta
);
226 v3_muladds( head_pos
, delta
, -2.5f
, follow_pos
);
227 v3_lerp( player
.camera_pos
, follow_pos
, 0.1f
, player
.camera_pos
);
230 * Make sure the camera stays above the ground
232 v3f min_height
= {0.0f
,1.0f
,0.0f
};
235 v3_add( player
.camera_pos
, min_height
, sample
);
237 hit
.dist
= min_height
[1]*2.0f
;
239 if( ray_world( sample
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
240 v3_add( hit
.pos
, min_height
, player
.camera_pos
);
242 player
.camera_pos
[1] =
243 vg_maxf( wrender
.height
+ 2.0f
, player
.camera_pos
[1] );
245 player
.angles
[0] = atan2f( delta
[0], -delta
[2] );
246 player
.angles
[1] = -asinf( delta
[1] );
249 static void player_animate_camera(void)
251 static v3f lerp_cam
= {0.0f
,0.0f
,0.0f
};
254 player
.fonboard
= vg_lerpf(player
.fonboard
, player
.on_board
, ktimestep
*1.0f
);
256 if( player
.on_board
)
258 v3f offs
= { -0.4f
, 0.15f
, 0.0f
};
259 v3_lerp( lerp_cam
, player
.mdl
.cam_pos
, 0.8f
, lerp_cam
);
260 v3_add( lerp_cam
, offs
, cam_pos
);
263 v3_lerp( player
.vl
, player
.rb
.v
, 0.05f
, player
.vl
);
265 float yaw
= atan2f( player
.vl
[0], -player
.vl
[2] ),
266 pitch
= atan2f( -player
.vl
[1],
268 player
.vl
[0]*player
.vl
[0] + player
.vl
[2]*player
.vl
[2]
271 player
.angles
[0] = yaw
;
272 player
.angles
[1] = vg_lerpf( player
.angles
[1], pitch
+ 0.30f
,
276 static v2f shake_damp
= {0.0f
,0.0f
};
277 v2f shake
= { vg_randf()-0.5f
, vg_randf()-0.5f
};
278 v2_muls( shake
, v3_length(player
.rb
.v
)*0.3f
279 * (1.0f
+fabsf(player
.slip
)), shake
);
281 v2_lerp( shake_damp
, shake
, 0.01f
, shake_damp
);
282 shake_damp
[0] *= 0.2f
;
284 v2_muladds( player
.angles
, shake_damp
, 0.1f
, player
.angles
);
285 m4x3_mulv( player
.rb
.to_world
, cam_pos
, player
.camera_pos
);
289 float speed
= ktimestep
* k_look_speed
;
290 player
.angles
[0] += vg_get_axis( "horizontal" ) * speed
;
291 player
.angles
[1] += vg_get_axis( "vertical" ) * speed
;
293 player
.angles
[1] = vg_clampf( player
.angles
[1],
294 -k_pitch_limit
, k_pitch_limit
);
296 float s
= sinf(player
.angles
[0]) * 0.2f
,
297 c
= -cosf(player
.angles
[0]) * 0.2f
;
298 v3f forward_dir
= { s
,0.15f
,c
};
303 q_axis_angle( rot
, (v3f
){0.0f
,1.0f
,0.0f
},
304 -player
.angles
[0] -VG_PIf
*0.5f
);
306 v3_copy( player
.rb
.to_world
[3], mtx
[3] );
308 m4x3_mulv( mtx
, player
.mdl
.cam_pos
, cam_pos
);
309 v3_add( cam_pos
, forward_dir
, player
.camera_pos
);
310 v3_lerp( player
.vl
, player
.rb
.v
, 0.3f
, player
.vl
);
314 #endif /* PLAYER_ANIMATION_H */