From ff33a19b85f7f741c24ec6993903e29f423b55fa Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Wed, 6 Nov 2024 21:37:07 +0100 Subject: [PATCH] Recast: move triangle intersection code to shared Light cleanup and reusability. --- src/naveditor/InputGeom.cpp | 52 ++----------------- .../recast/Shared/Include/SharedCommon.h | 3 ++ .../recast/Shared/Source/SharedCommon.cpp | 44 ++++++++++++++++ 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/naveditor/InputGeom.cpp b/src/naveditor/InputGeom.cpp index 8ba67f1d..e69e9e02 100644 --- a/src/naveditor/InputGeom.cpp +++ b/src/naveditor/InputGeom.cpp @@ -27,50 +27,6 @@ #include "NavEditor/Include/Editor.h" #include -// note(amos): based on the Möller–Trumbore algorithm, see: -// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm -static inline bool intersectSegmentTriangle(const float* sp, const float* sq, - const float* a, const float* b, const float* c, float& t) -{ - float ab[3], ac[3], qp[3]; - rdVsub(ab, b, a); - rdVsub(ac, c, a); - rdVsub(qp, sq, sp); - - float h[3]; - rdVcross(h, qp, ac); - - const float d = rdVdot(ab, h); - - if (d > -RD_EPS && d < RD_EPS) - return false; // Ray is parallel to the triangle plane - - float s[3]; - rdVsub(s, sp, a); - - const float id = 1.0f/d; - const float u = rdVdot(s, h)*id; - - if (u < 0.0f || u > 1.0f) - return false; - - float q[3]; - rdVcross(q, s, ab); - - const float v = rdVdot(qp, q)*id; - - if (v < 0.0f || u+v > 1.0f) - return false; - - t = rdVdot(ac, q)*id; - - if (t < 0.0f || t > 1.0f) - return false; - - // Segment/ray intersects triangle - return true; -} - static char* parseRow(char* buf, char* bufEnd, char* row, int len) { bool start = true; @@ -598,10 +554,10 @@ bool InputGeom::raycastMesh(const float* src, const float* dst, const unsigned i for (int j = 0; j < ntris*3; j += 3) { float t = 1; - if (intersectSegmentTriangle(src, dst, - &verts[tris[j]*3], - &verts[tris[j+1]*3], - &verts[tris[j+2]*3], t)) + if (rdIntersectSegmentTriangle(src, dst, + &verts[tris[j]*3], + &verts[tris[j+1]*3], + &verts[tris[j+2]*3], t)) { // Caller isn't interested in finding the closest intersection; return out. if (!tmin) diff --git a/src/thirdparty/recast/Shared/Include/SharedCommon.h b/src/thirdparty/recast/Shared/Include/SharedCommon.h index 0f5316c6..9dff27e9 100644 --- a/src/thirdparty/recast/Shared/Include/SharedCommon.h +++ b/src/thirdparty/recast/Shared/Include/SharedCommon.h @@ -473,6 +473,9 @@ void rdClosestPtPointTriangle(float* closest, const float* p, /// @param[out] h The resulting height. bool rdClosestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h); +bool rdIntersectSegmentTriangle(const float* sp, const float* sq, + const float* a, const float* b, const float* c, float& t); + bool rdIntersectSegmentPoly2D(const float* p0, const float* p1, const float* verts, int nverts, float& tmin, float& tmax, diff --git a/src/thirdparty/recast/Shared/Source/SharedCommon.cpp b/src/thirdparty/recast/Shared/Source/SharedCommon.cpp index f2fed543..d98f7057 100644 --- a/src/thirdparty/recast/Shared/Source/SharedCommon.cpp +++ b/src/thirdparty/recast/Shared/Source/SharedCommon.cpp @@ -120,6 +120,50 @@ void rdClosestPtPointTriangle(float* closest, const float* p, closest[2] = a[2] + ab[2] * v + ac[2] * w; } +// note(amos): based on the Möller–Trumbore algorithm, see: +// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm +bool rdIntersectSegmentTriangle(const float* sp, const float* sq, + const float* a, const float* b, const float* c, float& t) +{ + float ab[3], ac[3], qp[3]; + rdVsub(ab, b, a); + rdVsub(ac, c, a); + rdVsub(qp, sq, sp); + + float h[3]; + rdVcross(h, qp, ac); + + const float d = rdVdot(ab, h); + + if (d > -RD_EPS && d < RD_EPS) + return false; // Ray is parallel to the triangle plane + + float s[3]; + rdVsub(s, sp, a); + + const float id = 1.0f / d; + const float u = rdVdot(s, h) * id; + + if (u < 0.0f || u > 1.0f) + return false; + + float q[3]; + rdVcross(q, s, ab); + + const float v = rdVdot(qp, q) * id; + + if (v < 0.0f || u+v > 1.0f) + return false; + + t = rdVdot(ac, q)*id; + + if (t < 0.0f || t > 1.0f) + return false; + + // Segment/ray intersects triangle + return true; +} + bool rdIntersectSegmentPoly2D(const float* p0, const float* p1, const float* verts, int nverts, float& tmin, float& tmax,