namespace hr { vector all_plain_floorshapes; vector all_escher_floorshapes; 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 pp: lst) lstmid += pp; 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 &pp: lst) pp = T * pp; 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]); } hyperpoint get_horopoint(ld y, ld x) { return xpush(-y) * binary::parabolic(x) * C0; } void horopoint(ld y, ld x) { hpcpush(get_horopoint(y, x)); } void horopoint(ld y, ld x, cell &fc, int c) { hpcpush(iddspin(&fc, c) * get_horopoint(y, x)); } void horoline(ld y, ld x1, ld x2) { for(int a=0; a<=16; a++) horopoint(y, x1 + (x2-x1) * a / 16.); } void horoline(ld y, ld x1, ld x2, cell &fc, int c) { for(int a=0; a<=16; a++) horopoint(y, x1 + (x2-x1) * a / 16., fc, c); } void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) { if(binarytiling) { bshape(fsh.b[id], fsh.prio); ld yx = size * log(2) / 2; ld yy = yx; ld xx = size / sqrt(2)/2; horoline(-yx, -xx, xx); horoline(yx, xx*2, -xx*2); horopoint(-yx, -xx); bshape(fsh.shadow[id], fsh.prio); horoline(-yx*SHADMUL, -xx*SHADMUL, xx*SHADMUL); horoline(yx*SHADMUL, xx*SHADMUL*2, -xx*SHADMUL*2); horopoint(-yx*SHADMUL, -xx*SHADMUL); cell fc; fc.type = 6+id; 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 : SG6; 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; } } namespace irr { map usedml; void generate_floorshapes() { if(irr::cells.empty()) return; int cc = isize(irr::cells); for(auto pfsh: all_escher_floorshapes) { auto& fsh = *pfsh; generate_matrices_scale(1, fsh.noftype); /* if(siid == 0) for(auto& ma: m.v) ma.first = ma.first * pispin; */ fsh.b.resize(cc); for(int id=0; id cornerlist; int cor = isize(vs.vertices); if(&fsh == &shBigTriangle) { if(vs.is_pseudohept) { for(int i=0; i &shv, int col, int prio = -1) { if(gp::on) { int id = gp::get_plainshape_id(c); queuepolyat(V, shv[id], col, prio); } else if(irr::on) { int id = irr::cellindex[c]; if(id < 0 || id >= isize(shv)) { return; } 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 if(binarytiling) queuepolyat(V, shv[c->type-6], 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, isize(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 || irr::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); id = irr::cellindex[cwt.c]; for(auto& v: irr::usedml[id].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++; } */ } }