refactor player
[carveJwlIkooP6JGAAIwe30JlM.git] / player.h
1 /*
2 * Copyright 2021-2022 (C) Mount0 Software, Harry Godden - All Rights Reserved
3 * -----------------------------------------------------------------------------
4 *
5 * Player head module
6 *
7 * -----------------------------------------------------------------------------
8 */
9
10 #ifndef PLAYER_H
11 #define PLAYER_H
12
13 #include "audio.h"
14 #include "common.h"
15 #include "world.h"
16 #include "skeleton.h"
17 #include "bvh.h"
18
19 static float
20 k_walkspeed = 7.0f, /* no longer used */
21 k_runspeed = 14.0f,
22 k_board_radius = 0.3f,
23 k_board_length = 0.45f,
24 k_board_allowance = 0.04f,
25 k_friction_lat = 8.8f,
26 k_friction_resistance = 0.01f,
27 k_max_push_speed = 16.0f,
28 k_push_accel = 10.0f,
29 k_push_cycle_rate = 8.0f,
30 k_steer_ground = 2.5f,
31 k_steer_air = 3.6f,
32 k_steer_air_lerp = 0.3f,
33 k_pump_force = 0.0f,
34 k_downforce = 5.0f,
35 k_jump_charge_speed = (1.0f/1.0f),
36 k_jump_force = 5.0f,
37 k_pitch_limit = 1.5f,
38 k_look_speed = 2.0f,
39 k_walk_accel = 5.0f,
40 k_walk_friction = 8.0f;
41
42 static int freecam = 0;
43 static int walk_grid_iterations = 1;
44 static float fc_speed = 10.0f;
45
46 /*
47 * -----------------------------------------------------------------------------
48 * Memory
49 * -----------------------------------------------------------------------------
50 */
51
52 static struct gplayer
53 {
54 /* Physics */
55 rigidbody rb, collide_front, collide_back, rb_gate_frame;
56
57 /* TODO: eugh */
58 m3x3f gate_vr_frame, gate_vr_pstep_frame;
59 int on_board_frame, in_air_frame;
60
61 v3f a, v_last, m, bob, vl;
62
63 /* Utility */
64 float vswitch, slip, slip_last,
65 reverse;
66
67 float iY; /* Yaw inertia */
68 int in_air, is_dead, on_board;
69
70 v2f board_xy;
71 float grab;
72 float pitch;
73 float pushing, push_time;
74 float jump;
75 int jump_charge, jump_dir;
76
77 v3f land_target;
78 v3f land_target_log[22];
79 u32 land_target_colours[22];
80 int land_log_count;
81 m3x3f vr,vr_pstep;
82
83 v3f handl_target, handr_target,
84 handl, handr;
85
86 /* Camera */
87 float air_blend;
88
89 v3f camera_pos, smooth_localcam;
90 v2f angles;
91 m4x3f camera, camera_inverse;
92
93 /* animation */
94 double jump_time;
95 float fslide,
96 fdirz, fdirx,
97 fstand,
98 ffly,
99 fpush,
100 fairdir,
101 fsetup,
102 walk_timer,
103 fonboard;
104 int step_phase;
105
106 /* player model */
107 struct player_model
108 {
109 glmesh mesh;
110 struct skeleton sk;
111 struct skeleton_anim *anim_stand,
112 *anim_highg,
113 *anim_slide,
114 *anim_air,
115 *anim_push, *anim_push_reverse,
116 *anim_ollie, *anim_ollie_reverse,
117 *anim_grabs, *anim_stop,
118 *anim_walk, *anim_run, *anim_idle;
119
120 u32 id_hip,
121 id_ik_hand_l,
122 id_ik_hand_r,
123 id_ik_elbow_l,
124 id_ik_elbow_r,
125 id_head;
126
127 v3f cam_pos;
128
129 struct ragdoll_part
130 {
131 u32 bone_id;
132 v3f offset;
133
134 u32 use_limits;
135 v3f limits[2];
136
137 rigidbody rb;
138 u32 parent;
139 }
140 *ragdoll;
141 u32 ragdoll_count;
142
143 int shoes[2];
144 }
145 mdl;
146 }
147 player =
148 {
149 .on_board = 0,
150
151 .collide_front = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f },
152 .collide_back = { .type = k_rb_shape_sphere, .inf.sphere.radius = 0.3f }
153 };
154
155 /*
156 * API
157 */
158 static float *player_get_pos(void);
159 static void player_kill(void);
160 static float *player_cam_pos(void);
161
162 /*
163 * Submodules
164 */
165 #include "player_physics.h"
166 #include "player_ragdoll.h"
167 #include "player_model.h"
168 #include "player_animation.h"
169 #include "player_audio.h"
170
171 /*
172 * -----------------------------------------------------------------------------
173 * Events
174 * -----------------------------------------------------------------------------
175 */
176
177 static void player_register(void) /* 0 */
178 {
179 player_model_register();
180 }
181
182 static void player_init(void) /* 1 */
183 {
184 player_model_init();
185
186 rb_init( &player.collide_front );
187 rb_init( &player.collide_back );
188 }
189
190 static void player_update(void) /* 2 */
191 {
192 for( int i=0; i<player.land_log_count; i++ )
193 vg_line_cross( player.land_target_log[i],
194 player.land_target_colours[i], 0.25f);
195
196 if( vg_get_axis("grabl")>0.0f)
197 {
198 player.rb = player.rb_gate_frame;
199 player.on_board = player.on_board_frame;
200 player.in_air = player.in_air_frame;
201 m3x3_copy( player.gate_vr_frame, player.vr );
202 m3x3_copy( player.gate_vr_pstep_frame, player.vr_pstep );
203 player.is_dead = 0;
204 player.in_air = 1;
205
206
207 if( !player.on_board )
208 {
209 player.angles[0] = atan2f( -player.rb.forward[2],
210 -player.rb.forward[0] );
211 }
212
213 m3x3_identity( player.vr );
214
215 player.mdl.shoes[0] = 1;
216 player.mdl.shoes[1] = 1;
217
218 world_routes_notify_reset();
219 }
220
221 if( vg_get_button_down( "switchmode" ) )
222 {
223 player.on_board ^= 0x1;
224 }
225
226 if( (glfwGetKey( vg_window, GLFW_KEY_O ) || (player.rb.co[1] < 0.0f)) &&
227 !player.is_dead)
228 {
229 player_ragdoll_copy_model( player.rb.v );
230 player.is_dead = 1;
231 }
232
233 if( player.is_dead )
234 {
235 player_ragdoll_iter();
236 player_debug_ragdoll();
237
238 if( !freecam )
239 player_animate_death_cam();
240 }
241 else
242 {
243 player_do_motion();
244 player_animate();
245
246 if( !freecam )
247 player_animate_camera();
248 }
249
250 if( freecam )
251 player_freecam();
252
253 player_camera_update();
254 player_audio();
255 }
256
257 static void draw_player(void) /* 3 */
258 {
259 if( player.is_dead )
260 player_model_copy_ragdoll();
261
262 shader_viewchar_use();
263 vg_tex2d_bind( &tex_characters, 0 );
264 shader_viewchar_uTexMain( 0 );
265 shader_viewchar_uCamera( player.camera[3] );
266 shader_viewchar_uPv( vg_pv );
267 shader_link_standard_ub( _shader_viewchar.id, 2 );
268 glUniformMatrix4x3fv( _uniform_viewchar_uTransforms,
269 player.mdl.sk.bone_count,
270 0,
271 (float *)player.mdl.sk.final_mtx );
272
273 mesh_bind( &player.mdl.mesh );
274 mesh_draw( &player.mdl.mesh );
275 }
276
277 /*
278 * -----------------------------------------------------------------------------
279 * API implementation
280 * -----------------------------------------------------------------------------
281 */
282
283 static float *player_get_pos(void)
284 {
285 return player.rb.co;
286 }
287
288 static void player_kill(void)
289 {
290 player.is_dead = 1;
291 player_ragdoll_copy_model( player.rb.v );
292 }
293
294 static float *player_cam_pos(void)
295 {
296 return player.camera_pos;
297 }
298
299
300 #endif /* PLAYER_H */