From 2591c69b447e38d7d4f36311f04f043deee238e0 Mon Sep 17 00:00:00 2001 From: terminx <terminx@1a8010ca-5511-0410-912e-c29ae57300e0> Date: Sat, 6 Apr 2019 06:38:00 +0000 Subject: [PATCH] Add updatesectorbreadthz(), change pushmove() to use updatesectorbreadth(), and modify updatesectorbreadth() to include the early inside_p() return regular updatesector() has git-svn-id: https://svn.eduke32.com/eduke32@7482 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/src/clip.cpp | 2 +- source/build/src/engine.cpp | 82 +++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/source/build/src/clip.cpp b/source/build/src/clip.cpp index 587952b36..f6accc9b8 100644 --- a/source/build/src/clip.cpp +++ b/source/build/src/clip.cpp @@ -1435,7 +1435,7 @@ int32_t pushmove(vec3_t *vect, int16_t *sectnum, } while (clipinsidebox((vec2_t *)vect, i, walldist-4) != 0); bad = -1; k--; if (k <= 0) return bad; - updatesector(vect->x, vect->y, sectnum); + updatesectorbreadth(vect->x, vect->y, sectnum); if (*sectnum < 0) return -1; } else diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index ccdb00302..db6f127ec 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -11021,7 +11021,7 @@ void updatesector(int32_t const x, int32_t const y, int16_t * const sectnum) void updatesectorbreadth(int32_t const x, int32_t const y, int16_t * const sectnum) { - if ((unsigned)*sectnum >= (unsigned)numsectors) + if ((unsigned)*sectnum >= (unsigned)numsectors || inside_p(x, y, *sectnum)) return; static int16_t sectlist[MAXSECTORS]; @@ -11081,12 +11081,12 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * { if ((uint32_t)(*sectnum) < 2*MAXSECTORS) { - int32_t nofirstzcheck = 0; + bool nofirstzcheck = false; if (*sectnum >= MAXSECTORS) { *sectnum -= MAXSECTORS; - nofirstzcheck = 1; + nofirstzcheck = true; } // this block used to be outside the "if" and caused crashes in Polymost Mapster32 @@ -11130,9 +11130,85 @@ void updatesectorz(int32_t const x, int32_t const y, int32_t const z, int16_t * if (inside_z_p(x,y,z, i)) SET_AND_RETURN(*sectnum, i); + // fall back to regular old updatesector() because that's still better than returning -1 updatesector(x, y, sectnum); } +void updatesectorbreadthz(int32_t const x, int32_t const y, int32_t const z, int16_t * const sectnum) +{ + bool nofirstzcheck = false; + + if ((unsigned)*sectnum >= (unsigned)numsectors) + { + if ((unsigned)*sectnum < (unsigned)numsectors + MAXSECTORS) + { + *sectnum -= MAXSECTORS; + nofirstzcheck = true; + } + else + { + // we need to support passing in a sectnum of -1, unfortunately + for (int i = numsectors - 1; i >= 0; --i) + if (inside_z_p(x, y, z, i)) + SET_AND_RETURN(*sectnum, i); + + for (int i = numsectors - 1; i >= 0; --i) + if (inside_p(x, y, i)) + SET_AND_RETURN(*sectnum, i); + + SET_AND_RETURN(*sectnum, -1); + } + } + + int32_t cz, fz; + getzsofslope(*sectnum, x, y, &cz, &fz); + +#ifdef YAX_ENABLE + if (z < cz) + { + int const next = yax_getneighborsect(x, y, *sectnum, YAX_CEILING); + if (next >= 0 && z >= getceilzofslope(next, x, y)) + SET_AND_RETURN(*sectnum, next); + } + + if (z > fz) + { + int const next = yax_getneighborsect(x, y, *sectnum, YAX_FLOOR); + if (next >= 0 && z <= getflorzofslope(next, x, y)) + SET_AND_RETURN(*sectnum, next); + } +#endif + if (nofirstzcheck || (z >= cz && z <= fz)) + if (inside_p(x, y, *sectnum)) + return; + + static int16_t sectlist[MAXSECTORS]; + static uint8_t sectbitmap[MAXSECTORS>>3]; + int32_t nsecs; + + bfirst_search_init(sectlist, sectbitmap, &nsecs, numsectors, *sectnum); + + for (int sectcnt=0; sectcnt<nsecs; sectcnt++) + { + if (inside_z_p(x, y, z, sectlist[sectcnt])) + SET_AND_RETURN(*sectnum, sectlist[sectcnt]); + + auto const sec = §or[sectlist[sectcnt]]; + int const startwall = sec->wallptr; + int const endwall = sec->wallptr + sec->wallnum; + + for (int j=startwall; j<endwall; j++) + if (wall[j].nextsector >= 0) + bfirst_search_try(sectlist, sectbitmap, &nsecs, wall[j].nextsector); + } + + // fall back to searching without z... this is really a bullshit worst case scenario + for (int sectcnt=0; sectcnt<nsecs; sectcnt++) + if (inside_p(x, y, sectlist[sectcnt])) + SET_AND_RETURN(*sectnum, sectlist[sectcnt]); + + *sectnum = -1; +} // // rotatepoint