From 7f73388943754468f06e90c51d96531215568dd8 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Wed, 9 Aug 2023 13:54:56 +0900 Subject: [PATCH] Refactorings Use bounding boxes for collision checks, and only check collision against triangles when bounding box collides. Use const where applicable. --- src/screen_trunner.cc | 53 +++++++++++++++++++++++++++++++++++-------- src/screen_trunner.h | 1 + 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/screen_trunner.cc b/src/screen_trunner.cc index 2876648..cb18b8f 100644 --- a/src/screen_trunner.cc +++ b/src/screen_trunner.cc @@ -159,6 +159,38 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr stack) } 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 @@ -226,14 +258,17 @@ bool TRunnerScreen::update(float dt) { } }; - if (auto collision = ray_collision_triangle(ray, nw, sw, ne); - collision.has_value()) { - on_collide_fn(collision); - break; - } else if (auto collision = ray_collision_triangle(ray, ne, sw, se); - collision.has_value()) { - on_collide_fn(collision); - break; + if (auto bb_collision = GetRayCollisionBox(ray, surface_bbs[idx]); + bb_collision.hit) { + if (auto collision = ray_collision_triangle(ray, nw, sw, ne); + collision.has_value()) { + on_collide_fn(collision); + break; + } else if (auto collision = ray_collision_triangle(ray, ne, sw, se); + collision.has_value()) { + on_collide_fn(collision); + break; + } } } } @@ -260,7 +295,7 @@ bool TRunnerScreen::draw() { ? RAYWHITE : Color{(unsigned char)(200 + ox * 2), (unsigned char)(150 + oy * 2), 20, 255}; - auto ¤t = surface[idx].value(); + const auto ¤t = surface[idx].value(); DrawTriangle3D(Vector3{xf - 0.5F, current.nw, zf - 0.5F}, Vector3{xf - 0.5F, current.sw, zf + 0.5F}, Vector3{xf + 0.5F, current.ne, zf - 0.5F}, color); diff --git a/src/screen_trunner.h b/src/screen_trunner.h index dd2db2b..10621b3 100644 --- a/src/screen_trunner.h +++ b/src/screen_trunner.h @@ -56,6 +56,7 @@ class TRunnerScreen : public Screen { std::array, SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT> surface; + std::array surface_bbs; Camera3D camera; std::bitset<64> flags; Model TEMP_cube_model;