embeddings:: switching should now keep as much as possible

This commit is contained in:
Zeno Rogue 2023-02-10 19:04:32 +01:00
parent c2070a6fd6
commit fb2a3a7931
3 changed files with 98 additions and 35 deletions

View File

@ -840,16 +840,16 @@ EX void initConfig() {
param_f(geom3::euclid_embed_scale, "euclid_embed_scale", "euclid_embed_scale")
-> editable(0, 2, 0.05, "Euclidean embedding scale", "How to scale the Euclidean map, relatively to the 3D absolute unit.", 'X')
-> set_sets([] { dialog::bound_low(0.05); })
-> set_reaction([] { if(vid.always3) { for(auto m: allmaps) m->on_dim_change(); }});
-> set_reaction(geom3::apply_settings_full);
param_f(geom3::euclid_embed_scale_y, "euclid_embed_scale_y", "euclid_embed_scale_y")
-> editable(0, 2, 0.05, "Euclidean embedding scale Y/X", "This scaling factor affects only the Y coordinate.", 'Y')
-> set_sets([] { dialog::bound_low(0.05); })
-> set_reaction([] { if(vid.always3) { for(auto m: allmaps) m->on_dim_change(); }});
-> set_reaction(geom3::apply_settings_full);
param_f(geom3::euclid_embed_rotate, "euclid_embed_rotate", "euclid_embed_rotate")
-> editable(0, 360, 15, "Euclidean embedding rotation", "How to rotate the Euclidean embedding, in degrees.", 'F')
-> set_reaction([] { if(vid.always3) { for(auto m: allmaps) m->on_dim_change(); }});
-> set_reaction(geom3::apply_settings_full);
param_enum(embedded_shift_method_choice, "embedded_shift_method", "embedded_shift_method", smcBoth)
-> editable({
@ -863,23 +863,15 @@ EX void initConfig() {
param_b(geom3::inverted_embedding, "inverted_3d", false)
-> editable("invert convex/concave", 'I')
-> set_reaction([] { if(vid.always3) { geom3::switch_fpp(); geom3::switch_fpp(); } });
-> set_reaction(geom3::apply_settings_full);
param_b(geom3::flat_embedding, "flat_3d", false)
-> editable("flat, not equidistant", 'F')
-> set_reaction([] { if(vid.always3) { geom3::switch_fpp(); geom3::switch_fpp(); } });
-> set_reaction(geom3::apply_settings_full);
param_enum(geom3::spatial_embedding, "spatial_embedding", "spatial_embedding", geom3::seDefault)
->editable(geom3::spatial_embedding_options, "3D embedding method", 'E')
->set_reaction([] {
if(vid.always3) {
geom3::switch_fpp();
geom3::switch_fpp();
delete_sky();
// not sure why this is needed...
resetGL();
}
});
->set_reaction(geom3::apply_settings_full);
param_b(memory_saving_mode, "memory_saving_mode", (ISMOBILE || ISPANDORA || ISWEB) ? 1 : 0);
param_i(reserve_limit, "memory_reserve", 128);
@ -2280,7 +2272,7 @@ EX void display_embedded_errors() {
T0[1][0] = geometry == gEuclid ? 10 : 0;
euc::eu_input.twisted = false;
euc::build_torus3();
geom3::switch_fpp(); geom3::switch_fpp(); start_game(); }); });
geom3::apply_settings_full(); start_game(); }); });
return;
}
}
@ -2295,7 +2287,7 @@ EX void display_embedded_errors() {
T0[0][1] = T0[1][0] = T0[1][1] = 0;
euc::eu_input.twisted = false;
euc::build_torus3();
geom3::switch_fpp(); geom3::switch_fpp(); start_game(); }); });
geom3::apply_settings_full(); start_game(); }); });
return;
}
}
@ -2626,7 +2618,8 @@ EX int config3 = addHook(hooks_configfile, 100, [] {
"with parameter %2.", fts(current_camera_level), fts(tan_auto(vid.depth) / tan_auto(current_camera_level)));
}
dialog::addHelp(help);
});
})
->set_reaction(geom3::apply_settings_light);
param_f(vid.camera, "camera", "3D camera level", 1)
->editable(0, 5, .1, "", "", 'c')
->modif([] (float_setting* x) { x->menu_item_name = (GDIM == 2 ? "Camera level above the plane" : "Z shift"); })
@ -2660,7 +2653,8 @@ EX int config3 = addHook(hooks_configfile, 100, [] {
dialog::add_action([] () {
vid.gp_autoscale_heights = !vid.gp_autoscale_heights;
});
});
})
->set_reaction(geom3::apply_settings_light);
param_f(vid.rock_wall_ratio, "rock_wall_ratio", "3D rock-wall ratio", .9)
->editable(0, 1, .1, "Rock-III to wall ratio", "", 'r')
->set_extra([] { dialog::addHelp(XLAT(

View File

@ -1113,13 +1113,60 @@ void embedding_method::set_radar_transform() {
}
EX void swapmatrix(transmatrix& T) {
if(embedded_plane) T = swapper->emb->base_to_actual(T);
else T = swapper->emb->actual_to_base(T);
if(geom3::swap_direction == +1) T = cgi.emb->base_to_actual(T);
if(geom3::swap_direction == -1) T = cgi.emb->actual_to_base(T);
}
EX void swappoint(hyperpoint& h) {
if(embedded_plane) h = swapper->emb->base_to_actual(h);
else h = swapper->emb->actual_to_base(h);
if(geom3::swap_direction == +1) h = cgi.emb->base_to_actual(h);
if(geom3::swap_direction == -1) h = cgi.emb->actual_to_base(h);
}
struct embedded_matrix_data {
transmatrix saved;
hyperpoint logical_coordinates;
transmatrix rotation;
};
map<transmatrix*, embedded_matrix_data> mdata;
EX void swapmatrix_iview(transmatrix& ori, transmatrix& V) {
indenter id(2);
if(geom3::swap_direction == -1) {
auto& data = mdata[&V];
data.logical_coordinates = cgi.emb->intermediate_to_logical * cgi.emb->actual_to_intermediate(V*tile_center());
data.rotation = inverse(cgi.emb->map_relative_push(V*tile_center())) * V;
data.logical_coordinates[2] = ilerp(cgi.FLOOR, cgi.WALL, data.logical_coordinates[2]);
if(nisot::local_perspective_used) data.rotation = data.rotation * ori;
swapmatrix(V);
data.rotation = data.rotation * cgi.emb->logical_scaled_to_intermediate;
data.saved = V;
}
if(geom3::swap_direction == 1) {
if(!mdata.count(&V)) { swapmatrix(V); ori = Id; return; }
auto& data = mdata[&V];
if(!eqmatrix(data.saved, V)) { swapmatrix(V); ori = Id; return; }
data.logical_coordinates[2] = lerp(cgi.FLOOR, cgi.WALL, data.logical_coordinates[2]);
V = cgi.emb->intermediate_to_actual_translation( cgi.emb->logical_to_intermediate * data.logical_coordinates );
ori = Id;
auto rot = data.rotation;
rot = rot * cgi.emb->intermediate_to_logical_scaled;
if(nisot::local_perspective_used) ori = ori * rot;
else V = V * rot;
}
}
EX void swapmatrix_view(transmatrix& lp, transmatrix& V) {
if(!geom3::swap_direction) return;
if(geom3::swap_direction == +1) fix4(V);
V = inverse(V);
lp = inverse(lp);
swapmatrix_iview(lp, V);
if(geom3::swap_direction == -1) fix4(V);
V = inverse(V);
lp = inverse(lp);
}
void embedding_method::auto_configure() {

View File

@ -1070,17 +1070,28 @@ EX namespace geom3 {
EX namespace geom3 {
/** direction of swapping: +1 => from 2D to 3D; -1 => from 3D to 2D; 0 => make everything right */
EX int swap_direction;
EX void swapdim(int dir) {
swap_direction = dir;
decide_lpu();
swapmatrix_view(NLP, View);
swapmatrix_view(NLP, current_display->which_copy);
callhooks(hooks_swapdim);
for(auto m: allmaps) m->on_dim_change();
}
#if MAXMDIM >= 4
EX void switch_always3() {
if(dual::split(switch_always3)) return;
#if CAP_GL && CAP_RUG
if(rug::rugged) rug::close();
#endif
swapper = &cgi;
if(vid.always3) swapdim(-1);
vid.always3 = !vid.always3;
apply_always3();
swapmatrix(View);
callhooks(hooks_swapdim);
if(vid.always3) swapdim(+1);
}
#endif
@ -1121,14 +1132,10 @@ EX namespace geom3 {
emb->auto_configure();
check_cgi();
cgi.prepare_basics();
swapper = &cgi;
swapmatrix(View);
swapmatrix(current_display->which_copy);
callhooks(hooks_swapdim);
for(auto m: allmaps) m->on_dim_change();
swapdim(+1);
}
else {
swapper = &cgi;
swapdim(-1);
vid.always3 = false;
apply_always3();
vid.wall_height = .3;
@ -1136,15 +1143,30 @@ EX namespace geom3 {
vid.camera = 1;
vid.depth = 1;
if(among(pmodel, mdPerspective, mdGeodesic)) pmodel = mdDisk;
swapmatrix(View);
swapmatrix(current_display->which_copy);
callhooks(hooks_swapdim);
for(auto m: allmaps) m->on_dim_change();
swapdim(0);
}
View = models::rotmatrix() * View;
#endif
}
EX void apply_settings_full() {
if(vid.always3) {
geom3::switch_fpp();
delete_sky();
// not sure why this is needed...
resetGL();
geom3::switch_fpp();
}
}
EX void apply_settings_light() {
if(vid.always3) {
geom3::switch_always3();
check_cgi(); cgi.prepare_basics();
geom3::switch_always3();
}
}
EX }
EX geometry_information *cgip;