From 6cf779870b5c9370af3ad9335d932589ed9bc238 Mon Sep 17 00:00:00 2001 From: Alex Foster <123afoster@gmail.com> Date: Wed, 19 Feb 2025 21:54:16 -0800 Subject: [PATCH] replace INITRAYCUBE macro with struct --- src/engine/world/raycube.cpp | 129 +++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 53 deletions(-) diff --git a/src/engine/world/raycube.cpp b/src/engine/world/raycube.cpp index dda1cfa9..220d4db4 100644 --- a/src/engine/world/raycube.cpp +++ b/src/engine/world/raycube.cpp @@ -357,19 +357,19 @@ bool cubeworld::upoctree(const vec& v, int& x, int& y, int& z, const ivec& lo, i //======================================================= DOWNOCTREE INITRAYCUBE #define DOWNOCTREE(disttoent, earlyexit) \ - cube *lc = levels[lshift]; \ + cube *lc = r.levels[r.lshift]; \ for(;;) \ { \ - lshift--; \ - lc += OCTA_STEP(x, y, z, lshift); \ - if(lc->ext && lc->ext->ents && lshift < elvl) \ + r.lshift--; \ + lc += OCTA_STEP(x, y, z, r.lshift); \ + if(lc->ext && lc->ext->ents && r.lshift < r.elvl) \ { \ - float edist = disttoent(lc->ext->ents, o, ray, dent, mode, t); \ - if(edist < dent) \ + float edist = disttoent(lc->ext->ents, o, ray, r.dent, mode, t); \ + if(edist < r.dent) \ { \ - earlyexit return std::min(edist, dist); \ - elvl = lshift; \ - dent = std::min(dent, edist); \ + earlyexit return std::min(edist, r.dist); \ + r.elvl = r.lshift; \ + r.dent = std::min(r.dent, edist); \ } \ } \ if(lc->children==nullptr) \ @@ -377,7 +377,7 @@ bool cubeworld::upoctree(const vec& v, int& x, int& y, int& z, const ivec& lo, i break; \ } \ lc = &(*lc->children)[0]; \ - levels[lshift] = lc; \ + r.levels[r.lshift] = lc; \ } //NOTE: levels[20] magically assumes mapscale <20 @@ -392,77 +392,101 @@ bool cubeworld::upoctree(const vec& v, int& x, int& y, int& z, const ivec& lo, i elvl = mode&Ray_BB ? worldscale : 0; \ ivec lsizemask(invray.x>0 ? 1 : 0, invray.y>0 ? 1 : 0, invray.z>0 ? 1 : 0); +struct raycubeinfo +{ + float dist, + dent; + vec v, + invray; + cube *levels[20]; + int lshift, + elvl; + ivec lsizemask; + + raycubeinfo(float radius, const vec &o, const vec &ray, int worldscale, int mode, cube *r) + { + dist = 0; + dent = radius > 0 ? radius : 1e16f; + v = o; + invray = vec(ray.x ? 1/ray.x : 1e16f, ray.y ? 1/ray.y : 1e16f, ray.z ? 1/ray.z : 1e16f); + levels[worldscale] = r; + lshift = worldscale; + elvl = mode&Ray_BB ? worldscale : 0; + lsizemask = ivec(invray.x>0 ? 1 : 0, invray.y>0 ? 1 : 0, invray.z>0 ? 1 : 0); + } +}; + float cubeworld::raycube(const vec &o, const vec &ray, float radius, int mode, int size, const extentity *t) const { if(ray.iszero()) { return 0; } - INITRAYCUBE; + raycubeinfo r(radius, o, ray, worldscale, mode, &(*worldroot)[0]); //scope limiting brackets { float outrad = 0.f; - if(checkinsideworld(invray, radius, outrad, o, v, ray, dist)) + if(checkinsideworld(r.invray, radius, outrad, o, r.v, ray, r.dist)) { return outrad; } } int closest = -1, - x = static_cast(v.x), - y = static_cast(v.y), - z = static_cast(v.z); + x = static_cast(r.v.x), + y = static_cast(r.v.y), + z = static_cast(r.v.z); for(;;) { DOWNOCTREE(disttoent, if(mode&Ray_Shadow)); - int lsize = 1<0 || !(mode&Ray_SkipFirst)) && + if((r.dist>0 || !(mode&Ray_SkipFirst)) && (((mode&Ray_ClipMat) && IS_CLIPPED(c.material&MatFlag_Volume)) || ((mode&Ray_EditMat) && c.material != Mat_Air) || (!(mode&Ray_Pass) && lsize==size && !(c.isempty())) || c.issolid() || - dent < dist) && + r.dent < r.dist) && (!(mode&Ray_ClipMat) || (c.material&MatFlag_Clip)!=Mat_NoClip)) { - if(dist < dent) + if(r.dist < r.dent) { if(closest < 0) { - float dx = ((x&(~0U<0 ? 0 : 1<0 ? 0 : 1<0 ? 0 : 1<0 ? 0 : 1<0 ? 0 : 1<0 ? 0 : 1< dy ? (dx > dz ? 0 : 2) : (dy > dz ? 1 : 2); } hitsurface = vec(0, 0, 0); hitsurface[closest] = ray[closest]>0 ? -1 : 1; - return dist; + return r.dist; } - return dent; + return r.dent; } - ivec lo(x&(~0U<0 || !(mode&Ray_SkipFirst)) && (!(mode&Ray_ClipMat) || (c.material&MatFlag_Clip)!=Mat_NoClip)) + if(raycubeintersect(p, r.v, ray, r.invray, r.dent-r.dist, f) && (r.dist+f>0 || !(mode&Ray_SkipFirst)) && (!(mode&Ray_ClipMat) || (c.material&MatFlag_Clip)!=Mat_NoClip)) { - return std::min(dent, dist+f); + return std::min(r.dent, r.dist+f); } } - findclosest(closest, 0, 1, 2, lsizemask, invray, lo, lshift, v, dist, ray); - if(radius>0 && dist>=radius) + findclosest(closest, 0, 1, 2, r.lsizemask, r.invray, lo, r.lshift, r.v, r.dist, ray); + if(radius>0 && r.dist>=radius) { - return std::min(dent, dist); + return std::min(r.dent, r.dist); } - if(upoctree(v, x, y, z, lo, lshift)) + if(upoctree(r.v, x, y, z, lo, r.lshift)) { - return std::min(dent, radius>0 ? radius : dist); + return std::min(r.dent, radius>0 ? radius : r.dist); } } } @@ -470,69 +494,68 @@ float cubeworld::raycube(const vec &o, const vec &ray, float radius, int mode, i // optimized version for light shadowing... every cycle here counts!!! float cubeworld::shadowray(const vec &o, const vec &ray, float radius, int mode, const extentity *t) { - INITRAYCUBE; + raycubeinfo r(radius, o, ray, worldscale, mode, &(*worldroot)[0]); //scope limiting brackets { float outrad = 0.f; - if(checkinsideworld(invray, radius, outrad, o, v, ray, dist)) + if(checkinsideworld(r.invray, radius, outrad, o, r.v, ray, r.dist)) { return outrad; } } int side = Orient_Bottom, - x = static_cast(v.x), - y = static_cast(v.y), - z = static_cast(v.z); + x = static_cast(r.v.x), + y = static_cast(r.v.y), + z = static_cast(r.v.z); for(;;) { DOWNOCTREE(shadowent, ); const cube &c = *lc; - ivec lo(x&(~0U<= 0) { - return c.texture[side]==Default_Sky && mode&Ray_SkipSky ? radius : dist+std::max(enterdist+0.1f, 0.0f); + return c.texture[side]==Default_Sky && mode&Ray_SkipSky ? radius : r.dist+std::max(enterdist+0.1f, 0.0f); } } nextcube: - findclosest(side, Orient_Right - lsizemask.x, Orient_Front - lsizemask.y, Orient_Top - lsizemask.z, lsizemask, invray, lo, lshift, v, dist, ray); - if(dist>=radius) + findclosest(side, Orient_Right - r.lsizemask.x, Orient_Front - r.lsizemask.y, Orient_Top - r.lsizemask.z, r.lsizemask, r.invray, lo, r.lshift, r.v, r.dist, ray); + if(r.dist>=radius) { - return dist; + return r.dist; } - if(upoctree(v, x, y, z, lo, lshift)) + if(upoctree(r.v, x, y, z, lo, r.lshift)) { return radius; } } } -#undef INITRAYCUBE #undef DOWNOCTREE //============================================================================== float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent)