4 static aabb3f64 move_box(aabb3f32 box, v3f64 pos)
7 {pos.x + box.min.x, pos.y + box.min.y, pos.z + box.min.z},
8 {pos.x + box.max.x, pos.y + box.max.y, pos.z + box.max.z},
12 static aabb3s32 round_box(aabb3f64 box)
15 {floor(box.min.x + 0.5), floor(box.min.y + 0.5), floor(box.min.z + 0.5)},
16 { ceil(box.max.x - 0.5), ceil(box.max.y - 0.5), ceil(box.max.z - 0.5)},
20 static bool is_solid(Terrain *terrain, s32 x, s32 y, s32 z)
22 NodeType node = terrain_get_node(terrain, (v3s32) {x, y, z}).type;
23 return node == NODE_UNLOADED || node_def[node].solid;
26 bool physics_ground(Terrain *terrain, bool collide, aabb3f32 box, v3f64 *pos, v3f64 *vel)
34 aabb3f64 mbox = move_box(box, *pos);
37 aabb3s32 rbox = round_box(mbox);
39 if (mbox.min.y - (f64) rbox.min.y > 0.01)
42 for (s32 x = rbox.min.x; x <= rbox.max.x; x++)
43 for (s32 z = rbox.min.z; z <= rbox.max.z; z++)
44 if (is_solid(terrain, x, rbox.min.y, z))
50 bool physics_step(Terrain *terrain, bool collide, aabb3f32 box, v3f64 *pos, v3f64 *vel, v3f64 *acc, f64 t)
58 f32 *min = &box.min.x;
59 f32 *max = &box.max.x;
61 static u8 idx[3][3] = {
67 for (u8 i = 0; i < 3; i++) {
70 f64 v_cur = (v[i] + v_old) / 2.0;
79 aabb3s32 box_rnd = round_box(move_box(box, *pos));
83 s32 *min_rnd = &box_rnd.min.x;
84 s32 *max_rnd = &box_rnd.max.x;
90 min_rnd[i] = ceil(x_old + off + 0.5);
91 max_rnd[i] = floor(x[i] + off + 0.5);
96 min_rnd[i] = floor(x_old + off - 0.5);
97 max_rnd[i] = ceil(x[i] + off - 0.5);
102 u8 i_a = idx[i][0]; // = i
106 for (s32 a = min_rnd[i_a]; a != max_rnd[i_a]; a += dir)
107 for (s32 b = min_rnd[i_b]; b <= max_rnd[i_b]; b++)
108 for (s32 c = min_rnd[i_c]; c <= max_rnd[i_c]; c++) {
114 if (is_solid(terrain, p[0], p[1], p[2])) {
115 x[i] = (f64) a - off - 0.5 * (f64) dir;
124 return !v3f64_equals(*pos, old_pos);