mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
rots:: show the underlying geometry
This commit is contained in:
parent
e600c0af0a
commit
f8963a1c75
19
geom-exp.cpp
19
geom-exp.cpp
@ -709,7 +709,24 @@ EX void showEuclideanMenu() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(euwrap || geometry == gFieldQuotient || cryst || archimedean || (euclid && WDIM == 3)) {
|
else if(geometry == gRotSpace) {
|
||||||
|
constexpr auto& r = rots::underlying_scale;
|
||||||
|
dialog::addSelItem(XLAT("view the underlying geometry"), r > 0 ? fts(r)+"x" : "NO", '4');
|
||||||
|
dialog::add_action([] {
|
||||||
|
dialog::editNumber(r, 0, 1, 0.05, 0.25, XLAT("view the underlying geometry"),
|
||||||
|
XLAT(
|
||||||
|
"The space you are currently in the space of rotations of the underlying hyperbolic or spherical geometry. "
|
||||||
|
"This option lets you see the underlying space. Lands and some walls (e.g. in the Graveyard) are based on "
|
||||||
|
"the respective features in the underlying world, but details such as monsters or items are ignored."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
dialog::bound_low(0);
|
||||||
|
dialog::bound_up(1);
|
||||||
|
dialog::extra_options = [] () { rots::draw_underlying(true); };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(euwrap || geometry == gFieldQuotient || cryst || archimedean || (euclid && WDIM == 3)) {
|
||||||
dialog::addItem(XLAT("advanced parameters"), '4');
|
dialog::addItem(XLAT("advanced parameters"), '4');
|
||||||
dialog::add_action([] {
|
dialog::add_action([] {
|
||||||
if(0);
|
if(0);
|
||||||
|
14
graph.cpp
14
graph.cpp
@ -7531,6 +7531,8 @@ EX bool dronemode;
|
|||||||
|
|
||||||
purehookset hooks_calcparam;
|
purehookset hooks_calcparam;
|
||||||
|
|
||||||
|
EX int corner_centering;
|
||||||
|
|
||||||
EX void calcparam() {
|
EX void calcparam() {
|
||||||
|
|
||||||
DEBBI(DF_GRAPH, ("calc param"));
|
DEBBI(DF_GRAPH, ("calc param"));
|
||||||
@ -7571,11 +7573,21 @@ EX void calcparam() {
|
|||||||
if(GDIM == 3 && in_perspective()) cd->radius = cd->scrsize;
|
if(GDIM == 3 && in_perspective()) cd->radius = cd->scrsize;
|
||||||
realradius = min(realradius, cd->radius);
|
realradius = min(realradius, cd->radius);
|
||||||
|
|
||||||
|
ld aradius = sphere ? cd->radius / (vid.alpha - 1) : cd->radius;
|
||||||
|
|
||||||
if(dronemode) { cd->ycenter -= cd->radius; cd->ycenter += vid.fsize/2; cd->ycenter += vid.fsize/2; cd->radius *= 2; }
|
if(dronemode) { cd->ycenter -= cd->radius; cd->ycenter += vid.fsize/2; cd->ycenter += vid.fsize/2; cd->radius *= 2; }
|
||||||
|
|
||||||
|
if(corner_centering) {
|
||||||
|
cd->ycenter = cd->ytop + cd->ysize - vid.fsize - aradius;
|
||||||
|
if(corner_centering == 1)
|
||||||
|
cd->xcenter = cd->xtop + vid.fsize + aradius;
|
||||||
|
if(corner_centering == 2)
|
||||||
|
cd->xcenter = cd->xtop + cd->xsize - vid.fsize - aradius;
|
||||||
|
}
|
||||||
|
|
||||||
cd->xcenter += cd->scrsize * vid.xposition;
|
cd->xcenter += cd->scrsize * vid.xposition;
|
||||||
cd->ycenter += cd->scrsize * vid.yposition;
|
cd->ycenter += cd->scrsize * vid.yposition;
|
||||||
|
|
||||||
cd->tanfov = tan(vid.fov * degree / 2);
|
cd->tanfov = tan(vid.fov * degree / 2);
|
||||||
|
|
||||||
if(pmodel)
|
if(pmodel)
|
||||||
|
8
hud.cpp
8
hud.cpp
@ -481,6 +481,10 @@ EX void drawStats() {
|
|||||||
first_cell_to_draw = true;
|
first_cell_to_draw = true;
|
||||||
bool h = hide_player();
|
bool h = hide_player();
|
||||||
|
|
||||||
|
bool cornermode = (vid.xres > vid.yres * 85/100 && vid.yres > vid.xres * 85/100);
|
||||||
|
|
||||||
|
if(geometry == gRotSpace) rots::draw_underlying(!cornermode);
|
||||||
|
|
||||||
{
|
{
|
||||||
dynamicval<eModel> pm(pmodel, flat_model());
|
dynamicval<eModel> pm(pmodel, flat_model());
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
@ -492,9 +496,7 @@ EX void drawStats() {
|
|||||||
if(prod) vid.alpha = 30, vid.scale = 30;
|
if(prod) vid.alpha = 30, vid.scale = 30;
|
||||||
|
|
||||||
calcparam();
|
calcparam();
|
||||||
|
|
||||||
bool cornermode = (vid.xres > vid.yres * 85/100 && vid.yres > vid.xres * 85/100);
|
|
||||||
|
|
||||||
if(vid.radarsize > 0 && h)
|
if(vid.radarsize > 0 && h)
|
||||||
#if CAP_RACING
|
#if CAP_RACING
|
||||||
if(!racing::on)
|
if(!racing::on)
|
||||||
|
@ -1217,6 +1217,89 @@ EX namespace rots {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** reinterpret the given point of rotspace as a rotation matrix in the underlying geometry */
|
||||||
|
EX transmatrix qtm(hyperpoint h) {
|
||||||
|
if(hyperbolic) {
|
||||||
|
hyperpoint k = slr::to_phigans(h);
|
||||||
|
ld z = k[2]; k[2] = 0;
|
||||||
|
ld r = hypot_d(2, k);
|
||||||
|
// k[1] = -k[1];
|
||||||
|
k[0] = -k[0];
|
||||||
|
if(r) k = tangent_length(k, asinh(r) * 2);
|
||||||
|
return spin(-z * 2) * rgpushxto0(direct_exp(k, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
double sq0 = h[0]*h[0];
|
||||||
|
double sq1 = h[1]*h[1];
|
||||||
|
double sq2 = h[2]*h[2];
|
||||||
|
double sq3 = h[3]*h[3];
|
||||||
|
|
||||||
|
transmatrix M;
|
||||||
|
|
||||||
|
M[0][0] = sq0 - sq1 - sq2 + sq3;
|
||||||
|
M[1][1] = -sq0 + sq1 - sq2 + sq3;
|
||||||
|
M[2][2] = -sq0 - sq1 + sq2 + sq3;
|
||||||
|
|
||||||
|
double tmp1 = h[0]*h[1];
|
||||||
|
double tmp2 = h[2]*h[3];
|
||||||
|
M[0][1] = -2 * (tmp1 + tmp2);
|
||||||
|
M[1][0] = -2 * (tmp1 - tmp2);
|
||||||
|
|
||||||
|
tmp1 = h[0]*h[2];
|
||||||
|
tmp2 = h[1]*h[3];
|
||||||
|
M[0][2] = 2 * (tmp1 - tmp2);
|
||||||
|
M[2][0] = 2 * (tmp1 + tmp2);
|
||||||
|
|
||||||
|
tmp1 = h[1]*h[2];
|
||||||
|
tmp2 = h[0]*h[3];
|
||||||
|
M[1][2] = -2 * (tmp1 + tmp2);
|
||||||
|
M[2][1] = -2 * (tmp1 - tmp2);
|
||||||
|
|
||||||
|
return M;
|
||||||
|
}
|
||||||
|
|
||||||
|
EX ld underlying_scale = 0;
|
||||||
|
|
||||||
|
EX void draw_underlying(bool cornermode) {
|
||||||
|
if(underlying_scale <= 0) return;
|
||||||
|
ld d = hybrid::current_view_level;
|
||||||
|
d *= cgi.plevel;
|
||||||
|
transmatrix T = rots::uzpush(-d) * spin(-2*d);
|
||||||
|
|
||||||
|
if(det(T) < 0) T = centralsym * T;
|
||||||
|
|
||||||
|
hyperpoint h = inverse(View * spin(master_to_c7_angle()) * T) * C0;
|
||||||
|
|
||||||
|
auto g = std::move(gmatrix);
|
||||||
|
auto g0 = std::move(gmatrix0);
|
||||||
|
|
||||||
|
hybrid::in_underlying_map([&] {
|
||||||
|
cgi.require_shapes();
|
||||||
|
dynamicval<int> pcc(corner_centering, cornermode ? 1 : 2);
|
||||||
|
dynamicval<bool> pf(playerfound, true);
|
||||||
|
dynamicval<cellwalker> m5(centerover, viewctr.at->c7);
|
||||||
|
dynamicval<transmatrix> m2(View, ypush(0) * qtm(h));
|
||||||
|
dynamicval<transmatrix> m3(playerV, Id);
|
||||||
|
dynamicval<transmatrix> m4(actual_view_transform, Id);
|
||||||
|
dynamicval<eModel> pm(pmodel, mdDisk);
|
||||||
|
dynamicval<ld> pss(vid.scale, (sphere ? 10 : 1) * underlying_scale);
|
||||||
|
dynamicval<ld> psa(vid.alpha, sphere ? 10 : 1);
|
||||||
|
dynamicval<hrmap*> p(hybrid::pmap, NULL);
|
||||||
|
dynamicval<int> psr(sightrange_bonus, 0);
|
||||||
|
calcparam();
|
||||||
|
reset_projection(); current_display->set_all(0);
|
||||||
|
ptds.clear();
|
||||||
|
drawthemap();
|
||||||
|
drawqueue();
|
||||||
|
displaychr(current_display->xcenter, current_display->ycenter, 0, 24, '+', 0xFFFFFFFF);
|
||||||
|
glflush();
|
||||||
|
});
|
||||||
|
gmatrix = std::move(g);
|
||||||
|
gmatrix0 = std::move(g0);
|
||||||
|
calcparam();
|
||||||
|
reset_projection(); current_display->set_all(0);
|
||||||
|
}
|
||||||
|
|
||||||
EX }
|
EX }
|
||||||
|
|
||||||
EX namespace nisot {
|
EX namespace nisot {
|
||||||
@ -1370,6 +1453,11 @@ EX namespace nisot {
|
|||||||
set_geometry(gRotSpace);
|
set_geometry(gRotSpace);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if(argis("-rot_uscale")) {
|
||||||
|
PHASEFROM(2);
|
||||||
|
shift_arg_formula(rots::underlying_scale);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user