1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-05-28 20:14:06 +00:00

fully turnable product spaces

This commit is contained in:
Zeno Rogue 2019-08-18 01:31:37 +02:00
parent 52f19a26a8
commit 00f4f4fca5
10 changed files with 63 additions and 35 deletions

View File

@ -400,8 +400,13 @@ void display_data::set_projection(int ed) {
if(pers3) { if(pers3) {
glhr::projection_multiply(glhr::frustum(current_display->tanfov, current_display->tanfov * cd->ysize / cd->xsize)); glhr::projection_multiply(glhr::frustum(current_display->tanfov, current_display->tanfov * cd->ysize / cd->xsize));
glhr::projection_multiply(glhr::scale(1, -1, -1)); glhr::projection_multiply(glhr::scale(1, -1, -1));
if(nisot::local_perspective_used()) if(nisot::local_perspective_used()) {
if(prod) {
for(int i=0; i<3; i++) nisot::local_perspective[3][i] = nisot::local_perspective[i][3] = 0;
nisot::local_perspective[3][3] = 1;
}
glhr::projection_multiply(glhr::tmtogl_transpose(nisot::local_perspective)); glhr::projection_multiply(glhr::tmtogl_transpose(nisot::local_perspective));
}
} }
else if(GDIM == 3) { else if(GDIM == 3) {
glhr::glmatrix M = glhr::ortho(cd->xsize/current_display->radius/2, -cd->ysize/current_display->radius/2, 1); glhr::glmatrix M = glhr::ortho(cd->xsize/current_display->radius/2, -cd->ysize/current_display->radius/2, 1);

View File

@ -70,11 +70,13 @@ EX bool mouseout2() {
return outofmap(mouseh) || outofmap(mouseoh); return outofmap(mouseh) || outofmap(mouseoh);
} }
EX movedir vectodir(const hyperpoint& P) { EX movedir vectodir(hyperpoint P) {
transmatrix U = ggmatrix(cwt.at); transmatrix U = ggmatrix(cwt.at);
if(GDIM == 3 && WDIM == 2) U = radar_transform * U; if(GDIM == 3 && WDIM == 2) U = radar_transform * U;
if(nisot::local_perspective_used()) U = nisot::local_perspective * U;
if(nisot::local_perspective_used()) P = inverse(nisot::local_perspective) * P;
if(prod) P = product::direct_exp(P);
hyperpoint H = sphereflip * tC0(U); hyperpoint H = sphereflip * tC0(U);
transmatrix Centered = sphereflip * rgpushxto0(H); transmatrix Centered = sphereflip * rgpushxto0(H);
@ -111,13 +113,12 @@ EX void remission() {
} }
EX hyperpoint move_destination_vec(int d) { EX hyperpoint move_destination_vec(int d) {
hyperpoint Forward = prod ? hpxy3(1,0,0) : tC0(pushone());
if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone()); if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
// else if(WDIM == 2 && pmodel == mdPerspective) return cspin(0, 2, d * M_PI/4) * tC0(pushone()); // else if(WDIM == 2 && pmodel == mdPerspective) return cspin(0, 2, d * M_PI/4) * tC0(pushone());
// else if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone()); // else if(WDIM == 2) return spin(-d * M_PI/4) * tC0(pushone());
else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * tC0(pushone()); else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * Forward;
else if(prod && d == 6) return zshift(C0, product::plevel); else return cspin(0, 2, d * M_PI/4) * Forward;
else if(prod && d == 2) return zshift(C0, -product::plevel);
else return cspin(0, 2, d * M_PI/4) * tC0(pushone());
} }
EX void movepckeydir(int d) { EX void movepckeydir(int d) {
@ -284,28 +285,31 @@ typedef SDL_Event eventtype;
EX bool smooth_scrolling = false; EX bool smooth_scrolling = false;
EX void handlePanning(int sym, int uni) { EX void handlePanning(int sym, int uni) {
auto& LPe = nisot::local_perspective;
if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return; if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return;
if(GDIM == 3) { if(GDIM == 3) {
if(sym == PSEUDOKEY_WHEELUP) View = solmul(cpush(2, -0.05*shiftmul), View), didsomething = true, playermoved = false; if(sym == PSEUDOKEY_WHEELUP) View = solmul(cpush(2, -0.05*shiftmul), LPe, View), didsomething = true, playermoved = false;
if(sym == PSEUDOKEY_WHEELDOWN) View = solmul(cpush(2, 0.05*shiftmul), View), didsomething = true, playermoved = false; if(sym == PSEUDOKEY_WHEELDOWN) View = solmul(cpush(2, 0.05*shiftmul), LPe, View), didsomething = true, playermoved = false;
} }
if(rug::rugged || smooth_scrolling) { if(rug::rugged || smooth_scrolling) {
return; return;
} }
auto& LPV = prod ? nisot::local_perspective : View;
#if !ISPANDORA #if !ISPANDORA
if(sym == SDLK_END && GDIM == 3) { if(sym == SDLK_END && GDIM == 3) {
View = solmul(cpush(2, -0.2*shiftmul), View), didsomething = true, playermoved = false; View = solmul(cpush(2, -0.2*shiftmul), LPe, View), didsomething = true, playermoved = false;
} }
if(sym == SDLK_HOME && GDIM == 3) { if(sym == SDLK_HOME && GDIM == 3) {
View = solmul(cpush(2, +0.2*shiftmul), View), didsomething = true, playermoved = false; View = solmul(cpush(2, +0.2*shiftmul), LPe, View), didsomething = true, playermoved = false;
} }
if(sym == SDLK_RIGHT) { if(sym == SDLK_RIGHT) {
if(history::on) if(history::on)
history::lvspeed += 0.1 * shiftmul; history::lvspeed += 0.1 * shiftmul;
else if(GDIM == 3) else if(GDIM == 3)
View = cspin(0, 2, -0.2*shiftmul) * View, didsomething = true; LPV = cspin(0, 2, -0.2*shiftmul) * LPV, didsomething = true;
else else
View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
} }
@ -313,7 +317,7 @@ EX void handlePanning(int sym, int uni) {
if(history::on) if(history::on)
history::lvspeed -= 0.1 * shiftmul; history::lvspeed -= 0.1 * shiftmul;
else if(GDIM == 3) else if(GDIM == 3)
View = cspin(0, 2, 0.2*shiftmul) * View, didsomething = true; LPV = cspin(0, 2, 0.2*shiftmul) * LPV, didsomething = true;
else else
View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
} }
@ -321,7 +325,7 @@ EX void handlePanning(int sym, int uni) {
if(history::on) if(history::on)
history::lvspeed += 0.1 * shiftmul; history::lvspeed += 0.1 * shiftmul;
else if(GDIM == 3) else if(GDIM == 3)
View = cspin(1, 2, 0.2*shiftmul) * View, didsomething = true; LPV = cspin(1, 2, 0.2*shiftmul) * LPV, didsomething = true;
else else
View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true;
} }
@ -329,7 +333,7 @@ EX void handlePanning(int sym, int uni) {
if(history::on) if(history::on)
history::lvspeed -= 0.1 * shiftmul; history::lvspeed -= 0.1 * shiftmul;
else if(GDIM == 3) else if(GDIM == 3)
View = cspin(1, 2, -0.2*shiftmul) * View, didsomething = true; LPV = cspin(1, 2, -0.2*shiftmul) * LPV, didsomething = true;
else else
View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true;
} }
@ -338,13 +342,13 @@ EX void handlePanning(int sym, int uni) {
if(history::on) if(history::on)
models::rotation++; models::rotation++;
else else
View = spin(M_PI/cgi.S21/2*shiftmul) * View, didsomething = true; LPV = spin(M_PI/cgi.S21/2*shiftmul) * LPV, didsomething = true;
} }
if(sym == SDLK_PAGEDOWN) { if(sym == SDLK_PAGEDOWN) {
if(history::on) if(history::on)
models::rotation++; models::rotation++;
else else
View = spin(-M_PI/cgi.S21/2*shiftmul) * View, didsomething = true; LPV = spin(-M_PI/cgi.S21/2*shiftmul) * LPV, didsomething = true;
} }
if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN) if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN)
@ -672,7 +676,8 @@ EX void mainloopiter() {
if(GDIM == 3 && !shmup::on && !rug::rugged) { if(GDIM == 3 && !shmup::on && !rug::rugged) {
#if CAP_MOUSEGRAB #if CAP_MOUSEGRAB
View = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * View; auto &LPV = prod ? nisot::local_perspective : View;
LPV = cspin(0, 2, -mouseaim_x) * cspin(1, 2, -mouseaim_y) * LPV;
mouseaim_x = mouseaim_y = 0; mouseaim_x = mouseaim_y = 0;
#endif #endif
} }

View File

@ -897,7 +897,7 @@ void dqi_poly::draw() {
auto npoly = *this; auto npoly = *this;
glcoords.clear(); glcoords.clear();
for(int i=0; i<cnt; i++) for(int i=0; i<cnt; i++)
glcoords.push_back(glhr::pointtogl(product::where(V * glhr::gltopoint( (*tab)[offset+i])))); glcoords.push_back(glhr::pointtogl(product::inverse_exp(V * glhr::gltopoint( (*tab)[offset+i]))));
npoly.offset = 0; npoly.offset = 0;
npoly.tab = &glcoords; npoly.tab = &glcoords;

View File

@ -4483,7 +4483,7 @@ EX int noclipped;
void make_clipping_planes() { void make_clipping_planes() {
#if MAXMDIM >= 4 #if MAXMDIM >= 4
clipping_planes.clear(); clipping_planes.clear();
if(sphere) return; if(sphere || prod) return;
auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) { auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) {
ld z1 = 1, z2 = 1; ld z1 = 1, z2 = 1;
hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1); hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1);
@ -5994,7 +5994,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
for(int a=0; a<c->type; a++) for(int a=0; a<c->type; a++)
if(c->move(a) && !isWall3(c->move(a), dummy)) { if(c->move(a) && !isWall3(c->move(a), dummy)) {
if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic) { if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic && !prod) {
if(a < 4 && among(geometry, gHoroTris, gBinary3) && celldistAlt(c) >= celldistAlt(viewcenter())) continue; if(a < 4 && among(geometry, gHoroTris, gBinary3) && celldistAlt(c) >= celldistAlt(viewcenter())) continue;
else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewcenter())) continue; else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewcenter())) continue;
else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue; else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue;
@ -7149,7 +7149,7 @@ EX void make_actual_view() {
if(GDIM == 3) { if(GDIM == 3) {
ld max = WDIM == 2 ? vid.camera : vid.yshift; ld max = WDIM == 2 ? vid.camera : vid.yshift;
if(max) if(max)
actual_view_transform = solmul(zpush(wall_radar((masterless ? centerover.at : viewcenter()), inverse(View), max)), actual_view_transform * View) * inverse(View); actual_view_transform = solmul(zpush(wall_radar((masterless ? centerover.at : viewcenter()), inverse(View), max)), nisot::local_perspective, actual_view_transform * View) * inverse(View);
camera_level = asin_auto(tC0(inverse(actual_view_transform * View))[2]); camera_level = asin_auto(tC0(inverse(actual_view_transform * View))[2]);
} }
if(nonisotropic) { if(nonisotropic) {

View File

@ -449,6 +449,8 @@ EX transmatrix euaffine(hyperpoint h) {
EX transmatrix cpush(int cid, ld alpha) { EX transmatrix cpush(int cid, ld alpha) {
transmatrix T = Id; transmatrix T = Id;
if(prod && cid == 2)
return mscale(Id, exp(alpha));
if(nonisotropic) if(nonisotropic)
return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0); return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0);
T[LDIM][LDIM] = T[cid][cid] = cos_auto(alpha); T[LDIM][LDIM] = T[cid][cid] = cos_auto(alpha);
@ -926,8 +928,8 @@ bool asign(ld y1, ld y2) { return signum(y1) != signum(y2); }
ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2); } ld xcross(ld x1, ld y1, ld x2, ld y2) { return x1 + (x2 - x1) * y1 / (y1 - y2); }
EX transmatrix solmul(const transmatrix T, const transmatrix V) { EX transmatrix solmul(const transmatrix T, const transmatrix LPe, const transmatrix V) {
if(nonisotropic) return nisot::transport_view(T, V); if(nonisotropic || prod) return nisot::transport_view(T, LPe, V);
else return T * V; else return T * V;
} }

View File

@ -1358,10 +1358,10 @@ EX void centerpc(ld aspd) {
} }
if(R < aspd) { if(R < aspd) {
View = solmul(gpushxto0(H), View); View = solmul(gpushxto0(H), Id, View);
} }
else else
View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), View); View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), Id, View);
fixmatrix(View); fixmatrix(View);
spinEdge(aspd); spinEdge(aspd);
@ -1472,6 +1472,7 @@ EX void resetview() {
viewctr.spin = cwt.spin; viewctr.spin = cwt.spin;
else centerover = cwt; else centerover = cwt;
cwtV = View; cwtV = View;
nisot::local_perspective = Id;
// SDL_LockSurface(s); // SDL_LockSurface(s);
// SDL_UnlockSurface(s); // SDL_UnlockSurface(s);
} }

View File

@ -141,7 +141,7 @@ EX namespace models {
#endif #endif
EX transmatrix rotmatrix() { EX transmatrix rotmatrix() {
if(GDIM == 2) return spin(rotation * degree); if(GDIM == 2 || prod) return spin(rotation * degree);
return spin(rotation_xy2 * degree) * cspin(0, 2, -rotation_xz * degree) * spin(rotation * degree); return spin(rotation_xy2 * degree) * cspin(0, 2, -rotation_xz * degree) * spin(rotation * degree);
} }

View File

@ -12,7 +12,7 @@ EX namespace nisot {
EX transmatrix local_perspective; EX transmatrix local_perspective;
#if HDR #if HDR
inline bool local_perspective_used() { return nonisotropic; } inline bool local_perspective_used() { return nonisotropic || prod; }
#endif #endif
EX bool geodesic_movement = true; EX bool geodesic_movement = true;
@ -582,7 +582,8 @@ EX namespace product {
heptagon *getOrigin() override { return underlying_map->getOrigin(); } heptagon *getOrigin() override { return underlying_map->getOrigin(); }
template<class T> auto in_underlying(const T& t) { template<class T> auto in_underlying(const T& t) {
pcgip = cgip; pmap = this; pcgip = cgip;
dynamicval<hrmap*> gpm(pmap, this);
dynamicval<eGeometry> g(geometry, underlying); dynamicval<eGeometry> g(geometry, underlying);
dynamicval<geometry_information*> gc(cgip, underlying_cgip); dynamicval<geometry_information*> gc(cgip, underlying_cgip);
dynamicval<hrmap*> gu(currentmap, underlying_map); dynamicval<hrmap*> gu(currentmap, underlying_map);
@ -638,10 +639,10 @@ EX namespace product {
return mscale(get_corner_position(c, i), exp(plevel * z/2)); return mscale(get_corner_position(c, i), exp(plevel * z/2));
} }
EX hyperpoint where(hyperpoint h) { EX hyperpoint inverse_exp(hyperpoint h) {
hyperpoint res; hyperpoint res;
res[2] = zlevel(h); res[2] = zlevel(h);
h = mscale(h, exp(-res[2])); h = zshift(h, -res[2]);
ld r = hypot_d(2, h); ld r = hypot_d(2, h);
if(r < 1e-6 || h[2] < 1) { if(r < 1e-6 || h[2] < 1) {
res[0] = h[0]; res[0] = h[0];
@ -655,6 +656,16 @@ EX namespace product {
return res; return res;
} }
EX hyperpoint direct_exp(hyperpoint h) {
hyperpoint res;
ld d = hypot_d(2, h);
ld cd = d == 0 ? 0 : sinh(d) / d;
res[0] = h[0] * cd;
res[1] = h[1] * cd;
res[2] = cosh(d);
return zshift(res, h[2]);
}
EX void in_underlying_map(const reaction_t& f) { EX void in_underlying_map(const reaction_t& f) {
((hrmap_product*)currentmap)->in_underlying(f); ((hrmap_product*)currentmap)->in_underlying(f);
} }
@ -762,7 +773,11 @@ EX namespace nisot {
return parallel_transport_bare(P, T); return parallel_transport_bare(P, T);
} }
EX transmatrix transport_view(const transmatrix T, const transmatrix V) { EX transmatrix transport_view(const transmatrix T, const transmatrix LPe, const transmatrix V) {
if(prod) {
hyperpoint h = product::direct_exp(inverse(LPe) * product::inverse_exp(tC0(T)));
return rgpushxto0(h) * V;
}
if(!geodesic_movement) { if(!geodesic_movement) {
transmatrix IV = inverse(V); transmatrix IV = inverse(V);
nisot::fixmatrix(IV); nisot::fixmatrix(IV);

View File

@ -610,7 +610,7 @@ EX void apply() {
} }
} }
View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) * View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) *
cspin(0, GDIM-1, -movement_angle * degree), View); cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View);
moved(); moved();
if(clearup) { if(clearup) {
viewcenter()->wall = waNone; viewcenter()->wall = waNone;
@ -633,7 +633,7 @@ EX void apply() {
case maTranslationRotation: case maTranslationRotation:
View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) * View = solmul(cspin(0, GDIM-1, movement_angle * degree) * ypush(shift_angle * degree) * xpush(cycle_length * t / period) * ypush(-shift_angle * degree) *
cspin(0, GDIM-1, -movement_angle * degree), View); cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View);
moved(); moved();
View = cspin(0, GDIM-1, 2 * M_PI * t / period) * View; View = cspin(0, GDIM-1, 2 * M_PI * t / period) * View;
if(clearup) { if(clearup) {

View File

@ -794,7 +794,7 @@ EX hyperpoint gltopoint(const glvertex& t) {
EX glvertex pointtogl(const hyperpoint& t) { EX glvertex pointtogl(const hyperpoint& t) {
glvertex h; glvertex h;
h[0] = t[0]; h[1] = t[1]; h[2] = t[2]; h[0] = t[0]; h[1] = t[1]; h[2] = t[2];
if(SHDIM == 4) h[3] = (GDIM == 3) ? t[3] : 1; if(SHDIM == 4) h[3] = (MDIM == 4) ? t[3] : 1;
return h; return h;
} }