Refactorings

Use bounding boxes for collision checks, and only check collision
against triangles when bounding box collides.

Use const where applicable.
This commit is contained in:
Stephen Seo 2023-08-09 13:54:56 +09:00
parent cab92d140b
commit 7f73388943
2 changed files with 45 additions and 9 deletions

View file

@ -159,6 +159,38 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
} }
surface.at(idx) = current; surface.at(idx) = current;
// Calculate bounding boxes.
int x = idx % SURFACE_UNIT_WIDTH;
int y = idx / SURFACE_UNIT_WIDTH;
float xf = (float)(x)-SURFACE_X_OFFSET;
float zf = (float)(y)-SURFACE_Y_OFFSET;
surface_bbs.at(idx).min.x = xf - 0.5F;
surface_bbs.at(idx).min.z = zf - 0.5F;
surface_bbs.at(idx).max.x = xf + 0.5F;
surface_bbs.at(idx).max.z = zf + 0.5F;
surface_bbs.at(idx).min.y = current.nw;
if (current.ne < surface_bbs.at(idx).min.y) {
surface_bbs.at(idx).min.y = current.ne;
}
if (current.sw < surface_bbs.at(idx).min.y) {
surface_bbs.at(idx).min.y = current.sw;
}
if (current.se < surface_bbs.at(idx).min.y) {
surface_bbs.at(idx).min.y = current.se;
}
surface_bbs.at(idx).max.y = current.nw;
if (current.ne > surface_bbs.at(idx).max.y) {
surface_bbs.at(idx).max.y = current.ne;
}
if (current.sw > surface_bbs.at(idx).max.y) {
surface_bbs.at(idx).max.y = current.sw;
}
if (current.se > surface_bbs.at(idx).max.y) {
surface_bbs.at(idx).max.y = current.se;
}
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -226,14 +258,17 @@ bool TRunnerScreen::update(float dt) {
} }
}; };
if (auto collision = ray_collision_triangle(ray, nw, sw, ne); if (auto bb_collision = GetRayCollisionBox(ray, surface_bbs[idx]);
collision.has_value()) { bb_collision.hit) {
on_collide_fn(collision); if (auto collision = ray_collision_triangle(ray, nw, sw, ne);
break; collision.has_value()) {
} else if (auto collision = ray_collision_triangle(ray, ne, sw, se); on_collide_fn(collision);
collision.has_value()) { break;
on_collide_fn(collision); } else if (auto collision = ray_collision_triangle(ray, ne, sw, se);
break; collision.has_value()) {
on_collide_fn(collision);
break;
}
} }
} }
} }
@ -260,7 +295,7 @@ bool TRunnerScreen::draw() {
? RAYWHITE ? RAYWHITE
: Color{(unsigned char)(200 + ox * 2), : Color{(unsigned char)(200 + ox * 2),
(unsigned char)(150 + oy * 2), 20, 255}; (unsigned char)(150 + oy * 2), 20, 255};
auto &current = surface[idx].value(); const auto &current = surface[idx].value();
DrawTriangle3D(Vector3{xf - 0.5F, current.nw, zf - 0.5F}, DrawTriangle3D(Vector3{xf - 0.5F, current.nw, zf - 0.5F},
Vector3{xf - 0.5F, current.sw, zf + 0.5F}, Vector3{xf - 0.5F, current.sw, zf + 0.5F},
Vector3{xf + 0.5F, current.ne, zf - 0.5F}, color); Vector3{xf + 0.5F, current.ne, zf - 0.5F}, color);

View file

@ -56,6 +56,7 @@ class TRunnerScreen : public Screen {
std::array<std::optional<SurfaceUnit>, std::array<std::optional<SurfaceUnit>,
SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT> SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT>
surface; surface;
std::array<BoundingBox, SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT> surface_bbs;
Camera3D camera; Camera3D camera;
std::bitset<64> flags; std::bitset<64> flags;
Model TEMP_cube_model; Model TEMP_cube_model;