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) {
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)
if(true)
lastptd().u.poly.flags = POLY_INVERSE;
}
#endif

View File

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

View File

@ -647,11 +647,7 @@ namespace hr { namespace gp {
}
}
void whirl_set(loc xy, bool texture_remap) {
#if CAP_TEXTURE
auto old_tstate = texture::config.tstate;
auto old_tstate_max = texture::config.tstate_max;
#endif
void whirl_set(loc xy) {
xy = internal_representation(xy);
if(xy.second && xy.second != xy.first && nonorientable) {
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);
}
start_game();
#if CAP_TEXTURE
if(texture_remap)
texture::config.remap(old_tstate, old_tstate_max);
#endif
screens = g;
}
@ -692,30 +684,25 @@ namespace hr { namespace gp {
);
}
void show(bool texture_remap) {
void show() {
cmode = sm::SIDE;
gamescreen(0);
dialog::init(XLAT("variations"));
bool show_nonthree = !(texture_remap && (S7&1));
bool show_bitrunc = !(texture_remap && !(S7&1));
bool show_irregular = true;
if(texture_remap) {
if(patterns::cgroup == cpSingle)
show_nonthree = true, show_bitrunc = false, show_irregular = true;
int min_quality = 0;
if((texture::config.tstate == texture::tsActive) && (S7 % 2 == 1)) {
if(texture::cgroup == cpFootball) min_quality = 1;
}
if(show_nonthree) {
if(min_quality == 0) {
dialog::addBoolItem(XLAT("OFF"), param == loc(1,0) && !irr::on, 'a');
dialog::lastItem().value = "GP(1,0)";
}
if(show_bitrunc) {
dialog::addBoolItem(XLAT("bitruncated"), param == loc(1,1) && !nonbitrunc, 'b');
dialog::lastItem().value = S3 == 3 ? "GP(1,1)" : XLAT(nonbitrunc ? "OFF" : "ON");
}
dialog::addBoolItem(XLAT("bitruncated"), param == loc(1,1) && !nonbitrunc, 'b');
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::lastItem().value = "GP(2,0)";
}
@ -736,17 +723,15 @@ namespace hr { namespace gp {
if(config.second && config.second != config.first && nonorientable) {
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"));
else if(config == loc(1,1) && !show_bitrunc)
dialog::addInfo(XLAT("Select bitruncated from the previous menu"));
else
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::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();
});
}
@ -756,24 +741,24 @@ namespace hr { namespace gp {
dialog::addBack();
dialog::display();
keyhandler = [show_nonthree, show_bitrunc, texture_remap] (int sym, int uni) {
keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni);
if(uni == 'a' && show_nonthree)
whirl_set(loc(1, 0), texture_remap);
else if(uni == 'b' && show_bitrunc) {
if(uni == 'a')
whirl_set(loc(1, 0));
else if(uni == 'b') {
if(S3 == 4) {
if(nonbitrunc || gp::on)
restart_game(rg::bitrunc);
}
else
whirl_set(loc(1, 1), texture_remap);
whirl_set(loc(1, 1));
}
else if(uni == 'c' && show_nonthree)
whirl_set(loc(2, 0), texture_remap);
else if(uni == 'c')
whirl_set(loc(2, 0));
else if(uni == 'd')
whirl_set(S3 == 3 ? loc(3, 0) : loc(1,1), texture_remap);
else if(uni == 'f' && (config == loc(1,1) ? show_bitrunc : (show_nonthree || (config.first-config.second)%3 == 0)))
whirl_set(config, texture_remap);
whirl_set(S3 == 3 ? loc(3, 0) : loc(1,1));
else if(uni == 'f')
whirl_set(config);
else if(uni == 'x')
dialog::editNumber(config.first, 0, 8, 1, 1, "x", helptext());
else if(uni == 'y')
@ -793,11 +778,11 @@ namespace hr { namespace gp {
else return loc(1,1);
}
void configure(bool texture_remap = false) {
void configure() {
auto l = univ_param();
param = l;
config = human_representation(l);
pushScreen([texture_remap] () { gp::show(texture_remap); });
pushScreen(gp::show);
}
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 mapTexture2(textureinfo& mi);
void finish_mapping();
void remap(eTextureState old_tstate, eTextureState old_tstate_max);
void true_remap();
void remap();
bool correctly_mapped;
hyperpoint texture_coordinates(hyperpoint);
void drawRawTexture();
@ -3262,7 +3264,7 @@ namespace gp {
extern string operation_name();
extern int pseudohept_val(cell *);
extern int last_dir(cell *c);
extern void configure(bool texture_remap);
extern void configure();
extern ld alpha;
extern transmatrix Tf[8][32][32][6];
@ -3845,5 +3847,7 @@ heptagon* encodeId(int id);
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;
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();
for(hrmap *& hm : allmaps) if(hm == base) hm = NULL;
stop_game();
@ -815,9 +811,6 @@ void start_game_on_created_map() {
need_reset_geometry = true;
gridmaking = false;
start_game();
#if CAP_TEXTURE
texture::config.remap(old_tstate, old_tstate_max);
#endif
}
bool save_map(const string& fname) {

View File

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

View File

@ -1169,12 +1169,6 @@ void switch_game_mode(char switchWhat) {
nonbitrunc = !nonbitrunc; irr::on = false;
gp::on = (switchWhat == rg::gp && !gp::on);
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;
case rg::geometry:
@ -1194,12 +1188,6 @@ void switch_game_mode(char switchWhat) {
if(geometry == gBinaryTiling) nonbitrunc = true, gp::on = irr::on = false;
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;
case rg::yendor:
@ -1284,6 +1272,9 @@ void start_game() {
restartGraph();
resetmusic();
resetmusic();
#if CAP_TEXTURE
texture::config.remap();
#endif
}
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) {
if(config.tstate == tsOff) return false;
if(config.tstate == tsOff || !correctly_mapped) return false;
using namespace patterns;
auto si = getpatterninfo0(c);
@ -453,10 +453,15 @@ void texture_config::perform_mapping() {
}
set<int> missing_cells_known;
void texture_config::finish_mapping() {
if(config.tstate == tsActive)
if(config.tstate == tsActive) {
for(auto& mi: texture_map)
mapTexture2(mi.second);
correctly_mapped = true;
missing_cells_known.clear();
}
patterns::computeCgroup();
texture::cgroup = patterns::cgroup;
@ -1412,55 +1417,64 @@ void drawLine(hyperpoint h1, hyperpoint h2, int col, int steps) {
drawPixel(h2, col);
}
void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_max) {
void texture_config::true_remap() {
drawthemap();
clear_texture_map();
if(old_tstate == tsActive && patterns::compatible(texture::cgroup, patterns::cgroup)) {
config.tstate = old_tstate;
config.tstate_max = old_tstate_max;
for(cell *c: dcal) {
auto si = patterns::getpatterninfo0(c);
int oldid = si.id;
si.id += goldbergcode(c, si);
missing_cells_known.clear();
for(cell *c: dcal) {
auto si = patterns::getpatterninfo0(c);
int oldid = si.id;
si.id += goldbergcode(c, si);
if(texture_map.count(si.id)) continue;
int pshift = 0;
if(texture::cgroup == cpSingle) oldid = 0;
if(texture::cgroup == cpFootball && patterns::cgroup == cpThree) {
if(si.id == 4) pshift = 1;
oldid = !si.id;
if(texture_map.count(si.id)) continue;
int pshift = 0;
if(texture::cgroup == cpSingle) oldid = 0;
if(texture::cgroup == cpFootball && patterns::cgroup == cpThree) {
if(si.id == 4) pshift = 1;
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& 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];
}
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&) {
auto& mi2 = texture_map[si.id];
mi2 = mi;
if(gp::on || irr::on) pshift += si.dir;
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&) {
if(missing_cells_known.count(si.id) == 0) {
missing_cells_known.insert(si.id);
printf("Unexpected missing cell #%d/%d\n", si.id, oldid);
addMessage(XLAT("Unexpected missing cell #%d/%d", its(si.id), its(oldid)));
config.tstate_max = config.tstate = tsAdjusting;
return;
addMessage(XLAT("Unexpected missing cell #%1/%1", its(si.id), its(oldid)));
}
}
// 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);
calcparam();
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() {
using namespace arg;
@ -1495,12 +1507,7 @@ int textureArgs() {
else if(argis("-txcl")) {
PHASE(3); drawscreen();
config.load();
old_tstate_cl = texture::config.tstate;
old_tstate_max_cl = texture::config.tstate_max;
}
else if(argis("-txremap")) {
texture::config.remap(old_tstate_cl, old_tstate_max_cl);
need_reset_geometry = true;
}
else return 1;