mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-04-09 20:26:45 +00:00
more detailed Euclidean embedding parameters
This commit is contained in:
parent
731fcee7ce
commit
2182f442d9
17
config.cpp
17
config.cpp
@ -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)
|
||||
|
38
geometry.cpp
38
geometry.cpp
@ -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));
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user