1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 17:10:36 +00:00

whirl:: texture:: remapping (currently by commandline only)

This commit is contained in:
Zeno Rogue 2018-04-06 00:40:53 +02:00
parent a3479ae830
commit 587619ad42
4 changed files with 146 additions and 48 deletions

View File

@ -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) { void drawrec(cell *c, const transmatrix& V, whirl::loc at, int dir, int maindir) {
if(dodrawcell(c)) { 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); drawcell(c, V * Tf[maindir][at.first&31][at.second&31][fix6(dir)], 0, false);
} }
for(int i=0; i<c->type; i++) { for(int i=0; i<c->type; i++) {

View File

@ -551,7 +551,7 @@ namespace patterns {
si.id = (c->master->fiftyval >> 1) & 3; si.id = (c->master->fiftyval >> 1) & 3;
else else
si.id = 0; si.id = 0;
if(nonbitrunc) if(nonbitrunc && !whirl::whirl)
si.id *= 4; si.id *= 4;
else else
si.id += 4; si.id += 4;
@ -570,6 +570,7 @@ namespace patterns {
sp ^= ishex2(c); sp ^= ishex2(c);
} }
si.id = 8 * ((c->master->fiftyval & 1) ^ (sp & 1)); si.id = 8 * ((c->master->fiftyval & 1) ^ (sp & 1));
if(whirl::whirl && pseudohept(c)) si.id = 4;
bool dock = false; bool dock = false;
for(int i=0; i<c->type; i+=2) { for(int i=0; i<c->type; i+=2) {
int fiv = createMov(c, i)->master->fiftyval; int fiv = createMov(c, i)->master->fiftyval;
@ -582,6 +583,21 @@ namespace patterns {
if(symRotation) si.symmetries = 2; if(symRotation) si.symmetries = 2;
si.id += 8; si.id += 8;
si.id %= 12; si.id %= 12;
if(whirl::whirl && pat == PAT_COLORING)
for(int i=0; i<c->type; 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); applyAlt(si, sub, pat);
if(dock && (sub & SPF_DOCKS)) si.id += 16; if(dock && (sub & SPF_DOCKS)) si.id += 16;
} }

View File

@ -264,21 +264,42 @@ int getTriangleID(cell *c, patterns::patterninfo& si, hyperpoint h) {
return best; 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) { void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const transmatrix& T, int shift = 0) {
mi.c = c; mi.c = c;
mi.symmetries = si.symmetries; mi.symmetries = si.symmetries;
mi.current_type = c->type; mi.current_type = c->type;
mi.M = T * applyPatterndir(c, si); if(whirl::whirl) {
mi.M = T;
ld z = ctof(c) ? rhexf : hexvdist; mi.triangles.clear();
for(int i=0; i<c->type; 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(); else {
for(int i=0; i<c->type; i++) { mi.M = T * applyPatterndir(c, si);
int i2 = i+shift;
hyperpoint h1 = spin(M_PI + M_PI * (2*i2 -1) / c->type) * xpush(z) * C0; ld z = ctof(c) ? rhexf : hexvdist;
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)); mi.triangles.clear();
for(int i=0; i<c->type; 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; return false;
} }
try { 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(); int n = mi.vertices.size();
@ -328,7 +349,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) {
else { else {
queuetable(V * qfi.spin, mi.vertices, n, mesh_color, recolor(col), PPR_FLOOR); queuetable(V * qfi.spin, mi.vertices, n, mesh_color, recolor(col), PPR_FLOOR);
} }
lastptd().u.poly.tinf = &mi; lastptd().u.poly.tinf = &mi;
if(grid_color) { if(grid_color) {
queuepolyat(V, shFullFloor[ctof(c)], 0, PPR_FLOOR); 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); addaura(V*h, col, 0);
} }
} }
return true; return true;
} }
catch(out_of_range) { 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; return false;
} }
} }
@ -402,6 +423,8 @@ void texture_config::perform_mapping() {
bool replace = false; bool replace = false;
// int sgn = sphere ? -1 : 1; // int sgn = sphere ? -1 : 1;
si.id += whirlcode(c, si);
if(!texture_map.count(si.id)) if(!texture_map.count(si.id))
replace = true; replace = true;
@ -1373,10 +1396,12 @@ void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_ma
config.tstate_max = old_tstate_max; config.tstate_max = old_tstate_max;
for(cell *c: dcal) { for(cell *c: dcal) {
auto si = patterns::getpatterninfo0(c); auto si = patterns::getpatterninfo0(c);
int oldid = si.id;
si.id += whirlcode(c, si);
if(texture_map.count(si.id)) continue; if(texture_map.count(si.id)) continue;
int oldid = si.id;
int pshift = 0; int pshift = 0;
if(texture::cgroup == cpSingle) oldid = 1; if(texture::cgroup == cpSingle) oldid = 1;
if(texture::cgroup == cpFootball && patterns::cgroup == cpThree) { 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); mapTexture(c, mi2, si, shmup::ggmatrix(c), pshift);
mapTexture2(mi2); mapTexture2(mi2);
mi2.tvertices = move(new_tvertices); 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) { catch(out_of_range) {
printf("Unexpected missing cell #%d/%d", si.id, oldid); printf("Unexpected missing cell #%d/%d", si.id, oldid);

116
whirl.cpp
View File

@ -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<int> 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 last_dir(cell *c) {
int d = -1; return get_local_info(c).last_dir;
while(c != c->master->c7)
d = c->spin(0), c = c->mov[0];
return d;
} }
loc get_coord(cell *c) { loc get_coord(cell *c) {
if(c == c->master->c7) return loc(0,0); return get_local_info(c).relative;
vector<int> 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;
} }
int pseudohept_val(cell *c) { int pseudohept_val(cell *c) {
@ -262,47 +284,77 @@ namespace whirl {
hyperpoint loctoh_ort(loc at) { hyperpoint loctoh_ort(loc at) {
return hpxyz(at.first, at.second, 1); 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; int sp = 0;
again: 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) { if(corner[1] < -1e-6 || corner[2] < -1e-6) {
at = at * eudir(1); at = at * eudir(1);
if(cornerid < 6) cornerid = (1 + cornerid) % 6;
sp++; sp++;
goto again; 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); return normalize(spin(2*M_PI*sp/S7) * T * corner);
} }
transmatrix Tf[8][32][32][6]; 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() { void prepare_matrices() {
transmatrix corners = inverse(build_matrix( corners = inverse(build_matrix(
loctoh_ort(loc(0,0)), loctoh_ort(loc(0,0)),
loctoh_ort(param), loctoh_ort(param),
loctoh_ort(param * loc(0,1)) loctoh_ort(param * loc(0,1))
)); ));
for(int i=0; i<S7; i++) { for(int i=0; i<S7; i++) {
cell cc; cc.type = S7; transmatrix T = dir_matrix(i);
transmatrix T = spin(-alpha) * build_matrix(
C0,
ddspin(&cc, i) * xpush(tessf) * C0,
ddspin(&cc, i+1) * xpush(tessf) * C0
);
for(int x=-10; x<10; x++) for(int x=-10; x<10; x++)
for(int y=-10; y<10; y++) for(int y=-10; y<10; y++)
for(int d=0; d<6; d++) { for(int d=0; d<6; d++) {
loc at = loc(x, y); loc at = loc(x, y);
hyperpoint h = atz(T, corners, at); hyperpoint h = atz(T, corners, at, 6);
hyperpoint hl = atz(T, corners, at + eudir(d)); hyperpoint hl = atz(T, corners, at + eudir(d), 6);
Tf[i][x&31][y&31][d] = rgpushxto0(h) * rspintox(gpushxto0(h) * hl) * spin(M_PI); Tf[i][x&31][y&31][d] = rgpushxto0(h) * rspintox(gpushxto0(h) * hl) * spin(M_PI);
} }
} }
} }
hyperpoint get_corner_position(cell *c, int cid, ld cf = 3) {
auto li = get_local_info(c);
int i = li.last_dir;
if(i == -1)
return atz(dir_matrix(cid), corners, li.relative, 0, cf);
else {
auto& cellmatrix = Tf[i][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)];
return inverse(cellmatrix) * atz(dir_matrix(i), corners, li.relative, fix6(cid + li.total_dir), cf);
}
}
void compute_geometry() { void compute_geometry() {
if(whirl) { if(whirl) {