diff --git a/euclid.cpp b/euclid.cpp index 88dc6b5e..e723d41c 100644 --- a/euclid.cpp +++ b/euclid.cpp @@ -240,6 +240,7 @@ EX namespace euc { } transmatrix adj(cell *c, int i) override { + if(dont_inverse()) return adj(c->master, i); if(WDIM == 3) return adj(c->master, i); else return hrmap_standard::adj(c, i); } diff --git a/floorshapes.cpp b/floorshapes.cpp index 8695c540..7197d76a 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -346,7 +346,7 @@ void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, ld hpcpush(xspinpush0(-M_PI/sides, size)); chasmifyPoly(dlow_table[k], dhi_table[k], k); - if(geom3::euc_in_nil()) { + if(geom3::euc_in_noniso()) { fsh.gpside[k].resize(c->type); for(int i=0; itype; i++) { sizeto(fsh.gpside[k][i], id); diff --git a/geometry.cpp b/geometry.cpp index 9d830d1a..77687ca1 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -771,7 +771,7 @@ void geometry_information::prepare_basics() { scalefactor *= exp(-vid.depth); } - if(geom3::euc_in_nil()) scalefactor *= geom3::euclid_embed_scale; + if(geom3::euc_in_noniso()) scalefactor *= geom3::euclid_embed_scale; if(geom3::sph_in_euc()) scalefactor *= (1 + vid.depth); if(geom3::sph_in_hyp()) scalefactor *= sinh(1 + vid.depth); @@ -1022,7 +1022,7 @@ EX namespace geom3 { reduce = (GDIM == 3 ? human_height * .3 : 0); int sgn = vid.wall_height > 0 ? 1 : -1; - ld ees = geom3::euc_in_nil() ? geom3::euclid_embed_scale : 1; + ld ees = geom3::euc_in_noniso() ? geom3::euclid_embed_scale : 1; STUFF = lev_to_factor(0) - sgn * max(orbsize * ees * 0.3, zhexf * ees * .6); @@ -1080,7 +1080,9 @@ EX namespace geom3 { seMuchLowerCurvature, seMuchLowerCurvatureInverted, seProduct, - seNil + seNil, + seSol, seNIH, seSolN, + seNIH_inv }; #endif @@ -1093,7 +1095,11 @@ EX namespace geom3 { {"much lower curvature", "Embed sphere as a convex sphere in hyperbolic space."}, {"much lower curvature inverted", "Embed sphere as a concave sphere in hyperbolic space."}, {"product", "Add one extra dimension in the Euclidean way."}, - {"Nil", "Embed into Nil. Works only with Euclidean."}, + {"Nil", "Embed into Nil. Works only with Euclidean. You need to set the variation to Pure."}, + {"Sol", "Embed into Sol. Works only with Euclidean. You need to set the variation to Pure."}, + {"stretched hyperbolic", "Embed into stretched hyperbolic geometry. Works only with Euclidean. You need to set the variation to Pure."}, + {"stretched Sol", "Embed into stretched Sol geometry. Works only with Euclidean. You need to set the variation to Pure."}, + {"stretched hyperbolic inverted", "Embed into stretched hyperbolic geometry as a concave horosphere. Works only with Euclidean. You need to set the variation to Pure."}, }; EX eSpatialEmbedding spatial_embedding; @@ -1117,6 +1123,14 @@ EX namespace geom3 { return ggclass() == gcNil && mgclass() == gcEuclid; } + EX bool euc_in_solnih() { + return among(ggclass(), gcSol, gcNIH, gcSolN) && mgclass() == gcEuclid; + } + + EX bool euc_in_noniso() { + return among(ggclass(), gcNil, gcSol, gcNIH, gcSolN) && nonisotropic; + } + EX bool sph_in_euc() { return ggclass() == gcEuclid && mgclass() == gcSphere; } @@ -1189,6 +1203,26 @@ EX namespace geom3 { g = ginf[gNil].g; g.gameplay_dimension = 2; } + + if(spatial_embedding == seSol && euclid) { + g = ginf[gSol].g; + g.gameplay_dimension = 2; + } + + if(spatial_embedding == seNIH && euclid) { + g = ginf[gNIH].g; + g.gameplay_dimension = 2; + } + + if(spatial_embedding == seNIH_inv && euclid) { + g = ginf[gNIH].g; + g.gameplay_dimension = 2; + } + + if(spatial_embedding == seSolN && euclid) { + g = ginf[gSolN].g; + g.gameplay_dimension = 2; + } } } } @@ -1278,6 +1312,10 @@ EX void switch_always3() { vid.wall_height *= -1; vid.eye = 2 * vid.depth; } + if(euc_in_noniso() && spatial_embedding == seNIH_inv) { + vid.wall_height *= -1; + vid.eye = 2 * vid.depth; + } if(msphere && spatial_embedding == seProduct) { vid.depth = 0; vid.wall_height = 2; diff --git a/geometry2.cpp b/geometry2.cpp index 9ddd3b86..74bda0fd 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -442,7 +442,7 @@ EX bool no_easy_spin() { return NONSTDVAR || arcm::in() || WDIM == 3 || bt::in() || kite::in(); } -EX bool dont_inverse() { return geometry == 1 && PURE && geom3::euc_in_nil(); } +EX bool dont_inverse() { return geometry == 1 && PURE && geom3::euc_in_noniso(); } ld hrmap_standard::spin_angle(cell *c, int d) { if(WDIM == 3) return SPIN_NOT_AVAILABLE; diff --git a/graph.cpp b/graph.cpp index 4b7b045b..8561a9c1 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3490,7 +3490,7 @@ EX int countMinesAround(cell *c) { } EX transmatrix applyPatterndir(cell *c, const patterns::patterninfo& si) { - if(NONSTDVAR || bt::in() || geom3::euc_in_nil()) return Id; + if(NONSTDVAR || bt::in() || geom3::euc_in_noniso()) return Id; transmatrix V = ddspin180(c, si.dir); if(si.reflect) V = V * lmirror(); if(euclid) return V; @@ -3749,7 +3749,7 @@ EX bool placeSidewall(cell *c, int i, int sidepar, const shiftmatrix& V, color_t else if(sidepar == SIDE_BSHA) prio = PPR::BSHALLOW; else prio = PPR::REDWALL-2+4*(sidepar-SIDE_SLEV); - if(geom3::euc_in_nil()) { + if(geom3::euc_in_noniso()) { draw_shapevec(c, V, qfi.fshape->gpside[sidepar][i], col, prio); return false; } diff --git a/hyperpoint.cpp b/hyperpoint.cpp index 994c6eb2..57d6ba77 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -560,6 +560,7 @@ EX hyperpoint normalize_flat(hyperpoint h) { if(gproduct) return product_decompose(h).second; if(sl2) h = slr::translate(h) * zpush0(-atan2(h[2], h[3])); if(geom3::euc_in_nil()) h[1] = 0; + if(geom3::euc_in_solnih()) h[2] = 0; if(geom3::euc_in_hyp()) { h = normalize(h); auto h1 = deparabolic13(h); @@ -792,6 +793,9 @@ EX hyperpoint orthogonal_move(const hyperpoint& h, ld z) { if(geom3::euc_in_nil()) { return nisot::translate(h) * cpush0(1, z); } + if(geom3::euc_in_solnih()) { + return nisot::translate(h) * cpush0(2, z); + } if(geom3::sph_in_euc()) { ld z0 = hypot_d(3, h); ld f = ((z0 + z) / z0); @@ -868,6 +872,13 @@ EX void swapmatrix(transmatrix& T) { T = eupush(hyperpoint(h1[0] * geom3::euclid_embed_scale, 0, h1[1] * geom3::euclid_embed_scale, 1)); } } + else if(geom3::euc_in_solnih()) { + if(!geom3::flipped) { + hyperpoint h1 = T * C02; + // rotations are illegal anyway... + T = eupush(hyperpoint(h1[0] * geom3::euclid_embed_scale, h1[1] * geom3::euclid_embed_scale, 0, 1)); + } + } else if(geom3::in_product()) { /* just do nothing */ } @@ -889,6 +900,7 @@ EX void swapmatrix(hyperpoint& h) { 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_solnih()) { h[3] = 1; h[1] = h[1] * geom3::euclid_embed_scale; h[2] = 0; h[0] *= geom3::euclid_embed_scale; return; } swap(h[2], h[3]); if(GDIM == 3) h[2] = 0; if(geom3::euc_in_hyp()) h = parabolic13(h[0], h[1]) * C0;