From 0ab4a30406f316673f13b3d0eeb1c9c36f1cc6bb Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 21 Aug 2019 07:33:24 +0200 Subject: [PATCH] product:: backwall optimization --- geometry.cpp | 1 + graph.cpp | 5 ++++- nonisotropic.cpp | 38 ++++++++++++++++++++++++++++++++++---- polygons.cpp | 1 + 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 609d23ff..d44de350 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -245,6 +245,7 @@ hpcshape shAnimatedGargoyle, shAnimatedGargoyle2, shAnimatedBat, shAnimatedBat2; vector shPlainWall3D, shWireframe3D, shWall3D, shMiniWall3D; + vector walltester; vector all_plain_floorshapes; vector all_escher_floorshapes; diff --git a/graph.cpp b/graph.cpp index 4b1e1f20..1eb5031c 100644 --- a/graph.cpp +++ b/graph.cpp @@ -4559,7 +4559,7 @@ void radar_grid(cell *c, const transmatrix& V) { } int wall_offset(cell *c) { - if(prod) return product::wall_offset(c); + if(prod) return product::cwall_offset; if(penrose && kite::getshape(c->master) == kite::pKite) return 10; return 0; } @@ -6048,6 +6048,9 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { case 6: case 7: if (pmodel == mdPerspective && V[2][LDIM] <= -l) continue; break; } } + else if(prod) { + if(!((product::cwall_mask >> a) & 1)) continue; + } if(qfi.fshape && wmescher) { auto& poly = queuepoly(V, cgi.shWall3D[ofs + a], darkena(wcol2 - d * get_darkval(c, a), 0, 0xFF)); #if CAP_TEXTURE diff --git a/nonisotropic.cpp b/nonisotropic.cpp index 36710982..95455537 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -625,12 +625,30 @@ EX namespace product { EX pair get_where(cell *c) { return ((hrmap_product*)currentmap)->where[c]; } + EX int cwall_offset, cwall_mask; + void drawcell_stack(cell *c, transmatrix V, int spinv, bool mirrored) { if(sphere) gmatrix[c] = V; /* some computations need gmatrix0 for underlying geometry */ + bool s = sphere; in_actual([&] { + cell *c0 = get_at(c, current_view_level); + cwall_offset = wall_offset(c0); + if(s) cwall_mask = (1<type) - 1; + else { + cwall_mask = 0; + ld d = V[2][2]; + for(int i=0; itype; i++) { + ld d1 = (V * cgi.walltester[cwall_offset + i])[2]; + if(c0->item == itGold) println(hlog, i, ": ", d, " vs ", d1); + if(d1 < d - 1e-6) cwall_mask |= (1<type); int flat_distance = hdist0(product_decompose(tC0(V)).second); int max_z = flat_distance > sightranges[gProduct] ? 0 : sqrt(sightranges[gProduct] * sightranges[gProduct] - flat_distance * flat_distance) + 1; for(int z=-max_z; z<=max_z; z++) { + if(z == 0) cwall_mask ^= (2<type); + if(z == 1) cwall_mask ^= (1<type); cell *c1 = get_at(c, current_view_level+z); setdist(c1, 7, NULL); drawcell(c1, V * mscale(Id, cgi.plevel * z), spinv, mirrored); @@ -667,10 +685,22 @@ EX namespace product { cell *c1 = get_where(c).first; wo = isize(cgi.shWall3D); int won = wo + c->type; - cgi.shWall3D.resize(won); - cgi.shPlainWall3D.resize(won); - cgi.shWireframe3D.resize(won); - cgi.shMiniWall3D.resize(won); + cgi.reserve_wall3d(won); + + for(int i=0; itype; i++) { + hyperpoint w; + in_underlying_geometry([&] { + /* mirror image of C0 in the axis h1-h2 */ + hyperpoint h1 = get_corner_position(c1, i); + hyperpoint h2 = get_corner_position(c1, i+1); + transmatrix T = gpushxto0(h1); + T = spintox(T * h2) * T; + w = T * C0; + w[1] = -w[1]; + w = inverse(T) * w; + }); + cgi.walltester[wo + i] = w; + } for(int i=0; itype; i++) cgi.make_wall(wo + i, {product::get_corner(c1, i, -1), product::get_corner(c1, i, +1), product::get_corner(c1, i+1, +1), product::get_corner(c1, i+1, -1)}); diff --git a/polygons.cpp b/polygons.cpp index cd70b8a0..9db2429d 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -794,6 +794,7 @@ void geometry_information::reserve_wall3d(int i) { shPlainWall3D.resize(i); shWireframe3D.resize(i); shMiniWall3D.resize(i); + walltester.resize(i); } void geometry_information::create_wall3d() {