more detailed Euclidean embedding parameters

This commit is contained in:
Zeno Rogue 2023-01-05 14:01:23 +01:00
parent 731fcee7ce
commit 2182f442d9
5 changed files with 66 additions and 30 deletions

View File

@ -838,10 +838,19 @@ EX void initConfig() {
addsaver(vid.always3, "3D always", false);
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.", 'F')
-> 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) { geom3::switch_fpp(); geom3::switch_fpp(); } });
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) { geom3::switch_fpp(); geom3::switch_fpp(); } });
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) { geom3::switch_fpp(); geom3::switch_fpp(); } });
param_enum(embedded_shift_method_choice, "embedded_shift_method", "embedded_shift_method", smcBoth)
-> editable({
{"geodesic", "always move on geodesics"},
@ -2316,7 +2325,11 @@ EX void show3D() {
}
if(WDIM == 2) {
if(geom3::euc_in_noniso()) add_edit(geom3::euclid_embed_scale);
if(geom3::euc_in_noniso()) {
add_edit(geom3::euclid_embed_scale);
add_edit(geom3::euclid_embed_scale_y);
add_edit(geom3::euclid_embed_rotate);
}
add_edit(embedded_shift_method_choice);
add_edit(vid.camera);
if(GDIM == 3)

View File

@ -200,6 +200,12 @@ struct geometry_information {
int base_distlimit;
/* convert the tangent space in logical coordinates to actual coordinates */
transmatrix logical_to_actual;
/* convert the tangent space in actual coordinates to logical coordinates */
transmatrix actual_to_logical;
/** size of the Sword (from Orb of the Sword), used in the shmup mode */
ld sword_size;
/** scale factor for the graphics of most things*/
@ -440,6 +446,8 @@ hpcshape
void prepare_shapes();
void prepare_usershapes();
void prepare_lta();
void hpcpush(hyperpoint h);
void hpc_connect_ideal(hyperpoint a, hyperpoint b);
void hpcsquare(hyperpoint h1, hyperpoint h2, hyperpoint h3, hyperpoint h4);
@ -577,6 +585,21 @@ EX bool is_reg3_variation(eVariation var) {
return var == eVariation::coxeter;
}
void geometry_information::prepare_lta() {
auto& lta = logical_to_actual;
lta = Id;
if(embedded_plane) {
if(geom3::euc_in_noniso()) {
lta[0][0] *= geom3::euclid_embed_scale;
lta[1][1] *= geom3::euclid_embed_scale * geom3::euclid_embed_scale_y;
lta = cspin(0, 1, geom3::euclid_embed_rotate * degree) * lta;
}
if(geom3::euc_in_nil()) lta = cspin90(2, 1) * lta;
if(geom3::hyp_in_solnih()) lta = cspin90(0, 1) * cspin90(1, 2) * cspin90(0, 1) * lta;
}
actual_to_logical = inverse(lta);
}
void geometry_information::prepare_basics() {
DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("prepare_basics"));
@ -593,6 +616,8 @@ void geometry_information::prepare_basics() {
xp_order = 0;
prepare_lta();
if(arcm::in() && !mproduct)
ginf[gArchimedean].cclass = gcHyperbolic;
@ -1023,7 +1048,7 @@ EX namespace geom3 {
reduce = (GDIM == 3 ? human_height * .3 : 0);
int sgn = vid.wall_height > 0 ? 1 : -1;
ld ees = geom3::euc_in_noniso() ? geom3::euclid_embed_scale : 1;
ld ees = geom3::euc_in_noniso() ? geom3::euclid_embed_scale_mean() : 1;
STUFF = lev_to_factor(0) - sgn * max(orbsize * ees * 0.3, zhexf * ees * .6);
@ -1099,10 +1124,15 @@ EX namespace geom3 {
EX eSpatialEmbedding spatial_embedding = seDefault;
EX ld euclid_embed_scale = 1;
EX ld euclid_embed_scale_y = 1;
EX ld euclid_embed_rotate = 0;
EX bool auto_configure = true;
EX bool flat_embedding = false;
EX bool inverted_embedding = false;
EX ld euclid_embed_scale_mean() { return euclid_embed_scale * sqrt(euclid_embed_scale_y); }
EX void set_euclid_embed_scale(ld x) { euclid_embed_scale = x; euclid_embed_scale_y = 1; euclid_embed_rotate = 0; }
EX bool supports_flat() { return spatial_embedding == seDefault; }
EX bool supports_invert() { return among(spatial_embedding, seDefault, seLowerCurvature, seMuchLowerCurvature, seNil, seSol, seNIH, seSolN); }
@ -1480,7 +1510,11 @@ EX string cgi_string() {
if(embedded_plane) V("X:", its(geom3::ggclass()));
if(embedded_plane && meuclid) V("XS:", fts(geom3::euclid_embed_scale));
if(embedded_plane && meuclid) {
V("XS:", fts(geom3::euclid_embed_scale));
V("YS:", fts(geom3::euclid_embed_scale_y));
V("RS:", fts(geom3::euclid_embed_rotate));
}
if(scale_used()) V("CS", fts(vid.creature_scale));

View File

@ -5099,13 +5099,13 @@ EX void make_actual_view() {
transmatrix T = actual_view_transform * View;
ld z = -tC0(view_inverse(T)) [2];
transmatrix R = actual_view_transform;
R = (logical_to_actual()) * R;
R = cgi.logical_to_actual * R;
if(R[1][2] || R[2][2])
R = cspin(1, 2, -atan2(R[1][2], R[2][2])) * R;
if(R[0][2] || R[2][2])
R = cspin(0, 2, -atan2(R[0][2], R[2][2])) * R;
if(geom3::hyp_in_solnih()) R = Id;
R = inverse(logical_to_actual()) * R;
R = cgi.actual_to_logical * R;
current_display->radar_transform = inverse(R) * zpush(-z);
}
else if(gproduct) {

View File

@ -665,14 +665,8 @@ EX transmatrix spin(ld alpha) {
return cspin(0, 1, alpha);
}
EX transmatrix logical_to_actual() {
if(embedded_plane && geom3::euc_in_nil()) return cspin90(2, 1);
if(embedded_plane && geom3::hyp_in_solnih()) return cspin90(0, 1) * cspin90(1, 2) * cspin90(0, 1);
return Id;
}
EX transmatrix unswap_spin(transmatrix T) {
return ortho_inverse(logical_to_actual()) * T * logical_to_actual();
return cgi.actual_to_logical * T * cgi.logical_to_actual;
}
/** rotate by 90 degrees in the XY plane */
@ -896,11 +890,6 @@ EX transmatrix matrix4(ld a, ld b, ld c, ld d, ld e, ld f, ld g, ld h, ld i, ld
#endif
}
EX void euc_in_sph_rescale(hyperpoint& h) {
h[0] *= TAU * geom3::euclid_embed_scale;
h[1] *= TAU * geom3::euclid_embed_scale;
}
#if MAXMDIM >= 4
/** Transform a matrix between the 'embedded_plane' and underlying representation. Switches to the current variant. */
EX void swapmatrix(transmatrix& T) {
@ -926,17 +915,17 @@ EX void swapmatrix(transmatrix& T) {
}
else if(geom3::euc_in_nil()) {
if(!geom3::flipped) {
hyperpoint h1 = get_column(T, 2);
hyperpoint h1 = cgi.logical_to_actual * get_column(T, 2);
// rotations are illegal anyway...
T = eupush(hyperpoint(h1[0] * geom3::euclid_embed_scale, 0, h1[1] * geom3::euclid_embed_scale, 1));
T = eupush(hyperpoint(h1[0], 0, h1[2], 1));
return;
}
}
else if(geom3::euc_in_solnih()) {
if(!geom3::flipped) {
hyperpoint h1 = get_column(T, 2);
hyperpoint h1 = cgi.logical_to_actual * get_column(T, 2);
// rotations are illegal anyway...
T = eupush(hyperpoint(h1[0] * geom3::euclid_embed_scale, h1[1] * geom3::euclid_embed_scale, 0, 1));
T = eupush(hyperpoint(h1[0], h1[1], 0, 1));
return;
}
}
@ -944,8 +933,7 @@ EX void swapmatrix(transmatrix& T) {
/* just do nothing */
}
else if(geom3::euc_in_sph()) {
hyperpoint h1 = get_column(T, 2);
euc_in_sph_rescale(h1);
hyperpoint h1 = cgi.logical_to_actual * get_column(T, 2);
T = cspin(0, 2, h1[0]) * cspin(1, 3, h1[1]);
}
else {
@ -965,12 +953,13 @@ EX void swapmatrix(hyperpoint& h) {
if(geom3::in_product()) return;
if(geom3::sph_in_euc()) { h[3] = 1; return; }
if(geom3::sph_in_hyp()) { h[0] *= sinh(1); h[1] *= sinh(1); h[2] *= sinh(1); h[3] = cosh(1); return; }
if(geom3::euc_in_nil()) { h[3] = 1; h[2] = h[1] * geom3::euclid_embed_scale; h[1] = 0; h[0] *= geom3::euclid_embed_scale; return; }
if(geom3::euc_in_nil()) { h = cgi.logical_to_actual * h; h[3] = 1; h[1] = 0; return; }
if(geom3::euc_in_sph()) {
euc_in_sph_rescale(h); h = cspin(0, 2, h[0]) * cspin(1, 3, h[1]) * lzpush(1) * C0;
h = cgi.logical_to_actual * h;
h = cspin(0, 2, h[0]) * cspin(1, 3, h[1]) * lzpush(1) * C0;
return;
}
if(geom3::euc_in_solnih()) { h[3] = 1; h[1] = h[1] * geom3::euclid_embed_scale; h[2] = 0; h[0] *= geom3::euclid_embed_scale; return; }
if(geom3::euc_in_solnih()) { h = cgi.logical_to_actual * h; h[3] = 1; h[2] = 0; return; }
if(geom3::hyp_in_solnih()) {
// copied from deparabolic13
h /= (1 + h[2]);

View File

@ -2036,11 +2036,11 @@ EX void adjust_eye(transmatrix& T, cell *c, ld sign) {
/** achieve top-down perspective */
EX transmatrix default_spin() {
return cspin90(0, 1) * inverse(logical_to_actual());
return cspin90(0, 1) * cgi.actual_to_logical;
}
EX void centerpc(ld aspd) {
if(subscreens::split([=] () {centerpc(aspd);})) return;
if(dual::split([=] () { centerpc(aspd); })) return;
@ -2239,7 +2239,7 @@ EX void resetview() {
if(WDIM == 2) View = spin(M_PI + vid.fixed_facing_dir * degree) * View;
if(WDIM == 3 && !gproduct) View = cspin90(0, 2) * View;
if(gproduct) NLP = cspin90(0, 2);
View = inverse(logical_to_actual()) * View;
View = cgi.actual_to_logical * View;
if(embedded_plane) get_view_orientation() = cspin90(1, 2) * get_view_orientation();
if(embedded_plane && vid.wall_height < 0) View = cspin180(0, 1) * View;