From ea86e5520b7fe4beda07d8dd3c79ce19bc0709f5 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 15 Dec 2018 01:40:31 +0000 Subject: [PATCH] Revert "engine.cpp/.h: clean up & fix lintersect(). Additionally, add support for finding intersections of collinear line segments." This reverts r6886. git-svn-id: https://svn.eduke32.com/eduke32@7290 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/include/build.h | 6 +- source/build/src/engine.cpp | 111 +++++++++++++++-------------------- 2 files changed, 48 insertions(+), 69 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 2cafc5c84..9d0b64860 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -1230,10 +1230,8 @@ int32_t sectorofwall_noquick(int16_t wallNum); int32_t loopnumofsector(int16_t sectnum, int16_t wallnum); void setslope(int32_t sectnum, int32_t cf, int16_t slope); -int32_t lintersect(int32_t originX, int32_t originY, int32_t originZ, - int32_t destX, int32_t destY, int32_t destZ, - int32_t lineStartX, int32_t lineStartY, int32_t lineEndX, int32_t lineEndY, - int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ); +int32_t lintersect(int32_t x1, int32_t y1, int32_t z1, int32_t x2, int32_t y2, int32_t z2, int32_t x3, + int32_t y3, int32_t x4, int32_t y4, int32_t *intx, int32_t *inty, int32_t *intz); int32_t rayintersect(int32_t x1, int32_t y1, int32_t z1, int32_t vx, int32_t vy, int32_t vz, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *intx, int32_t *inty, int32_t *intz); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 12cf6870a..d4e397f8a 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -7369,75 +7369,56 @@ int32_t changespritestat(int16_t spritenum, int16_t newstatnum) // // lintersect (internal) // -int32_t lintersect(const int32_t originX, const int32_t originY, const int32_t originZ, - const int32_t destX, const int32_t destY, const int32_t destZ, - const int32_t lineStartX, const int32_t lineStartY, const int32_t lineEndX, const int32_t lineEndY, - int32_t *intersectionX, int32_t *intersectionY, int32_t *intersectionZ) +int32_t lintersect(int32_t x1, int32_t y1, int32_t z1, + int32_t x2, int32_t y2, int32_t z2, + int32_t x3, int32_t y3, int32_t x4, int32_t y4, + int32_t *intx, int32_t *inty, int32_t *intz) { - const vec2_t ray = { destX-originX, - destY-originY }; - const vec2_t lineVec = { lineEndX-lineStartX, - lineEndY-lineStartY }; - const vec2_t originDiff = { lineStartX-originX, - lineStartY-originY }; + // p1 to p2 is a line segment + int32_t const x21 = x2 - x1; + int32_t const x34 = x3 - x4; + int32_t const y21 = y2 - y1; + int32_t const y34 = y3 - y4; + int32_t const bot = x21 * y34 - y21 * x34; + int32_t topt; - const int32_t rayCrossLineVec = ray.x*lineVec.y - ray.y*lineVec.x; - const int32_t originDiffCrossRay = originDiff.x*ray.y - originDiff.y*ray.x; - - if (rayCrossLineVec == 0) - { - if (originDiffCrossRay != 0) - { - // line segments are parallel - return 0; - } - - // line segments are collinear - const int32_t rayLengthSquared = ray.x*ray.x + ray.y*ray.y; - const int32_t rayDotOriginDiff = ray.x*originDiff.x + ray.y*originDiff.y; - const int32_t rayDotLineEndDiff = rayDotOriginDiff + ray.x*lineVec.x + ray.y*lineVec.y; - int32_t t = min(rayDotOriginDiff, rayDotLineEndDiff); - if (rayDotOriginDiff < 0) - { - if (rayDotLineEndDiff < 0) - return 0; - - t = 0; - } - else if (rayDotOriginDiff > rayLengthSquared) - { - if (rayDotLineEndDiff > rayLengthSquared) - return 0; - - t = rayDotLineEndDiff; - } - t = divscale24(t, rayLengthSquared); - *intersectionX = originX + mulscale24(ray.x, t); - *intersectionY = originY + mulscale24(ray.y, t); - *intersectionZ = originZ + mulscale24(destZ-originZ, t); - - return 1; - } - - const int32_t originDiffCrossLineVec = originDiff.x*lineVec.y - originDiff.y*lineVec.x; - static const int32_t signBit = 1u<<31u; - // t is < 0 if (originDiffCrossLineVec^rayCrossLineVec) & signBit) - // t is > 1 if originDiffCrossLineVec > rayCrossLineVec - // u is < 0 if (originDiffCrossRay^rayCrossLineVec) & signBit - // u is > 1 if originDiffCrossRay > rayCrossLineVec - // where int32_t u = divscale24(originDiffCrossRay, rayCrossLineVec); - if (originDiffCrossLineVec > rayCrossLineVec || - originDiffCrossRay > rayCrossLineVec || - ((originDiffCrossLineVec^rayCrossLineVec) & signBit) || - ((originDiffCrossRay^rayCrossLineVec) & signBit)) - { - // line segments do not overlap + if (bot == 0) return 0; + else if (bot > 0) + { + int32_t x31 = x3 - x1; + int32_t y31 = y3 - y1; + + topt = x31 * y34 - y31 * x34; + + if ((unsigned)topt >= (unsigned)bot) + return 0; + + int32_t topu = x21 * y31 - y21 * x31; + + if ((unsigned)topu >= (unsigned)bot) + return 0; } - int32_t t = divscale24(originDiffCrossLineVec, rayCrossLineVec); - *intersectionX = originX + mulscale24(ray.x, t); - *intersectionY = originY + mulscale24(ray.y, t); - *intersectionZ = originZ + mulscale24(destZ-originZ, t); + else + { + int32_t x31 = x3 - x1; + int32_t y31 = y3 - y1; + + topt = x31 * y34 - y31 * x34; + + if ((unsigned)topt <= (unsigned)bot) + return 0; + + int32_t topu = x21 * y31 - y21 * x31; + + if ((unsigned)topu <= (unsigned)bot) + return 0; + } + + int32_t t = divscale24(topt, bot); + *intx = x1 + mulscale24(x21, t); + *inty = y1 + mulscale24(y21, t); + *intz = z1 + mulscale24(z2 - z1, t); return 1; }