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) {
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; i<c->type; i++) {

View File

@ -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; i<c->type; 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; 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);
if(dock && (sub & SPF_DOCKS)) si.id += 16;
}

View File

@ -264,11 +264,31 @@ 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;
if(whirl::whirl) {
mi.M = T;
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));
}
}
else {
mi.M = T * applyPatterndir(c, si);
ld z = ctof(c) ? rhexf : hexvdist;
@ -281,6 +301,7 @@ void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const trans
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
}
}
void texture_config::mapTexture2(textureinfo& mi) {
mi.vertices.clear();
@ -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();
@ -360,7 +381,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) {
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;
}
}
@ -403,6 +424,8 @@ void texture_config::perform_mapping() {
// int sgn = sphere ? -1 : 1;
si.id += whirlcode(c, si);
if(!texture_map.count(si.id))
replace = true;
else if(hdist0(p.second*sphereflip * C0) < hdist0(texture_map[si.id].M * sphereflip * C0))
@ -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);

View File

@ -39,20 +39,31 @@ namespace whirl {
}
}
int last_dir(cell *c) {
int d = -1;
while(c != c->master->c7)
d = c->spin(0), c = c->mov[0];
return d;
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);
}
loc get_coord(cell *c) {
if(c == c->master->c7) return loc(0,0);
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);
@ -62,7 +73,18 @@ namespace whirl {
dirs.pop_back();
at = at + eudir(dir);
}
return at;
li.relative = at;
li.total_dir = dir + 3;
}
return li;
}
int last_dir(cell *c) {
return get_local_info(c).last_dir;
}
loc get_coord(cell *c) {
return get_local_info(c).relative;
}
int pseudohept_val(cell *c) {
@ -263,47 +285,77 @@ namespace whirl {
return hpxyz(at.first, at.second, 1);
}
hyperpoint atz(const transmatrix& T, const transmatrix& corners, loc at) {
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, 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<S7; i++) {
cell cc; cc.type = S7;
transmatrix T = spin(-alpha) * build_matrix(
C0,
ddspin(&cc, i) * xpush(tessf) * C0,
ddspin(&cc, i+1) * xpush(tessf) * C0
);
transmatrix T = dir_matrix(i);
for(int x=-10; x<10; x++)
for(int y=-10; y<10; y++)
for(int d=0; d<6; d++) {
loc at = loc(x, y);
hyperpoint h = atz(T, corners, at);
hyperpoint hl = atz(T, corners, at + eudir(d));
hyperpoint h = atz(T, corners, at, 6);
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);
}
}
}
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() {
if(whirl) {
int x = param.first;