fix regression with gate flipping
[carveJwlIkooP6JGAAIwe30JlM.git] / physics_test.h
1 /*
2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
3 */
4
5 #ifndef PHYSICS_TEST_H
6 #define PHYSICS_TEST_H
7
8 #include "rigidbody.h"
9 #include "player.h"
10
11 rigidbody ground = { .type = k_rb_shape_box,
12 .bbx = {{-100.0f,-1.0f,-100.0f},{100.0f,0.0f,100.0f}},
13 .co = {0.0f, 0.0f, 0.0f},
14 .q = {0.0f,0.0f,0.0f,1.0f},
15 .is_world = 1 };
16
17 rigidbody blocky =
18 {
19 .type = k_rb_shape_box,
20 .bbx = {{-2.0f,-1.0f,-3.0f},{2.0f,1.0f,2.0f}},
21 .co = {30.0f,2.0f,30.0f},
22 .q = {0.0f,0.0f,0.0f,1.0f},
23 .is_world = 1
24 };
25
26 rigidbody marko =
27 {
28 .type = k_rb_shape_box,
29 .bbx = {{-0.5f,-0.5f,-0.5f},{0.5f,0.5f,0.5f}},
30 .co = {-36.0f,8.0f,-36.0f},
31 .q = {0.0f,0.0f,0.0f,1.0f},
32 .is_world = 0
33 };
34
35 scene epic_scene;
36
37 rigidbody epic_scene_rb =
38 {
39 .type = k_rb_shape_scene,
40 .co = {0.0f,0.0f,0.0f},
41 .q = {0.0f,0.0f,0.0f,1.0f},
42 .is_world = 1,
43 .inf.scene = { .pscene = &epic_scene }
44 };
45
46 rigidbody funnel[4] = {
47 {
48 .type = k_rb_shape_box,
49 .bbx = {{-20.0f,-1.0f,-20.0f},{20.0f,1.0f,20.0f}},
50 .co = {-10.0f,5.0f,0.0f},
51 .is_world = 1
52 },
53 {
54 .type = k_rb_shape_box,
55 .bbx = {{-20.0f,-1.0f,-20.0f},{20.0f,1.0f,20.0f}},
56 .co = { 10.0f,5.0f,0.0f},
57 .is_world = 1
58 },
59 {
60 .type = k_rb_shape_box,
61 .bbx = {{-20.0f,-1.0f,-20.0f},{20.0f,1.0f,20.0f}},
62 .co = { 0.0f,5.0f,10.0f},
63 .is_world = 1
64 },
65 {
66 .type = k_rb_shape_box,
67 .bbx = {{-20.0f,-1.0f,-20.0f},{20.0f,1.0f,20.0f}},
68 .co = {0.0f,5.0f,-10.0f},
69 .is_world = 1
70 }
71 };
72
73 rigidbody jeff1 = { .type = k_rb_shape_capsule,
74 .inf.capsule = { .radius = 0.75f, .height = 3.0f },
75 .co = {30.0f, 4.0f, 30.0f },
76 .q = {1.0f,0.0f,0.0f,0.0f}
77 };
78
79 rigidbody ball = { .type = k_rb_shape_sphere,
80 .inf.sphere = { .radius = 2.0f },
81 .co = {0.0f,20.0f,2.0f},
82 .q = {0.0f,0.0f,0.0f,1.0f}},
83
84 ball1= { .type = k_rb_shape_sphere,
85 .inf.sphere = { .radius = 2.0f },
86 .co = {0.1f,25.0f,0.2f},
87 .q = {0.0f,0.0f,0.0f,1.0f}};
88
89 rigidbody jeffs[16];
90
91 static void reorg_jeffs(void)
92 {
93 for( int i=0; i<vg_list_size(jeffs); i++ )
94 {
95 v3_copy( (v3f){ (vg_randf()-0.5f) * 10.0f,
96 (vg_randf()-0.5f) * 10.0f + 17.0f,
97 (vg_randf()-0.5f) * 10.0f }, jeffs[i].co );
98 v4_copy( (v4f){ vg_randf(), vg_randf(), vg_randf(), vg_randf() },
99 jeffs[i].q );
100 q_normalize( jeffs[i].q );
101
102 jeffs[i].type = k_rb_shape_capsule;
103 jeffs[i].inf.capsule.radius = 0.75f;
104 jeffs[i].inf.capsule.height = 3.0f;
105
106 rb_init( &jeffs[i] );
107 }
108 }
109
110 static void physics_test_start(void)
111 {
112 q_axis_angle( funnel[0].q, (v3f){1.0f,0.0f,0.0f}, 0.6f );
113 q_axis_angle( funnel[1].q, (v3f){1.0f,0.0f,0.0f}, -0.6f );
114 q_axis_angle( funnel[2].q, (v3f){0.0f,0.0f,1.0f}, 0.6f );
115 q_axis_angle( funnel[3].q, (v3f){0.0f,0.0f,1.0f}, -0.6f );
116
117 for( int i=0; i<4; i++ )
118 rb_init( &funnel[i] );
119
120 reorg_jeffs();
121
122 rb_init( &ground );
123 rb_init( &ball );
124 rb_init( &ball1 );
125 rb_init( &jeff1 );
126 rb_init( &blocky );
127
128 scene_init( &epic_scene );
129
130 mdl_header *mdl = mdl_load( "models/epic_scene.mdl" );
131
132 m4x3f transform;
133 m4x3_identity( transform );
134
135 for( int i=0; i<mdl->node_count; i++ )
136 {
137 mdl_node *pnode = mdl_node_from_id( mdl, i );
138
139 for( int j=0; j<pnode->submesh_count; j++ )
140 {
141 mdl_submesh *sm = mdl_node_submesh( mdl, pnode, j );
142 scene_add_submesh( &epic_scene, mdl, sm, transform );
143 }
144 }
145
146 vg_free( mdl );
147 scene_bh_create( &epic_scene );
148
149 rb_init( &epic_scene_rb );
150 rb_init( &marko );
151 }
152
153 static void physics_test_update(void)
154 {
155 player_freecam();
156 player_camera_update();
157
158 for( int i=0; i<4; i++ )
159 rb_debug( &funnel[i], 0xff0060e0 );
160 rb_debug( &ground, 0xff00ff00 );
161 rb_debug( &ball, 0xffe00040 );
162 rb_debug( &ball1, 0xff00e050 );
163
164 rb_debug( &blocky, 0xffcccccc );
165 rb_debug( &jeff1, 0xff00ffff );
166
167 rb_debug( &epic_scene_rb, 0xffcccccc );
168 rb_debug( &marko, 0xffffcc00 );
169
170 {
171
172 rb_solver_reset();
173
174 for( int i=0; i<4; i++ )
175 {
176 rigidbody *fn = &funnel[i];
177 rb_collide( &ball, fn );
178 rb_collide( &ball1, fn );
179 rb_collide( &jeff1, fn );
180
181 for( int i=0; i<vg_list_size(jeffs); i++ )
182 rb_collide( jeffs+i, fn );
183 }
184
185 for( int i=0; i<vg_list_size(jeffs)-1; i++ )
186 {
187 for( int j=i+1; j<vg_list_size(jeffs); j++ )
188 {
189 rb_collide( jeffs+i, jeffs+j );
190 }
191 }
192
193 for( int i=0; i<vg_list_size(jeffs); i++ )
194 {
195 rb_collide( jeffs+i, &ground );
196 rb_collide( jeffs+i, &ball );
197 rb_collide( jeffs+i, &ball1 );
198 rb_collide( jeffs+i, &jeff1 );
199 }
200
201 rb_collide( &jeff1, &ground );
202 rb_collide( &jeff1, &blocky );
203 rb_collide( &jeff1, &ball );
204 rb_collide( &jeff1, &ball1 );
205
206 rb_collide( &ball, &ground );
207 rb_collide( &ball1, &ground );
208 rb_collide( &ball1, &ball );
209 rb_collide( &marko, &epic_scene_rb );
210
211 rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
212 for( int i=0; i<8; i++ )
213 rb_solve_contacts( rb_contact_buffer, rb_contact_count );
214
215
216 /* ITERATE */
217 {
218 for( int i=0; i<vg_list_size(jeffs); i++ )
219 {
220 rb_debug( &jeffs[i], (u32[]){ 0xff0000ff, 0xff00ff00, 0xff00ffff,
221 0xffff0000, 0xffff00ff, 0xffffff00,
222 }[i%6] );
223 rb_iter( jeffs+i );
224 }
225
226 rb_iter( &ball );
227 rb_iter( &ball1 );
228 rb_iter( &jeff1 );
229 rb_iter( &marko );
230 }
231
232 /* POSITION OVERRIDE */
233 {
234 if(glfwGetKey( vg.window, GLFW_KEY_L ))
235 {
236 m4x3_mulv( player.camera, (v3f){0.0f,0.0f,-5.0f}, marko.co );
237 v3_zero( marko.v );
238 v3_zero( marko.w );
239 }
240 if(glfwGetKey( vg.window, GLFW_KEY_K ))
241 {
242 m4x3_mulv( player.camera, (v3f){0.0f,0.0f,-5.0f}, ball.co );
243 v3_zero( ball.v );
244 v3_zero( ball.w );
245 }
246 if(glfwGetKey( vg.window, GLFW_KEY_J ))
247 {
248 m4x3_mulv( player.camera, (v3f){0.0f,0.0f,-5.0f}, ball1.co );
249 v3_zero( ball1.v );
250 v3_zero( ball1.w );
251 }
252
253 if(glfwGetKey( vg.window, GLFW_KEY_H ))
254 {
255 reorg_jeffs();
256 }
257 }
258
259 /* UPDATE TRANSFORMS */
260 for( int i=0; i<vg_list_size(jeffs); i++ )
261 {
262 rb_update_transform(jeffs+i);
263 }
264
265 rb_update_transform( &ball );
266 rb_update_transform( &ball1 );
267 rb_update_transform( &jeff1 );
268 rb_update_transform( &marko );
269
270 }
271 }
272
273 static void physics_test_render(void)
274 {
275 m4x4f world_4x4;
276 m4x3_expand( player.camera_inverse, world_4x4 );
277
278 gpipeline.fov = 60.0f;
279 m4x4_projection( vg_pv, gpipeline.fov,
280 (float)vg_window_x / (float)vg_window_y,
281 0.1f, 2100.0f );
282
283 m4x4_mul( vg_pv, world_4x4, vg_pv );
284 glEnable( GL_DEPTH_TEST );
285
286 glDisable( GL_DEPTH_TEST );
287 vg_lines_drawall( (float *)vg_pv );
288 }
289
290 #endif /* PHYSICS_TEST_H */