From 8bf0bb8e0d7e2d9bb22f78605333c57eb7b71669 Mon Sep 17 00:00:00 2001 From: Orange Date: Fri, 18 Apr 2025 13:56:08 +0300 Subject: [PATCH] improved line trace and box primitive --- include/omath/3d_primitives/box.hpp | 2 +- include/omath/collision/line_tracer.hpp | 2 +- source/3d_primitives/box.cpp | 53 ++++++++++++++++--------- source/collision/line_tracer.cpp | 7 +++- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/include/omath/3d_primitives/box.hpp b/include/omath/3d_primitives/box.hpp index d915ca2..0f18c40 100644 --- a/include/omath/3d_primitives/box.hpp +++ b/include/omath/3d_primitives/box.hpp @@ -11,7 +11,7 @@ namespace omath::primitives { [[nodiscard]] - std::array>, 8> CreateBox(const Vector3& top, const Vector3& bottom, + std::array>, 12> CreateBox(const Vector3& top, const Vector3& bottom, const Vector3& dirForward, const Vector3& dirRight, float ratio = 4.f); } diff --git a/include/omath/collision/line_tracer.hpp b/include/omath/collision/line_tracer.hpp index 8834136..cd7a87a 100644 --- a/include/omath/collision/line_tracer.hpp +++ b/include/omath/collision/line_tracer.hpp @@ -13,7 +13,7 @@ namespace omath::collision public: Vector3 start; Vector3 end; - + bool infinite_length = false; [[nodiscard]] Vector3 DirectionVector() const; diff --git a/source/3d_primitives/box.cpp b/source/3d_primitives/box.cpp index 202e47b..0e45eaa 100644 --- a/source/3d_primitives/box.cpp +++ b/source/3d_primitives/box.cpp @@ -4,36 +4,53 @@ #include "omath/3d_primitives/box.hpp" - namespace omath::primitives { - - std::array>, 8> CreateBox(const Vector3& top, const Vector3& bottom, - const Vector3& dirForward, - const Vector3& dirRight, - const float ratio) + std::array>, 12> CreateBox(const Vector3& top, const Vector3& bottom, + const Vector3& dirForward, + const Vector3& dirRight, + const float ratio) { const auto height = top.DistTo(bottom); const auto sideSize = height / ratio; - std::array, 8> points; + // corner layout (0‑3 bottom, 4‑7 top) + std::array, 8> p; + p[0] = bottom + (dirForward + dirRight) * sideSize; // front‑right‑bottom + p[1] = bottom + (dirForward - dirRight) * sideSize; // front‑left‑bottom + p[2] = bottom + (-dirForward + dirRight) * sideSize; // back‑right‑bottom + p[3] = bottom + (-dirForward - dirRight) * sideSize; // back‑left‑bottom + p[4] = top + (dirForward + dirRight) * sideSize; // front‑right‑top + p[5] = top + (dirForward - dirRight) * sideSize; // front‑left‑top + p[6] = top + (-dirForward + dirRight) * sideSize; // back‑right‑top + p[7] = top + (-dirForward - dirRight) * sideSize; // back‑left‑top - points[0] = bottom + (dirForward + dirRight) * sideSize; - points[1] = bottom + (dirForward - dirRight) * sideSize; + std::array>, 12> poly; - points[2] = bottom + (-dirForward + dirRight) * sideSize; - points[3] = bottom + (-dirForward - dirRight) * sideSize; + // bottom face (+Y up ⇒ wind CW when viewed from above) + poly[0] = {p[0], p[2], p[3]}; + poly[1] = {p[0], p[3], p[1]}; - points[4] = top + (dirForward + dirRight) * sideSize; - points[5] = top + (dirForward - dirRight) * sideSize; + // top face + poly[2] = {p[4], p[7], p[6]}; + poly[3] = {p[4], p[5], p[7]}; - points[6] = top + (-dirForward + dirRight) * sideSize; - points[7] = top + (-dirForward - dirRight) * sideSize; + // front face + poly[4] = {p[0], p[5], p[1]}; + poly[5] = {p[0], p[4], p[5]}; + // right face + poly[6] = {p[0], p[6], p[2]}; + poly[7] = {p[0], p[4], p[6]}; - std::array>, 8> polygons; + // back face + poly[8] = {p[2], p[7], p[3]}; + poly[9] = {p[2], p[6], p[7]}; - polygons[0] = {points[0], points[2], points[3]}; - return polygons; + // left face + poly[10] = {p[1], p[7], p[5]}; + poly[11] = {p[1], p[3], p[7]}; + + return poly; } } diff --git a/source/collision/line_tracer.cpp b/source/collision/line_tracer.cpp index 0dfc7f5..2d55956 100644 --- a/source/collision/line_tracer.cpp +++ b/source/collision/line_tracer.cpp @@ -54,7 +54,12 @@ namespace omath::collision const auto tHit = sideB.Dot(q) * invDet; - if (tHit <= kEpsilon) + if (ray.infinite_length) + { + if (tHit <= kEpsilon) + return ray.end; + } + else if (tHit < 0.0f || tHit > 1.0f) return ray.end; return ray.start + rayDir * tHit;