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