From 9a319e2d2a61f13398c86dea145436b452e1a5ba Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 9 Jul 2021 10:09:31 +0200 Subject: [PATCH] refactored shvid_full and wall_offset as virtual functions --- archimedean.cpp | 4 +++ bigstuff.cpp | 1 + cell.cpp | 3 ++ celldrawer.cpp | 4 +-- goldberg.cpp | 5 +++ graph.cpp | 69 ++++++++++++++++++++++++++++++++++------ kite.cpp | 7 +++++ models.cpp | 2 +- nonisotropic.cpp | 82 ------------------------------------------------ pattern2.cpp | 6 ++-- raycaster.cpp | 13 ++++---- reg3.cpp | 11 ++++--- 12 files changed, 98 insertions(+), 109 deletions(-) diff --git a/archimedean.cpp b/archimedean.cpp index 19d50778..0ca7bf27 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -774,6 +774,10 @@ struct hrmap_archimedean : hrmap { return id; } + int full_shvid(cell *c) override { + return id_of(c->master) + 20 * parent_index_of(c->master); + } + hyperpoint get_corner(cell *c, int cid, ld cf) override { auto &ac = arcm::current_or_fake(); if(PURE) { diff --git a/bigstuff.cpp b/bigstuff.cpp index 12c52d85..e5347126 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -1485,6 +1485,7 @@ EX bool good_for_wall(cell *c) { } EX bool walls_not_implemented() { + if(WDIM == 3 && !PURE) return true; if(sphere || quotient || nonisotropic || (kite::in() && !bt::in()) || experimental) return true; return WDIM == 3 && (cgflags & qIDEAL); } diff --git a/cell.cpp b/cell.cpp index 3d75883f..fd9361d2 100644 --- a/cell.cpp +++ b/cell.cpp @@ -64,7 +64,10 @@ struct hrmap { virtual void find_cell_connection(cell *c, int d); virtual int shvid(cell *c) { return 0; } + virtual int full_shvid(cell *c) { return shvid(c); } virtual hyperpoint get_corner(cell *c, int cid, ld cf=3) { return C0; } + + virtual int wall_offset(cell *c); }; /** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient diff --git a/celldrawer.cpp b/celldrawer.cpp index adb058a4..10300ddb 100644 --- a/celldrawer.cpp +++ b/celldrawer.cpp @@ -857,7 +857,7 @@ void celldrawer::draw_grid() { if(0); #if MAXMDIM == 4 else if(WDIM == 3) { - int ofs = wall_offset(c); + int ofs = currentmap->wall_offset(c); for(int t=0; ttype; t++) { if(!c->move(t)) continue; if(bt::in() && !sn::in() && !among(t, 5, 6, 8)) continue; @@ -1666,7 +1666,7 @@ void celldrawer::draw_features() { void celldrawer::draw_features_and_walls_3d() { #if MAXMDIM >= 4 color_t dummy; - int ofs = wall_offset(c); + int ofs = currentmap->wall_offset(c); if(isWall3(c, wcol)) { if(!no_wall_rendering) { color_t wcol2 = wcol; diff --git a/goldberg.cpp b/goldberg.cpp index ada1d8f6..7b75d2c4 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -1283,6 +1283,11 @@ EX namespace gp { return gp::get_plainshape_id(c); } + int full_shvid(cell *c) override { + gp::draw_li = gp::get_local_info(c); + return shvid(c); + } + hyperpoint get_corner(cell *c, int cid, ld cf) override { if(UNTRUNCATED) { cell *c1 = gp::get_mapped(c); diff --git a/graph.cpp b/graph.cpp index 0c2104f7..638aa960 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3963,14 +3963,64 @@ EX void gridline(const shiftmatrix& V, const hyperpoint h1, const hyperpoint h2, gridline(V, h1, V, h2, col, prec); } -EX int wall_offset(cell *c) { - if(hybri || WDIM == 2) return hybrid::wall_offset(c); - #if CAP_BT - if(kite::in() && kite::getshape(c->master) == kite::pKite) return 10; - #endif - if(reg3::in() && !PURE) - return reg3::get_wall_offset(c); - return 0; +int hrmap::wall_offset(cell *c) { + int id = currentmap->full_shvid(c); + + if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, {-1, nullptr}); + auto &wop = cgi.walloffsets[id]; + int &wo = wop.first; + if(!wop.second) wop.second = c; + if(wo == -1) { + cell *c1 = hybri ? hybrid::get_where(c).first : c; + wo = isize(cgi.shWall3D); + int won = wo + c->type + (WDIM == 2 ? 2 : 0); + if(!cgi.wallstart.empty()) cgi.wallstart.pop_back(); + cgi.reserve_wall3d(won); + + if(prod || WDIM == 2) for(int i=0; itype; i++) { + hyperpoint w; + auto f = [&] { + /* 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 = iso_inverse(T) * w; + }; + if(prod) PIU(f()); + else f(); + cgi.walltester[wo + i] = w; + } + + for(int i=0; itype; i++) + cgi.make_wall(wo + i, {hybrid::get_corner(c1, i, 0, -1), hybrid::get_corner(c1, i, 0, +1), hybrid::get_corner(c1, i, 1, +1), hybrid::get_corner(c1, i, 1, -1)}); + + for(int a: {0,1}) { + vector l; + int z = a ? 1 : -1; + hyperpoint ctr = zpush0(z * cgi.plevel/2); + for(int i=0; itype; i++) + if(prod || WDIM == 2) + l.push_back(hybrid::get_corner(c1, i, 0, z)); + else { + l.push_back(ctr); + l.push_back(hybrid::get_corner(c1, i, 0, z)); + l.push_back(hybrid::get_corner(c1, i+1, 1, z)); + l.push_back(ctr); + l.push_back(hybrid::get_corner(c1, i, 1, z)); + l.push_back(hybrid::get_corner(c1, i, 0, z)); + } + if(a == 0) std::reverse(l.begin()+1, l.end()); + cgi.make_wall(won-2+a, l); + } + + cgi.wallstart.push_back(isize(cgi.raywall)); + cgi.compute_cornerbonus(); + cgi.extra_vertices(); + } + return wo; } EX void queue_transparent_wall(const shiftmatrix& V, hpcshape& sh, color_t color) { @@ -4253,8 +4303,7 @@ void celldrawer::draw_fallanims() { EX void queuecircleat1(cell *c, const shiftmatrix& V, double rad, color_t col) { if(WDIM == 3) { dynamicval p(poly_outline, col); - // we must do hybrid::wall_offset in hybrid because the cached value is likely incorrect - int ofs = hybri ? hybrid::wall_offset(c) : wall_offset(c); + int ofs = currentmap->wall_offset(c); for(int i=0; itype; i++) { queuepolyat(V, cgi.shWireframe3D[ofs + i], 0, PPR::SUPERLINE); } diff --git a/kite.cpp b/kite.cpp index b6d16fe2..0f3dc6da 100644 --- a/kite.cpp +++ b/kite.cpp @@ -338,6 +338,13 @@ struct hrmap_kite : hrmap { } return gm * where; } + + virtual int wall_offset(cell *c) { + if(WDIM == 3) + return kite::getshape(c->master) == kite::pKite ? 10 : 0; + else + return hrmap::wall_offset(c); + } hrmap_kite() { make_graphrules(); diff --git a/models.cpp b/models.cpp index 126e3a42..b86a11ca 100644 --- a/models.cpp +++ b/models.cpp @@ -173,7 +173,7 @@ EX namespace models { spiral_multiplier = cld(cos_spiral, sin_spiral) * cld(spiral_cone_rad * mul / 2., 0); } if(euclid) { - euclidean_spin = pispin * iso_inverse(cview().T * master_relative(centerover, true)); + euclidean_spin = pispin * iso_inverse(cview().T * currentmap->master_relative(centerover, true)); euclidean_spin = gpushxto0(euclidean_spin * C0) * euclidean_spin; hyperpoint h = inverse(euclidean_spin) * (C0 + (euc::eumove(gp::loc{1,0})*C0 - C0) * vpconf.spiral_x + (euc::eumove(gp::loc{0,1})*C0 - C0) * vpconf.spiral_y); spiral_multiplier = cld(0, 2 * M_PI) / cld(h[0], h[1]); diff --git a/nonisotropic.cpp b/nonisotropic.cpp index b56248f1..75d4b6d7 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -1355,88 +1355,6 @@ EX namespace hybrid { } } - EX int wall_offset(cell *c) { - if(GOLDBERG || INVERSE) { - /* a bit slow... */ - cell *c1 = WDIM == 2 ? c : get_where(c).first; - gp::draw_li = WDIM == 2 ? gp::get_local_info(c1) : PIU(gp::get_local_info(c1)); - } - auto ugeometry = hybri ? hybrid::underlying : geometry; - - int id; - - #if CAP_ARCM - if(ugeometry == gArchimedean) - id = arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master); - else - #endif - if(ugeometry == gArbitrary) - id = arb::id_of(c->master); - else - if(PURE && !kite::in() && !bt::in()) - id = 0; - else - id = shvid(c); - - if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, {-1, nullptr}); - auto &wop = cgi.walloffsets[id]; - int &wo = wop.first; - if(!wop.second) wop.second = c; - if(wo == -1) { - cell *c1 = hybri ? hybrid::get_where(c).first : c; - wo = isize(cgi.shWall3D); - int won = wo + c->type + (WDIM == 2 ? 2 : 0); - if(!cgi.wallstart.empty()) cgi.wallstart.pop_back(); - cgi.reserve_wall3d(won); - - if(prod || WDIM == 2) for(int i=0; itype; i++) { - hyperpoint w; - auto f = [&] { - /* 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 = iso_inverse(T) * w; - }; - if(prod) - ((hrmap_hybrid*)currentmap)->in_underlying(f); - else - f(); - cgi.walltester[wo + i] = w; - } - - for(int i=0; itype; i++) - cgi.make_wall(wo + i, {hybrid::get_corner(c1, i, 0, -1), hybrid::get_corner(c1, i, 0, +1), hybrid::get_corner(c1, i, 1, +1), hybrid::get_corner(c1, i, 1, -1)}); - - for(int a: {0,1}) { - vector l; - int z = a ? 1 : -1; - hyperpoint ctr = zpush0(z * cgi.plevel/2); - for(int i=0; itype; i++) - if(prod || WDIM == 2) - l.push_back(hybrid::get_corner(c1, i, 0, z)); - else { - l.push_back(ctr); - l.push_back(hybrid::get_corner(c1, i, 0, z)); - l.push_back(hybrid::get_corner(c1, i+1, 1, z)); - l.push_back(ctr); - l.push_back(hybrid::get_corner(c1, i, 1, z)); - l.push_back(hybrid::get_corner(c1, i, 0, z)); - } - if(a == 0) std::reverse(l.begin()+1, l.end()); - cgi.make_wall(won-2+a, l); - } - - cgi.wallstart.push_back(isize(cgi.raywall)); - cgi.compute_cornerbonus(); - cgi.extra_vertices(); - } - return wo; - } - auto clear_samples = addHook(hooks_clearmemory, 40, [] () { for(auto& c: cgis) for(auto& v: c.second.walloffsets) v.second = nullptr; diff --git a/pattern2.cpp b/pattern2.cpp index 06ebdeba..177d5131 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -2698,7 +2698,7 @@ EX namespace linepatterns { if(S3 >= OINF) gridlinef(V, C0, V, mid(C0, tC0(currentmap->adj(c, dir))), col, 2 + vid.linequality); else - gridlinef(V, C0, V * master_relative(c, true) * currentmap->adj(c->master, dir), C0, col, 2 + vid.linequality); + gridlinef(V, C0, V * currentmap->master_relative(c, true) * currentmap->adj(c->master, dir), C0, col, 2 + vid.linequality); } } ) @@ -2716,7 +2716,7 @@ EX namespace linepatterns { gridlinef(V, C0, V, mid(C0, tC0(inverse_shift(V, gmatrix[c2]))), col, 2 + vid.linequality); } else - gridlinef(V, C0, V*master_relative(c, true) * currentmap->adj(c->master,i), C0, col, 2 + vid.linequality); + gridlinef(V, C0, V*currentmap->master_relative(c, true) * currentmap->adj(c->master,i), C0, col, 2 + vid.linequality); } } } @@ -2777,7 +2777,7 @@ EX namespace linepatterns { linepattern patIrregularMaster("irregular master", 0x8438A400, [] { return IRREGULAR; }, ALLCELLS( if(c->master->c7 != c) if(gmatrix.count(c->master->c7)) - gridlinef(V, C0, V*master_relative(c, true), C0, + gridlinef(V, C0, V*currentmap->master_relative(c, true), C0, darkena(backcolor ^ 0xFFFFFF, 0, col), 2 + vid.linequality); ) diff --git a/raycaster.cpp b/raycaster.cpp index b9e30e47..cfe920f0 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -312,7 +312,7 @@ void enable_raycaster() { return "uWallstart[" + s + "]"; }; - wall_offset(centerover); /* so raywall is not empty and deg is not zero */ + currentmap->wall_offset(centerover); /* so raywall is not empty and deg is not zero */ deg = 0; @@ -1691,7 +1691,7 @@ struct raycast_map { } } - int wo = wall_offset(c); + int wo = currentmap->wall_offset(c); if(wo >= irays) { println(hlog, "wo=", wo, " irays = ", irays); reset_raycaster(); @@ -1706,11 +1706,12 @@ struct raycast_map { connections[u][2] = (k+.5) / 1024.; break; } - if(wall_offset(c1) >= max_wall_offset) - println(hlog, "error: wall_offset exceeds ", max_wall_offset); + auto wo1 = currentmap->wall_offset(c1); + if(wo1 >= max_wall_offset) + println(hlog, "error: wall_offset ", wo1, " exceeds ", max_wall_offset); if(c1->type >= max_celltype) println(hlog, "error: type " + its(c1->type) + " exceeds ", max_celltype); - connections[u][3] = (wall_offset(c1) * 1. / max_wall_offset) + (c1->type + (WDIM == 2 ? 2 : 0) + .5) * 1. / max_wall_offset / max_celltype; + connections[u][3] = (wo1 * 1. / max_wall_offset) + (c1->type + (WDIM == 2 ? 2 : 0) + .5) * 1. / max_wall_offset / max_celltype; } if(WDIM == 2) for(int a: {0, 1}) { celldrawer dd; @@ -1907,7 +1908,7 @@ EX void cast() { } if(o->uWallOffset != -1) { - glUniform1i(o->uWallOffset, wall_offset(cs)); + glUniform1i(o->uWallOffset, currentmap->wall_offset(cs)); glUniform1i(o->uSides, cs->type + (WDIM == 2 ? 2 : 0)); } diff --git a/reg3.cpp b/reg3.cpp index 3e7e0a89..59f178bb 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -659,22 +659,23 @@ EX namespace reg3 { } void make_subconnections(); + + int wall_offset(cell *c) override; + int shvid(cell *c) { return local_id[c].second; } }; struct hrmap_quotient3 : hrmap_closed3 { }; #endif - EX int get_wall_offset(cell *c) { - auto m = (hrmap_closed3*) currentmap; - auto& wo = cgi.walloffsets[ m->local_id[c].second ]; + int hrmap_closed3::wall_offset(cell *c) { + auto& wo = cgi.walloffsets[ local_id[c].second ]; if(wo.second == nullptr) wo.second = c; return wo.first; } EX const vector& get_face_vertices(cell *c, int d) { - auto m = (hrmap_closed3*) currentmap; - return cgi.subshapes[m->local_id[c].second].faces_local[d]; + return cgi.subshapes[currentmap->shvid(c)].faces_local[d]; } EX int get_face_vertex_count(cell *c, int d) {