major cleanup of texture remapping

This commit is contained in:
Zeno Rogue 2018-08-20 02:04:49 +02:00
parent 47c49c6d1d
commit 625144195c
8 changed files with 109 additions and 127 deletions

View File

@ -631,7 +631,7 @@ void draw_qfi(cell *c, const transmatrix& V, int col, int prio = -1, vector<hpcs
else if(qfi.tinf) { 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); 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; lastptd().u.poly.tinf = qfi.tinf;
if(gp::on || irr::on) if(true)
lastptd().u.poly.flags = POLY_INVERSE; lastptd().u.poly.flags = POLY_INVERSE;
} }
#endif #endif

View File

@ -403,9 +403,7 @@ void showEuclideanMenu() {
else if(binarytiling) { else if(binarytiling) {
dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), ""); dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), "");
dialog::reaction = [] () { dialog::reaction = [] () {
resetGeometry(); resetGeometry(); texture::config.remap();
if(texture::config.tstate == texture::tsActive)
texture::config.remap(texture::tsActive, texture::tsActive);
}; };
} }
else // if(S3 == 3) else // if(S3 == 3)

View File

@ -647,11 +647,7 @@ namespace hr { namespace gp {
} }
} }
void whirl_set(loc xy, bool texture_remap) { void whirl_set(loc xy) {
#if CAP_TEXTURE
auto old_tstate = texture::config.tstate;
auto old_tstate_max = texture::config.tstate_max;
#endif
xy = internal_representation(xy); xy = internal_representation(xy);
if(xy.second && xy.second != xy.first && nonorientable) { if(xy.second && xy.second != xy.first && nonorientable) {
addMessage(XLAT("This does not work in non-orientable geometries")); addMessage(XLAT("This does not work in non-orientable geometries"));
@ -675,10 +671,6 @@ namespace hr { namespace gp {
stop_game_and_switch_mode(rg::gp); stop_game_and_switch_mode(rg::gp);
} }
start_game(); start_game();
#if CAP_TEXTURE
if(texture_remap)
texture::config.remap(old_tstate, old_tstate_max);
#endif
screens = g; screens = g;
} }
@ -692,30 +684,25 @@ namespace hr { namespace gp {
); );
} }
void show(bool texture_remap) { void show() {
cmode = sm::SIDE; cmode = sm::SIDE;
gamescreen(0); gamescreen(0);
dialog::init(XLAT("variations")); dialog::init(XLAT("variations"));
bool show_nonthree = !(texture_remap && (S7&1)); int min_quality = 0;
bool show_bitrunc = !(texture_remap && !(S7&1)); if((texture::config.tstate == texture::tsActive) && (S7 % 2 == 1)) {
bool show_irregular = true; if(texture::cgroup == cpFootball) min_quality = 1;
if(texture_remap) {
if(patterns::cgroup == cpSingle)
show_nonthree = true, show_bitrunc = false, show_irregular = true;
} }
if(show_nonthree) { if(min_quality == 0) {
dialog::addBoolItem(XLAT("OFF"), param == loc(1,0) && !irr::on, 'a'); dialog::addBoolItem(XLAT("OFF"), param == loc(1,0) && !irr::on, 'a');
dialog::lastItem().value = "GP(1,0)"; dialog::lastItem().value = "GP(1,0)";
} }
if(show_bitrunc) { dialog::addBoolItem(XLAT("bitruncated"), param == loc(1,1) && !nonbitrunc, 'b');
dialog::addBoolItem(XLAT("bitruncated"), param == loc(1,1) && !nonbitrunc, 'b'); dialog::lastItem().value = S3 == 3 ? "GP(1,1)" : XLAT(nonbitrunc ? "OFF" : "ON");
dialog::lastItem().value = S3 == 3 ? "GP(1,1)" : XLAT(nonbitrunc ? "OFF" : "ON");
}
if(show_nonthree) { if(min_quality == 0) {
dialog::addBoolItem(XLAT(S3 == 3 ? "chamfered" : "expanded"), param == loc(2,0), 'c'); dialog::addBoolItem(XLAT(S3 == 3 ? "chamfered" : "expanded"), param == loc(2,0), 'c');
dialog::lastItem().value = "GP(2,0)"; dialog::lastItem().value = "GP(2,0)";
} }
@ -736,17 +723,15 @@ namespace hr { namespace gp {
if(config.second && config.second != config.first && nonorientable) { if(config.second && config.second != config.first && nonorientable) {
dialog::addInfo(XLAT("This does not work in non-orientable geometries")); dialog::addInfo(XLAT("This does not work in non-orientable geometries"));
} }
else if((config.first-config.second)%3 && !show_nonthree) else if((config.first-config.second)%3 && min_quality)
dialog::addInfo(XLAT("This pattern needs x-y divisible by 3")); dialog::addInfo(XLAT("This pattern needs x-y divisible by 3"));
else if(config == loc(1,1) && !show_bitrunc)
dialog::addInfo(XLAT("Select bitruncated from the previous menu"));
else else
dialog::addBoolItem(XLAT("select"), param == internal_representation(config) && !irr::on, 'f'); dialog::addBoolItem(XLAT("select"), param == internal_representation(config) && !irr::on, 'f');
if(show_irregular && irr::supports(geometry)) { if(irr::supports(geometry)) {
dialog::addBoolItem(XLAT("irregular"), irr::on, 'i'); dialog::addBoolItem(XLAT("irregular"), irr::on, 'i');
dialog::add_action([=] () { dialog::add_action([=] () {
if(texture_remap && !show_nonthree && !irr::bitruncations_requested) irr::bitruncations_requested++; if(min_quality && !irr::bitruncations_requested) irr::bitruncations_requested++;
if(!irr::on) irr::visual_creator(); if(!irr::on) irr::visual_creator();
}); });
} }
@ -756,24 +741,24 @@ namespace hr { namespace gp {
dialog::addBack(); dialog::addBack();
dialog::display(); dialog::display();
keyhandler = [show_nonthree, show_bitrunc, texture_remap] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
if(uni == 'a' && show_nonthree) if(uni == 'a')
whirl_set(loc(1, 0), texture_remap); whirl_set(loc(1, 0));
else if(uni == 'b' && show_bitrunc) { else if(uni == 'b') {
if(S3 == 4) { if(S3 == 4) {
if(nonbitrunc || gp::on) if(nonbitrunc || gp::on)
restart_game(rg::bitrunc); restart_game(rg::bitrunc);
} }
else else
whirl_set(loc(1, 1), texture_remap); whirl_set(loc(1, 1));
} }
else if(uni == 'c' && show_nonthree) else if(uni == 'c')
whirl_set(loc(2, 0), texture_remap); whirl_set(loc(2, 0));
else if(uni == 'd') else if(uni == 'd')
whirl_set(S3 == 3 ? loc(3, 0) : loc(1,1), texture_remap); whirl_set(S3 == 3 ? loc(3, 0) : loc(1,1));
else if(uni == 'f' && (config == loc(1,1) ? show_bitrunc : (show_nonthree || (config.first-config.second)%3 == 0))) else if(uni == 'f')
whirl_set(config, texture_remap); whirl_set(config);
else if(uni == 'x') else if(uni == 'x')
dialog::editNumber(config.first, 0, 8, 1, 1, "x", helptext()); dialog::editNumber(config.first, 0, 8, 1, 1, "x", helptext());
else if(uni == 'y') else if(uni == 'y')
@ -793,11 +778,11 @@ namespace hr { namespace gp {
else return loc(1,1); else return loc(1,1);
} }
void configure(bool texture_remap = false) { void configure() {
auto l = univ_param(); auto l = univ_param();
param = l; param = l;
config = human_representation(l); config = human_representation(l);
pushScreen([texture_remap] () { gp::show(texture_remap); }); pushScreen(gp::show);
} }
void be_in_triangle(local_info& li) { void be_in_triangle(local_info& li) {

View File

@ -2941,7 +2941,9 @@ namespace texture {
void mapTextureTriangle(textureinfo &mi, const array<hyperpoint, 3>& v, const array<hyperpoint, 3>& tv) { mapTextureTriangle(mi, v, tv, gsplits); } void mapTextureTriangle(textureinfo &mi, const array<hyperpoint, 3>& v, const array<hyperpoint, 3>& tv) { mapTextureTriangle(mi, v, tv, gsplits); }
void mapTexture2(textureinfo& mi); void mapTexture2(textureinfo& mi);
void finish_mapping(); void finish_mapping();
void remap(eTextureState old_tstate, eTextureState old_tstate_max); void true_remap();
void remap();
bool correctly_mapped;
hyperpoint texture_coordinates(hyperpoint); hyperpoint texture_coordinates(hyperpoint);
void drawRawTexture(); void drawRawTexture();
@ -3262,7 +3264,7 @@ namespace gp {
extern string operation_name(); extern string operation_name();
extern int pseudohept_val(cell *); extern int pseudohept_val(cell *);
extern int last_dir(cell *c); extern int last_dir(cell *c);
extern void configure(bool texture_remap); extern void configure();
extern ld alpha; extern ld alpha;
extern transmatrix Tf[8][32][32][6]; extern transmatrix Tf[8][32][32][6];
@ -3845,5 +3847,7 @@ heptagon* encodeId(int id);
void virtualRebaseSimple(heptagon*& base, transmatrix& at); void virtualRebaseSimple(heptagon*& base, transmatrix& at);
extern bool game_active;
} }

View File

@ -801,10 +801,6 @@ int celldist(cell *c, bool alts) {
eGeometry orig_geometry; eGeometry orig_geometry;
void start_game_on_created_map() { void start_game_on_created_map() {
#if CAP_TEXTURE
auto old_tstate = texture::config.tstate;
auto old_tstate_max = texture::config.tstate_max;
#endif
popScreen(); popScreen();
for(hrmap *& hm : allmaps) if(hm == base) hm = NULL; for(hrmap *& hm : allmaps) if(hm == base) hm = NULL;
stop_game(); stop_game();
@ -815,9 +811,6 @@ void start_game_on_created_map() {
need_reset_geometry = true; need_reset_geometry = true;
gridmaking = false; gridmaking = false;
start_game(); start_game();
#if CAP_TEXTURE
texture::config.remap(old_tstate, old_tstate_max);
#endif
} }
bool save_map(const string& fname) { bool save_map(const string& fname) {

View File

@ -1599,30 +1599,39 @@ namespace patterns {
#if CAP_EDIT #if CAP_EDIT
mapeditor::modelcell.clear(); mapeditor::modelcell.clear();
#endif #endif
texture::config.remap();
} }
else if(uni >= '0' && uni <= '5') else if(uni >= '0' && uni <= '5') {
subpattern_flags ^= (1 << (uni - '0')); subpattern_flags ^= (1 << (uni - '0'));
texture::config.remap();
}
else if(uni == '=') else if(uni == '=') {
subpattern_flags ^= SPF_EXTRASYM; subpattern_flags ^= SPF_EXTRASYM;
texture::config.remap();
}
else if(uni == '\'') { else if(uni == '\'') {
subpattern_flags ^= SPF_ALTERNATE; subpattern_flags ^= SPF_ALTERNATE;
subpattern_flags &= ~SPF_FOOTBALL; subpattern_flags &= ~SPF_FOOTBALL;
texture::config.remap();
} }
else if(uni == '*') { else if(uni == '*') {
subpattern_flags ^= SPF_FOOTBALL; subpattern_flags ^= SPF_FOOTBALL;
subpattern_flags &= ~SPF_ALTERNATE; subpattern_flags &= ~SPF_ALTERNATE;
texture::config.remap();
} }
else if(uni == '!') { else if(uni == '!') {
subpattern_flags ^= SPF_FULLSYM; subpattern_flags ^= SPF_FULLSYM;
texture::config.remap();
} }
else if(uni == '@') { else if(uni == '@') {
subpattern_flags ^= SPF_DOCKS; subpattern_flags ^= SPF_DOCKS;
texture::config.remap();
} }
else if(uni == '6' || uni == '7' || uni == '8' || uni == '9') { else if(uni == '6' || uni == '7' || uni == '8' || uni == '9') {
@ -1803,23 +1812,18 @@ namespace patterns {
else if(uni >= '0' && uni < '0' + isize(cpatterns)) else if(uni >= '0' && uni < '0' + isize(cpatterns))
cgroup = cpatterntype(uni - '0'); cgroup = cpatterntype(uni - '0');
else if(cgroup != cpUnknown && uni >= 'a' && uni < 'a' + isize(cpatterns[cgroup].geometries)) { else if(cgroup != cpUnknown && uni >= 'a' && uni < 'a' + isize(cpatterns[cgroup].geometries)) {
#if CAP_TEXTURE
auto old_tstate = texture::config.tstate;
auto old_tstate_max = texture::config.tstate_max;
#endif
auto &g = cpatterns[cgroup].geometries[uni - 'a']; auto &g = cpatterns[cgroup].geometries[uni - 'a'];
if(g.geo != geometry) { targetgeometry = g.geo; stop_game_and_switch_mode(rg::geometry); } if(g.geo != geometry) { targetgeometry = g.geo; stop_game_and_switch_mode(rg::geometry); }
if(gp::on) stop_game_and_switch_mode(rg::gp); if(gp::on) stop_game_and_switch_mode(rg::gp);
if(g.nonbitru != nonbitrunc) stop_game_and_switch_mode(rg::bitrunc);; if(g.nonbitru != nonbitrunc) stop_game_and_switch_mode(rg::bitrunc);;
start_game();
whichPattern = g.whichPattern; whichPattern = g.whichPattern;
subpattern_flags = g.subpattern_flags; subpattern_flags = g.subpattern_flags;
#if CAP_TEXTURE bool not_restarted = game_active;
texture::config.remap(old_tstate, old_tstate_max); start_game();
#endif if(not_restarted) texture::config.remap();
} }
else if(uni == 'G' && (have_goldberg || have_variations)) else if(uni == 'G' && (have_goldberg || have_variations))
gp::configure(true); gp::configure();
else if(doexiton(sym, uni)) else if(doexiton(sym, uni))
popScreen(); popScreen();
}; };

View File

@ -1169,12 +1169,6 @@ void switch_game_mode(char switchWhat) {
nonbitrunc = !nonbitrunc; irr::on = false; nonbitrunc = !nonbitrunc; irr::on = false;
gp::on = (switchWhat == rg::gp && !gp::on); gp::on = (switchWhat == rg::gp && !gp::on);
need_reset_geometry = true; need_reset_geometry = true;
#if CAP_TEXTURE
if(texture::config.tstate == texture::tsActive)
texture::config.tstate = texture::tsAdjusting;
if(texture::config.tstate_max == texture::tsActive)
texture::config.tstate = texture::tsAdjusting;
#endif
break; break;
case rg::geometry: case rg::geometry:
@ -1194,12 +1188,6 @@ void switch_game_mode(char switchWhat) {
if(geometry == gBinaryTiling) nonbitrunc = true, gp::on = irr::on = false; if(geometry == gBinaryTiling) nonbitrunc = true, gp::on = irr::on = false;
need_reset_geometry = true; need_reset_geometry = true;
#if CAP_TEXTURE
if(texture::config.tstate == texture::tsActive)
texture::config.tstate = texture::tsOff;
if(texture::config.tstate_max == texture::tsActive)
texture::config.tstate = texture::tsAdjusting;
#endif
break; break;
case rg::yendor: case rg::yendor:
@ -1284,6 +1272,9 @@ void start_game() {
restartGraph(); restartGraph();
resetmusic(); resetmusic();
resetmusic(); resetmusic();
#if CAP_TEXTURE
texture::config.remap();
#endif
} }
void restart_game(char switchWhat) { void restart_game(char switchWhat) {

View File

@ -328,7 +328,7 @@ bool using_aura() {
} }
bool texture_config::apply(cell *c, const transmatrix &V, int col) { bool texture_config::apply(cell *c, const transmatrix &V, int col) {
if(config.tstate == tsOff) return false; if(config.tstate == tsOff || !correctly_mapped) return false;
using namespace patterns; using namespace patterns;
auto si = getpatterninfo0(c); auto si = getpatterninfo0(c);
@ -453,10 +453,15 @@ void texture_config::perform_mapping() {
} }
set<int> missing_cells_known;
void texture_config::finish_mapping() { void texture_config::finish_mapping() {
if(config.tstate == tsActive) if(config.tstate == tsActive) {
for(auto& mi: texture_map) for(auto& mi: texture_map)
mapTexture2(mi.second); mapTexture2(mi.second);
correctly_mapped = true;
missing_cells_known.clear();
}
patterns::computeCgroup(); patterns::computeCgroup();
texture::cgroup = patterns::cgroup; texture::cgroup = patterns::cgroup;
@ -1412,55 +1417,64 @@ void drawLine(hyperpoint h1, hyperpoint h2, int col, int steps) {
drawPixel(h2, col); drawPixel(h2, col);
} }
void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_max) { void texture_config::true_remap() {
drawthemap(); drawthemap();
clear_texture_map(); clear_texture_map();
if(old_tstate == tsActive && patterns::compatible(texture::cgroup, patterns::cgroup)) { missing_cells_known.clear();
for(cell *c: dcal) {
config.tstate = old_tstate; auto si = patterns::getpatterninfo0(c);
config.tstate_max = old_tstate_max; int oldid = si.id;
for(cell *c: dcal) {
auto si = patterns::getpatterninfo0(c); si.id += goldbergcode(c, si);
int oldid = si.id;
si.id += goldbergcode(c, si);
if(texture_map.count(si.id)) continue; if(texture_map.count(si.id)) continue;
int pshift = 0; int pshift = 0;
if(texture::cgroup == cpSingle) oldid = 0; if(texture::cgroup == cpSingle) oldid = 0;
if(texture::cgroup == cpFootball && patterns::cgroup == cpThree) { if(texture::cgroup == cpFootball && patterns::cgroup == cpThree) {
if(si.id == 4) pshift = 1; if(si.id == 4) pshift = 1;
oldid = !si.id; oldid = !si.id;
}
try {
auto& mi = texture_map_orig.at(oldid);
int ncurr = isize(mi.tvertices);
int ntarget = ncurr * celltriangles(c) / mi.current_type;
vector<glvertex> new_tvertices = mi.tvertices;
new_tvertices.resize(ntarget);
for(int i=ncurr; i<ntarget; i++) {
new_tvertices[i] = new_tvertices[i - ncurr];
} }
try { auto& mi2 = texture_map[si.id];
mi2 = mi;
auto& mi = texture_map_orig.at(oldid); if(gp::on || irr::on) pshift += si.dir;
int ncurr = isize(mi.tvertices); mapTexture(c, mi2, si, ggmatrix(c), pshift);
int ntarget = ncurr * celltriangles(c) / mi.current_type; mapTexture2(mi2);
vector<glvertex> new_tvertices = mi.tvertices; mi2.tvertices = move(new_tvertices);
new_tvertices.resize(ntarget); // printf("%08x remapping %d vertices to %d vertices\n", si.id, isize(mi.tvertices), isize(mi2.tvertices));
for(int i=ncurr; i<ntarget; i++) { }
new_tvertices[i] = new_tvertices[i - ncurr]; catch(out_of_range&) {
} if(missing_cells_known.count(si.id) == 0) {
missing_cells_known.insert(si.id);
auto& mi2 = texture_map[si.id];
mi2 = mi;
mapTexture(c, mi2, si, ggmatrix(c), pshift);
mapTexture2(mi2);
mi2.tvertices = move(new_tvertices);
// printf("%08x remapping %d vertices to %d vertices\n", si.id, isize(mi.tvertices), isize(mi2.tvertices));
}
catch(out_of_range&) {
printf("Unexpected missing cell #%d/%d\n", si.id, oldid); printf("Unexpected missing cell #%d/%d\n", si.id, oldid);
addMessage(XLAT("Unexpected missing cell #%d/%d", its(si.id), its(oldid))); addMessage(XLAT("Unexpected missing cell #%1/%1", its(si.id), its(oldid)));
config.tstate_max = config.tstate = tsAdjusting;
return;
} }
} // config.tstate_max = config.tstate = tsAdjusting;
return;
}
} }
else if(old_tstate >= tsAdjusting || old_tstate_max >= tsAdjusting) { }
void texture_config::remap() {
if(tstate == tsActive) {
patterns::computeCgroup();
correctly_mapped = patterns::compatible(texture::cgroup, patterns::cgroup);
if(correctly_mapped) true_remap();
else addMessage(XLAT("Pattern incompatible."));
}
else if(tstate == tsAdjusting) {
printf("perform_mapping %d/%d\n", config.tstate, config.tstate_max); printf("perform_mapping %d/%d\n", config.tstate, config.tstate_max);
calcparam(); calcparam();
drawthemap(); drawthemap();
@ -1470,8 +1484,6 @@ void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_ma
} }
} }
eTextureState old_tstate_cl, old_tstate_max_cl;
int textureArgs() { int textureArgs() {
using namespace arg; using namespace arg;
@ -1495,12 +1507,7 @@ int textureArgs() {
else if(argis("-txcl")) { else if(argis("-txcl")) {
PHASE(3); drawscreen(); PHASE(3); drawscreen();
config.load(); config.load();
old_tstate_cl = texture::config.tstate; need_reset_geometry = true;
old_tstate_max_cl = texture::config.tstate_max;
}
else if(argis("-txremap")) {
texture::config.remap(old_tstate_cl, old_tstate_max_cl);
} }
else return 1; else return 1;