diff --git a/hypgraph.cpp b/hypgraph.cpp index 9d058101..2471cd63 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -474,6 +474,10 @@ void drawrec(cell *c, const transmatrix& V) { void drawrec(cell *c, const transmatrix& V, whirl::loc at, int dir, int maindir) { if(dodrawcell(c)) { +/* auto li = get_local_info(c); + if(fix6(dir) != fix6(li.total_dir)) printf("totaldir %d/%d\n", dir, li.total_dir); + if(at != li.relative) printf("at %s/%s\n", disp(at), disp(li.relative)); + if(maindir != li.last_dir) printf("ld %d/%d\n", maindir, li.last_dir); */ drawcell(c, V * Tf[maindir][at.first&31][at.second&31][fix6(dir)], 0, false); } for(int i=0; itype; i++) { diff --git a/pattern2.cpp b/pattern2.cpp index 85405fe7..be00fe38 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -551,7 +551,7 @@ namespace patterns { si.id = (c->master->fiftyval >> 1) & 3; else si.id = 0; - if(nonbitrunc) + if(nonbitrunc && !whirl::whirl) si.id *= 4; else si.id += 4; @@ -570,6 +570,7 @@ namespace patterns { sp ^= ishex2(c); } si.id = 8 * ((c->master->fiftyval & 1) ^ (sp & 1)); + if(whirl::whirl && pseudohept(c)) si.id = 4; bool dock = false; for(int i=0; itype; i+=2) { int fiv = createMov(c, i)->master->fiftyval; @@ -582,6 +583,21 @@ namespace patterns { if(symRotation) si.symmetries = 2; si.id += 8; si.id %= 12; + if(whirl::whirl && pat == PAT_COLORING) + for(int i=0; itype; i++) { + cell *c2 = createMov(c, i); + int id2 = 4; + if(!pseudohept(c2)) { + int sp2 = c2->spin(0); + if(whirl::whirl) { + sp2 = whirl::last_dir(c2); + sp2 ^= ishex2(c2); + } + id2 = 8 * ((c2->master->fiftyval & 1) ^ (sp2 & 1)); + } +// printf("%p %2d : %d %d\n", c, si.id, i, id2); + if((id2+4) % 12 == si.id) si.dir = i; + } applyAlt(si, sub, pat); if(dock && (sub & SPF_DOCKS)) si.id += 16; } diff --git a/textures.cpp b/textures.cpp index df16e5e8..207ef1a2 100644 --- a/textures.cpp +++ b/textures.cpp @@ -264,21 +264,42 @@ int getTriangleID(cell *c, patterns::patterninfo& si, hyperpoint h) { return best; } +int whirlcode(cell *c, const patterns::patterninfo& si) { + if(!whirl::whirl) return 0; + else if(c == c->master->c7) return (fixdir(si.dir, c) << 8); + else return (get_code(whirl::get_local_info(c)) << 16) | (fixdir(si.dir, c) << 8); + } + void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const transmatrix& T, int shift = 0) { mi.c = c; mi.symmetries = si.symmetries; mi.current_type = c->type; - mi.M = T * applyPatterndir(c, si); - - ld z = ctof(c) ? rhexf : hexvdist; + if(whirl::whirl) { + mi.M = T; + mi.triangles.clear(); + for(int i=0; itype; i++) { + int d = si.dir; + int i0 = fixdir(i + d + 0, c); + int i1 = fixdir(i + d + 1, c); + hyperpoint h1 = whirl::get_corner_position(c, i0); + hyperpoint h2 = whirl::get_corner_position(c, i1); + mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2)); + } + } - mi.triangles.clear(); - for(int i=0; itype; i++) { - int i2 = i+shift; - hyperpoint h1 = spin(M_PI + M_PI * (2*i2 -1) / c->type) * xpush(z) * C0; - hyperpoint h2 = spin(M_PI + M_PI * (2*i2 +1) / c->type) * xpush(z) * C0; - mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2)); + else { + mi.M = T * applyPatterndir(c, si); + + ld z = ctof(c) ? rhexf : hexvdist; + + mi.triangles.clear(); + for(int i=0; itype; i++) { + int i2 = i+shift; + hyperpoint h1 = spin(M_PI + M_PI * (2*i2 -1) / c->type) * xpush(z) * C0; + hyperpoint h2 = spin(M_PI + M_PI * (2*i2 +1) / c->type) * xpush(z) * C0; + mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2)); + } } } @@ -310,9 +331,9 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) { return false; } try { - auto& mi = texture_map.at(si.id); + auto& mi = texture_map.at(si.id + whirlcode(c, si)); - qfi.spin = applyPatterndir(c, si); + qfi.spin = whirl::whirl ? Id : applyPatterndir(c, si); int n = mi.vertices.size(); @@ -328,7 +349,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) { else { queuetable(V * qfi.spin, mi.vertices, n, mesh_color, recolor(col), PPR_FLOOR); } - + lastptd().u.poly.tinf = &mi; if(grid_color) { queuepolyat(V, shFullFloor[ctof(c)], 0, PPR_FLOOR); @@ -356,11 +377,11 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) { addaura(V*h, col, 0); } } - + return true; } catch(out_of_range) { - // printf("Ignoring tile #%d : not mapped\n", si.id); + // printf("Ignoring tile #%d / %08x: not mapped\n", si.id, whirlcode(c, si)); return false; } } @@ -402,6 +423,8 @@ void texture_config::perform_mapping() { bool replace = false; // int sgn = sphere ? -1 : 1; + + si.id += whirlcode(c, si); if(!texture_map.count(si.id)) replace = true; @@ -1373,10 +1396,12 @@ void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_ma config.tstate_max = old_tstate_max; for(cell *c: dcal) { auto si = patterns::getpatterninfo0(c); + int oldid = si.id; + si.id += whirlcode(c, si); + if(texture_map.count(si.id)) continue; - int oldid = si.id; int pshift = 0; if(texture::cgroup == cpSingle) oldid = 1; if(texture::cgroup == cpFootball && patterns::cgroup == cpThree) { @@ -1400,6 +1425,7 @@ void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_ma mapTexture(c, mi2, si, shmup::ggmatrix(c), pshift); mapTexture2(mi2); mi2.tvertices = move(new_tvertices); + // printf("%08x remapping %d vertices to %d vertices\n", si.id, size(mi.tvertices), size(mi2.tvertices)); } catch(out_of_range) { printf("Unexpected missing cell #%d/%d", si.id, oldid); diff --git a/whirl.cpp b/whirl.cpp index 535e1343..bac7c77c 100644 --- a/whirl.cpp +++ b/whirl.cpp @@ -39,30 +39,52 @@ namespace whirl { } } + int get_code(const local_info& li) { + return + ((li.relative.first & 15) << 0) + + ((li.relative.second & 15) << 4) + + ((fix6(li.total_dir)) << 8) + + ((li.last_dir & 15) << 12); + } + + local_info get_local_info(cell *c) { + local_info li; + if(c == c->master->c7) { + li.relative = loc(0,0); + li.first_dir = -1; + li.last_dir = -1; + li.total_dir = -1; + } + else { + vector dirs; + while(c != c->master->c7) { + dirs.push_back(c->spin(0)); + c = c->mov[0]; + } + li.first_dir = dirs[0]; + li.last_dir = dirs.back(); + + loc at(0,0); + int dir = 0; + at = at + eudir(dir); + dirs.pop_back(); + while(dirs.size()) { + dir += dirs.back() + 3; + dirs.pop_back(); + at = at + eudir(dir); + } + li.relative = at; + li.total_dir = dir + 3; + } + return li; + } + int last_dir(cell *c) { - int d = -1; - while(c != c->master->c7) - d = c->spin(0), c = c->mov[0]; - return d; + return get_local_info(c).last_dir; } loc get_coord(cell *c) { - if(c == c->master->c7) return loc(0,0); - vector dirs; - while(c != c->master->c7) { - dirs.push_back(c->spin(0)); - c = c->mov[0]; - } - loc at(0,0); - int dir = 0; - at = at + eudir(dir); - dirs.pop_back(); - while(dirs.size()) { - dir += dirs.back() + 3; - dirs.pop_back(); - at = at + eudir(dir); - } - return at; + return get_local_info(c).relative; } int pseudohept_val(cell *c) { @@ -262,47 +284,77 @@ namespace whirl { hyperpoint loctoh_ort(loc at) { return hpxyz(at.first, at.second, 1); } + + hyperpoint corner_coords[7] = { + hpxyz(2, -1, 0), + hpxyz(1, 1, 0), + hpxyz(-1, 2, 0), + hpxyz(-2, 1, 0), + hpxyz(-1, -1, 0), + hpxyz(1, -2, 0), + hpxyz(0, 0, 0) // center, not a corner + }; + + int bak_sp; - hyperpoint atz(const transmatrix& T, const transmatrix& corners, loc at) { + hyperpoint atz(const transmatrix& T, const transmatrix& corners, loc at, int cornerid = 6, ld cf = 3) { int sp = 0; again: - auto corner = corners * loctoh_ort(at); + auto corner = corners * hyperpoint_vec::operator+ (loctoh_ort(at), hyperpoint_vec::operator/ (corner_coords[cornerid], cf)); if(corner[1] < -1e-6 || corner[2] < -1e-6) { at = at * eudir(1); + if(cornerid < 6) cornerid = (1 + cornerid) % 6; sp++; goto again; } - if(sp>3) sp -= 6; + if(sp>3) sp -= 6; bak_sp = sp; return normalize(spin(2*M_PI*sp/S7) * T * corner); } transmatrix Tf[8][32][32][6]; + transmatrix corners; + + transmatrix dir_matrix(int i) { + cell cc; cc.type = S7; + return spin(-alpha) * build_matrix( + C0, + ddspin(&cc, i) * xpush(tessf) * C0, + ddspin(&cc, i+1) * xpush(tessf) * C0 + ); + } + void prepare_matrices() { - transmatrix corners = inverse(build_matrix( + corners = inverse(build_matrix( loctoh_ort(loc(0,0)), loctoh_ort(param), loctoh_ort(param * loc(0,1)) )); for(int i=0; i