From 0467c945b54aebe52136dfdea0ee9feb4bc281cb Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Wed, 9 Aug 2023 12:22:33 +0900 Subject: [PATCH] Refactor duplicate code into function --- src/3d_helpers.cc | 27 +++++++++++++++++++++ src/3d_helpers.h | 5 ++++ src/screen_trunner.cc | 56 +++++++------------------------------------ 3 files changed, 40 insertions(+), 48 deletions(-) diff --git a/src/3d_helpers.cc b/src/3d_helpers.cc index ec4f3ea..a8e37b0 100644 --- a/src/3d_helpers.cc +++ b/src/3d_helpers.cc @@ -160,3 +160,30 @@ std::optional ray_to_plane(const Ray &ray, const Ray &plane) { ray.position.y + ray.direction.y * amount, ray.position.z + ray.direction.z * amount}; } + +std::optional ray_collision_triangle(const Ray &ray, const Vector3 &a, + const Vector3 &b, + const Vector3 &c) { + const Vector3 ab = Vector3Subtract(a, b); + const Vector3 cb = Vector3Subtract(c, b); + Vector3 ortho = Vector3CrossProduct(ab, cb); + ortho = Vector3Normalize(ortho); + + Ray plane{.position = b, .direction = ortho}; + + auto result = ray_to_plane(ray, plane); + if (!result.has_value()) { + return std::nullopt; + } + + Vector3 bary = Vector3Barycenter(result.value(), a, b, c); + if (bary.x >= 0.0F && bary.x <= 1.0F && bary.y >= 0.0F && bary.y <= 1.0F && + bary.z >= 0.0F && bary.z <= 1.0F) { + float sum = bary.x + bary.y + bary.z; + if (sum > 0.999F && sum < 1.001) { + return result; + } + } + + return std::nullopt; +} diff --git a/src/3d_helpers.h b/src/3d_helpers.h index 88b0021..ff90a31 100644 --- a/src/3d_helpers.h +++ b/src/3d_helpers.h @@ -27,6 +27,11 @@ extern bool ray_to_xz_plane(const Ray &ray, float &x_out, float &z_out); /// plane.direction is plane normal, plane.position is position on plane. extern std::optional ray_to_plane(const Ray &ray, const Ray &plane); +extern std::optional ray_collision_triangle(const Ray &ray, + const Vector3 &a, + const Vector3 &b, + const Vector3 &c); + // Unimplemented as this function isn't really needed and it exposes some // weirdness regarding column-major matrices. // extern Vector4 operator*(const Matrix &m, const Vector4 &v); diff --git a/src/screen_trunner.cc b/src/screen_trunner.cc index d62e933..45e9c9c 100644 --- a/src/screen_trunner.cc +++ b/src/screen_trunner.cc @@ -205,58 +205,18 @@ bool TRunnerScreen::update(float dt) { Vector3 sw{xf - 0.5F, current.sw, zf + 0.5F}; Vector3 se{xf + 0.5F, current.se, zf + 0.5F}; - { - Vector3 a = Vector3Subtract(nw, sw); - Vector3 b = Vector3Subtract(ne, sw); - Vector3 ortho = Vector3CrossProduct(a, b); - ortho = Vector3Normalize(ortho); - - Ray plane{.position = sw, .direction = ortho}; - - auto result = ray_to_plane(ray, plane); - if (!result.has_value()) { - continue; - } - - Vector3 bary = Vector3Barycenter(result.value(), nw, sw, ne); - if (bary.x >= 0.0F && bary.x <= 1.0F && bary.y >= 0.0F && - bary.y <= 1.0F && bary.z >= 0.0F && bary.z <= 1.0F) { - float sum = bary.x + bary.y + bary.z; - if (sum > 0.999F && sum < 1.001) { - idx_hit = idx; + if (ray_collision_triangle(ray, nw, sw, ne).has_value()) { + idx_hit = idx; #ifndef NDEBUG - std::cout << "first: idx_hit set to " << idx_hit << std::endl; + std::cout << "first: idx_hit set to " << idx_hit << std::endl; #endif - break; - } - } - } - - { - Vector3 a = Vector3Subtract(se, sw); - Vector3 b = Vector3Subtract(ne, sw); - Vector3 ortho = Vector3CrossProduct(a, b); - ortho = Vector3Normalize(ortho); - - Ray plane{.position = sw, .direction = ortho}; - - auto result = ray_to_plane(ray, plane); - if (!result.has_value()) { - continue; - } - - Vector3 bary = Vector3Barycenter(result.value(), se, sw, ne); - if (bary.x >= 0.0F && bary.x <= 1.0F && bary.y >= 0.0F && - bary.y <= 1.0F && bary.z >= 0.0F && bary.z <= 1.0F) { - float sum = bary.x + bary.y + bary.z; - if (sum > 0.999F && sum < 1.001) { - idx_hit = idx; + break; + } else if (ray_collision_triangle(ray, ne, sw, se).has_value()) { + idx_hit = idx; #ifndef NDEBUG - std::cout << "second: idx_hit set to " << idx_hit << std::endl; + std::cout << "second: idx_hit set to " << idx_hit << std::endl; #endif - break; - } - } + break; } }