struct plain_floorshape; struct escher_floorshape; vector all_plain_floorshapes; vector all_escher_floorshapes; struct floorshape { bool is_plain; int shapeid, prio; vector b, shadow, side[SIDEPARS], gpside[SIDEPARS][8]; floorshape() { prio = PPR_FLOOR; } }; struct plain_floorshape : floorshape { ld rad0, rad1; plain_floorshape() { is_plain = true; all_plain_floorshapes.push_back(this); } void configure(ld r0, ld r1) { rad0 = r0; rad1 = r1; } }; // noftype: 0 (shapeid2 is heptagonal or just use shapeid1), 1 (shapeid2 is pure heptagonal), 2 (shapeid2 is Euclidean), 3 (shapeid2 is hexagonal) struct escher_floorshape : floorshape { int shapeid0, shapeid1, noftype, shapeid2; ld scale; escher_floorshape(int s0, int s1, int noft=0, int s2=0) : shapeid0(s0), shapeid1(s1), noftype(noft), shapeid2(s2) { all_escher_floorshapes.push_back(this); scale = 1; is_plain = false; } }; plain_floorshape shFloor, shMFloor, shMFloor2, shMFloor3, shMFloor4, shFullFloor, shBigTriangle, shTriheptaFloor, shBigHepta; escher_floorshape shStarFloor(1,2), shCloudFloor(3, 4), shCrossFloor(5, 6, 2, 54), shChargedFloor(7, 385, 1, 10), shSStarFloor(11, 12), shOverFloor(13, 15, 1, 14), shTriFloor(17, 18, 0, 385), shFeatherFloor(19, 21, 1, 20), shBarrowFloor(23, 24, 1, 25), shNewFloor(26, 27, 2, 54), shTrollFloor(28, 29), shButterflyFloor(325, 326, 1, 178), shLavaFloor(359, 360, 1, 178), shSeabed(334, 335), shCloudSeabed(336, 337), shCaveSeabed(338, 339, 2, 54), shPalaceFloor(45, 46, 0, 385), shDemonFloor(51, 50, 1, 178), shCaveFloor(52, 53, 2, 54), shDesertFloor(55, 56, 0, 4), shPowerFloor(57, 58, 0, 12), /* dragon */ shRoseFloor(174, 175, 1, 173), shSwitchFloor(377, 378, 1, 379), shTurtleFloor(176, 177, 1, 178), shRedRockFloor[3] = {{55, 56}, {55, 56}, {55, 56}}, // 1 - .1 * i shDragonFloor(181, 182, 2, 183); /* dragon */ hyperpoint adist(ld a, ld x) { return spin(a) * xpush(x) * C0; } typedef pair> matrixitem; struct mesher { eGeometry g; int sym; ld bspi; hyperpoint lcorner, rcorner, mfar[2], vfar[4]; }; mesher msh(eGeometry g, int sym, ld main, ld v0, ld v1, ld bspi, ld scale) { main *= scale; v0 *= scale; v1 *= scale; mesher m; m.sym = sym; m.bspi = bspi; dynamicval dg(geometry, g); hyperpoint rot = xpush(v0) * spin(M_PI - M_PI/sym) * xpush(main) * C0; hyperpoint bnlfar = xpush(v0) * spin(M_PI) * rspintox(rot) * rspintox(rot) * rspintox(rot) * xpush(hdist0(rot)) * C0; hyperpoint bnrfar = xpush(v0) * spin(M_PI) * spintox(rot) * spintox(rot) * spintox(rot) * xpush(hdist0(rot)) * C0; m.lcorner = adist (bspi-M_PI/sym, main); m.rcorner = adist (bspi+M_PI/sym, main); m.mfar[0] = adist (bspi, v0); m.mfar[1] = adist (bspi, v1); m.vfar[0] = spin(bspi) * bnlfar; m.vfar[2] = spin(bspi) * bnrfar; m.vfar[1] = spin(-2*M_PI/sym) * m.vfar[2]; m.vfar[3] = spin(+2*M_PI/sym) * m.vfar[0]; return m; } struct matrixlist { mesher o, n; vector v; }; matrixitem genitem(const transmatrix& m1, const transmatrix& m2, int nsym) { matrixitem mi; mi.first = m1; for(int i=0; i lst; for(int i=0; i dg(geometry, gNormal); lst.push_back(hpxy(polydata[whereis+2*i], polydata[whereis+2*i+1])); } if(sym == 2) for(int i=qty-1; i>=0; i--) { dynamicval dg(geometry, gNormal); lst.push_back(hpxy(polydata[whereis+2*i], -polydata[whereis+2*i+1])); } hyperpoint lstmid = hpxyz(0,0,0); using namespace hyperpoint_vec; for(auto p: lst) lstmid += p; transmatrix T = spin(-m.o.bspi); while((spin(2*M_PI / rots) * T* lstmid)[0] < (T*lstmid)[0]) T = spin(2*M_PI / rots) * T; while((spin(-2*M_PI / rots) * T* lstmid)[0] < (T*lstmid)[0]) T = spin(-2*M_PI / rots) * T; T = spin(m.o.bspi) * T; for(auto &p: lst) p = T * p; if(osym % rots && rots % osym) printf("warning: rotation oddity (shapeid %d, osym=%d rots=%d)\n", shapeid, osym, rots); if(rots > osym && rots % osym == 0) { int rep = rots / osym; int s = lst.size(); for(int i=0; i -1e-5 && z[1] > -1e-5 && z[2] > -1e-5) { nh = m.second[r] * z, mapped++; } } if(mapped == 0) printf("warning: not mapped (shapeid %d)\n", shapeid); hpcpush(mid(nh, nh)); } } hpcpush(hpc[last->s]); } void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) { bshape(fsh.b[id], fsh.prio); for(int t=0; t<=sides; t++) hpcpush(ddi(t*S84 / sides + shift, size) * C0); bshape(fsh.shadow[id], fsh.prio); for(int t=0; t<=sides; t++) hpcpush(ddi(t*S84 / sides + shift, size * SHADMUL) * C0); for(int k=0; k usedml; void build_plainshape(int& id, gp::local_info& li, cell *c0, int siid, int sidir) { if(!just_matrices) id = nextid++; bool master = !(li.relative.first||li.relative.second); int cor = master ? S7 : 6; if(master) li.last_dir = -1; if(debug_geometry) printf("last=%d at=%d,%d tot=%d siid=%d sidir=%d cor=%d id=%d\n", li.last_dir, li.relative.first, li.relative.second, li.total_dir, siid, sidir, cor, id); for(auto pfsh: all_escher_floorshapes) { auto& fsh = *pfsh; generate_matrices_scale(1, fsh.noftype); auto& m = (siid && geosupport_graveyard() == 2) ? hex_matrices : hept_matrices; m.n.sym = cor; int i = 0; /* if(siid == 0) for(auto& ma: m.v) ma.first = ma.first * pispin; */ for(int d=0; d cornerlist; if(&fsh == &shTriheptaFloor) { if(!siid) { for(int i=0; i>2; // if(siid == 2) si.dir++; // if(siid != pattern_threecolor(c)) printf("threecolor mismatch\n"); // if(pattern_threecolor(createMov(c, fixdir(si.dir, c))) != (siid+1)%3) printf("threecolor mismatch direction\n"); sidir = fixdir(si.dir, c); } else if(geosupport_graveyard() == 2) { siid = !pseudohept(c); sidir = !ishex1(c); } else { siid = 0; sidir = 0; } auto& id = pshid[siid][sidir][draw_li.relative.first&31][draw_li.relative.second&31][fix6(draw_li.total_dir)]; if(id == -1 || just_matrices) build_plainshape(id, draw_li, c, siid, sidir); return id; } } qfloorinfo qfi; qfloorinfo qfi_dc; int chasmg; void set_no_floor() { qfi.fshape = NULL; qfi.shape = NULL; } void set_floor(floorshape& sh) { qfi.fshape = &sh; qfi.shape = NULL; } void set_floor(hpcshape& sh) { qfi.shape = &sh; qfi.fshape = NULL; qfi.spin = Id; } void set_floor(const transmatrix& spin, hpcshape& sh) { qfi.shape = &sh; qfi.fshape = NULL; qfi.spin = spin; } void draw_shapevec(cell *c, const transmatrix& V, const vector &shv, int col, int prio = -1) { if(gp::on) { int id = gp::get_plainshape_id(c); queuepolyat(V, shv[id], col, prio); } else if((euclid || gp::on) && ishex1(c)) queuepolyat(V * pispin, shv[0], col, prio); else if(!(S7&1) && nonbitrunc) { auto si = patterns::getpatterninfo(c, patterns::PAT_COLORING, 0); if(si.id == 8) si.dir++; transmatrix D = applyPatterndir(c, si); queuepolyat(V*D, shv[pseudohept(c)], col, prio); } else if(geosupport_threecolor() == 2) queuepolyat(V, shv[pseudohept(c)], col, prio); else queuepolyat(V, shv[ctof(c)], col, prio); } void draw_floorshape(cell *c, const transmatrix& V, const floorshape &fsh, int col, int prio = -1) { draw_shapevec(c, V, fsh.b, col, prio); } void draw_qfi(cell *c, const transmatrix& V, int col, int prio = -1, vector floorshape::* tab = &floorshape::b) { if(qfi.shape) queuepolyat(V * qfi.spin, *qfi.shape, col, prio); else if(!qfi.fshape) ; #if CAP_TEXTURE else if(qfi.tinf) { queuetable(V * qfi.spin, qfi.tinf->vertices, size(qfi.tinf->vertices), texture::config.mesh_color, texture::config.recolor(col), prio == -1 ? PPR_FLOOR : prio); lastptd().u.poly.tinf = qfi.tinf; if(gp::on) lastptd().u.poly.flags = POLY_INVERSE; } #endif else draw_shapevec(c, V, (qfi.fshape->*tab), col, prio); } void viewmat() { /* int id = 0; if(gp::on) { gp::just_matrices = true; gp::draw_li = gp::get_local_info(cwt.c); if(gp::draw_li.last_dir == -1) gp::draw_li.total_dir = 0; gp::draw_li.total_dir = fix6(gp::draw_li.total_dir); gp::get_plainshape_id(cwt.c); gp::just_matrices = false; } // if(gp::on && !gp::usedml.count(cwt.c)) return; for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { // for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0); hyperpoint h2 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,1,0); hyperpoint h3 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,0,1); queueline(h1, h2, 0xFFFFFFFF, 4, PPR_LINE); queueline(h2, h3, 0xFFFFFFFF, 4, PPR_LINE); queueline(h3, h1, 0xFFFFFFFF, 4, PPR_LINE); hyperpoint ch = mid3(h1, h2, h3); queuestr(ch, vid.fsize, its(id), 0xFFFFFF); if(0) { hyperpoint h1 = gmatrix[cwt.c] * inverse(v.first) * hpxyz(1,0,0); hyperpoint h2 = gmatrix[cwt.c] * inverse(v.first) * hpxyz(0,1,0); hyperpoint h3 = gmatrix[cwt.c] * inverse(v.first) * hpxyz(0,0,1); queueline(h1, h2, 0xFF00FF80, 4, PPR_LINE); queueline(h2, h3, 0xFF00FF80, 4, PPR_LINE); queueline(h3, h1, 0xFF00FF80, 4, PPR_LINE); hyperpoint ch = mid3(h1, h2, h3); queuestr(ch, vid.fsize, its(id), 0xFFFFFF); } id++; } */ }