LPR - Walking
[carveJwlIkooP6JGAAIwe30JlM.git] / player_physics.h
1 /*
2 * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
3 */
4
5 #define PLAYER_PHYSICS_H
6 #ifndef PLAYER_PHYSICS_H
7 #define PLAYER_PHYSICS_H
8
9 #include "player.h"
10 #include "camera.h"
11
12 VG_STATIC void player_integrate(void);
13
14 VG_STATIC int player_collide_sphere( rigidbody *rb, rb_ct *manifold )
15 {
16 int len = 0;
17
18 len = rb_sphere_scene( rb, &world.rb_geo, manifold );
19 rb_manifold_filter_coplanar( manifold, len, 0.05f );
20 if( len > 1 )
21 {
22 rb_manifold_filter_backface( manifold, len );
23 rb_manifold_filter_joint_edges( manifold, len, 0.05f );
24 rb_manifold_filter_pairs( manifold, len, 0.05f );
25 }
26 int new_len = rb_manifold_apply_filtered( manifold, len );
27 if( len && !new_len )
28 len = 1;
29 else
30 len = new_len;
31
32 return len;
33 }
34
35 #if 0
36 VG_STATIC void apply_gravity( v3f vel, float const timestep )
37 {
38 v3f gravity = { 0.0f, -9.6f, 0.0f };
39 v3_muladds( vel, gravity, timestep, vel );
40 }
41
42 VG_STATIC void player_integrate(void)
43 {
44 struct player_phys *phys = &player.phys;
45 v3_sub( phys->rb.v, phys->v_last, phys->a );
46 v3_muls( phys->a, 1.0f/VG_TIMESTEP_FIXED, phys->a );
47 v3_copy( phys->rb.v, phys->v_last );
48
49 apply_gravity( phys->rb.v, VG_TIMESTEP_FIXED );
50 v3_muladds( phys->rb.co, phys->rb.v, VG_TIMESTEP_FIXED, phys->rb.co );
51 }
52 #endif
53
54 VG_STATIC void player_freecam(void)
55 {
56 player_mouseview();
57
58 float movespeed = fc_speed * VG_TIMESTEP_FIXED;
59 v3f lookdir = { 0.0f, 0.0f, -1.0f },
60 sidedir = { 1.0f, 0.0f, 0.0f };
61
62 m3x3_mulv( main_camera.transform, lookdir, lookdir );
63 m3x3_mulv( main_camera.transform, sidedir, sidedir );
64
65 static v3f move_vel = { 0.0f, 0.0f, 0.0f };
66
67 v2f steer = { player.input_js1h->axis.value,
68 player.input_js1v->axis.value };
69
70 v3_muladds( move_vel, sidedir, movespeed*steer[0], move_vel );
71 v3_muladds( move_vel, lookdir, -movespeed*steer[1], move_vel );
72
73 v3_muls( move_vel, 0.7f, move_vel );
74 v3_add( move_vel, player.camera_pos, player.camera_pos );
75 }
76
77 VG_STATIC int kill_player( int argc, char const *argv[] )
78 {
79 player_kill();
80 return 0;
81 }
82
83 VG_STATIC int reset_player( int argc, char const *argv[] )
84 {
85 struct respawn_point *rp = NULL, *r;
86
87 if( argc == 1 )
88 {
89 for( int i=0; i<world.spawn_count; i++ )
90 {
91 r = &world.spawns[i];
92 if( !strcmp( r->name, argv[0] ) )
93 {
94 rp = r;
95 break;
96 }
97 }
98
99 if( !rp )
100 vg_warn( "No spawn named '%s'\n", argv[0] );
101 }
102
103 if( !rp )
104 {
105 float min_dist = INFINITY;
106
107 for( int i=0; i<world.spawn_count; i++ )
108 {
109 r = &world.spawns[i];
110 float d = v3_dist2( r->co, player.co );
111
112 vg_info( "Dist %s : %f\n", r->name, d );
113 if( d < min_dist )
114 {
115 min_dist = d;
116 rp = r;
117 }
118 }
119 }
120
121 if( !rp )
122 {
123 vg_error( "No spawn found\n" );
124 vg_info( "Player position: %f %f %f\n", player.co[0],
125 player.co[1],
126 player.co[2] );
127
128 if( !world.spawn_count )
129 return 0;
130
131 rp = &world.spawns[0];
132 }
133
134 player.is_dead = 0;
135
136 m3x3f the_long_way;
137 q_m3x3( rp->q, the_long_way );
138
139 v3f delta = {1.0f,0.0f,0.0f};
140 m3x3_mulv( the_long_way, delta, delta );
141
142 if( !freecam )
143 {
144 player.angles[0] = atan2f( delta[0], -delta[2] );
145 player.angles[1] = -asinf( delta[1] );
146 }
147
148 player.controller = k_player_controller_walk;
149 /* TODO: trigger controller slurp */
150
151 player_save_frame();
152 return 1;
153 }
154
155 VG_STATIC void reset_player_poll( int argc, char const *argv[] )
156 {
157 if( argc == 1 )
158 {
159 for( int i=0; i<world.spawn_count; i++ )
160 {
161 struct respawn_point *r = &world.spawns[i];
162 console_suggest_score_text( r->name, argv[argc-1], 0 );
163 }
164 }
165 }
166
167 #endif /* PLAYER_PHYSICS_H */