From 00f4f4fca53bac6a7ed247ee7b871f36601256d6 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 18 Aug 2019 01:31:37 +0200 Subject: [PATCH] fully turnable product spaces --- basegraph.cpp | 7 ++++++- control.cpp | 39 ++++++++++++++++++++++----------------- drawing.cpp | 2 +- graph.cpp | 6 +++--- hyperpoint.cpp | 6 ++++-- hypgraph.cpp | 5 +++-- models.cpp | 2 +- nonisotropic.cpp | 25 ++++++++++++++++++++----- screenshot.cpp | 4 ++-- shaders.cpp | 2 +- 10 files changed, 63 insertions(+), 35 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index 941bd7c1..3698302f 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -400,8 +400,13 @@ void display_data::set_projection(int ed) { if(pers3) { glhr::projection_multiply(glhr::frustum(current_display->tanfov, current_display->tanfov * cd->ysize / cd->xsize)); 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)); + } } else if(GDIM == 3) { glhr::glmatrix M = glhr::ortho(cd->xsize/current_display->radius/2, -cd->ysize/current_display->radius/2, 1); diff --git a/control.cpp b/control.cpp index ce3e7e84..2b1cdc03 100644 --- a/control.cpp +++ b/control.cpp @@ -70,11 +70,13 @@ EX bool mouseout2() { return outofmap(mouseh) || outofmap(mouseoh); } -EX movedir vectodir(const hyperpoint& P) { +EX movedir vectodir(hyperpoint P) { transmatrix U = ggmatrix(cwt.at); 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); transmatrix Centered = sphereflip * rgpushxto0(H); @@ -111,13 +113,12 @@ EX void remission() { } 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()); // 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(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * tC0(pushone()); - else if(prod && d == 6) return zshift(C0, product::plevel); - else if(prod && d == 2) return zshift(C0, -product::plevel); - else return cspin(0, 2, d * M_PI/4) * tC0(pushone()); + else if(d&1) return cspin(0, 1, d > 4 ? M_PI/2 : -M_PI/2) * Forward; + else return cspin(0, 2, d * M_PI/4) * Forward; } EX void movepckeydir(int d) { @@ -284,28 +285,31 @@ typedef SDL_Event eventtype; EX bool smooth_scrolling = false; EX void handlePanning(int sym, int uni) { + auto& LPe = nisot::local_perspective; if(mousepan && dual::split([=] { handlePanning(sym, uni); })) return; if(GDIM == 3) { - if(sym == PSEUDOKEY_WHEELUP) View = solmul(cpush(2, -0.05*shiftmul), View), didsomething = true, playermoved = false; - if(sym == PSEUDOKEY_WHEELDOWN) 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), LPe, View), didsomething = true, playermoved = false; } if(rug::rugged || smooth_scrolling) { return; } + + auto& LPV = prod ? nisot::local_perspective : View; #if !ISPANDORA 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) { - 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(history::on) history::lvspeed += 0.1 * shiftmul; 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 View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; } @@ -313,7 +317,7 @@ EX void handlePanning(int sym, int uni) { if(history::on) history::lvspeed -= 0.1 * shiftmul; 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 View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; } @@ -321,7 +325,7 @@ EX void handlePanning(int sym, int uni) { if(history::on) history::lvspeed += 0.1 * shiftmul; 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 View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; } @@ -329,7 +333,7 @@ EX void handlePanning(int sym, int uni) { if(history::on) history::lvspeed -= 0.1 * shiftmul; 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 View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; } @@ -338,13 +342,13 @@ EX void handlePanning(int sym, int uni) { if(history::on) models::rotation++; 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(history::on) models::rotation++; 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) @@ -672,7 +676,8 @@ EX void mainloopiter() { if(GDIM == 3 && !shmup::on && !rug::rugged) { #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; #endif } diff --git a/drawing.cpp b/drawing.cpp index 4dde8b1d..144ade54 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -897,7 +897,7 @@ void dqi_poly::draw() { auto npoly = *this; glcoords.clear(); for(int i=0; i= 4 clipping_planes.clear(); - if(sphere) return; + if(sphere || prod) return; auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) { ld z1 = 1, z2 = 1; 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; atype; a++) 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; 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; @@ -7149,7 +7149,7 @@ EX void make_actual_view() { if(GDIM == 3) { ld max = WDIM == 2 ? vid.camera : vid.yshift; 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]); } if(nonisotropic) { diff --git a/hyperpoint.cpp b/hyperpoint.cpp index 084336a8..9fc3badc 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -449,6 +449,8 @@ EX transmatrix euaffine(hyperpoint h) { EX transmatrix cpush(int cid, ld alpha) { transmatrix T = Id; + if(prod && cid == 2) + return mscale(Id, exp(alpha)); if(nonisotropic) return eupush3(cid == 0 ? alpha : 0, cid == 1 ? alpha : 0, cid == 2 ? alpha : 0); 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); } -EX transmatrix solmul(const transmatrix T, const transmatrix V) { - if(nonisotropic) return nisot::transport_view(T, V); +EX transmatrix solmul(const transmatrix T, const transmatrix LPe, const transmatrix V) { + if(nonisotropic || prod) return nisot::transport_view(T, LPe, V); else return T * V; } diff --git a/hypgraph.cpp b/hypgraph.cpp index 1c966cb9..8742da0d 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -1358,10 +1358,10 @@ EX void centerpc(ld aspd) { } if(R < aspd) { - View = solmul(gpushxto0(H), View); + View = solmul(gpushxto0(H), Id, View); } else - View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), View); + View = solmul(rspintox(H) * xpush(-aspd) * spintox(H), Id, View); fixmatrix(View); spinEdge(aspd); @@ -1472,6 +1472,7 @@ EX void resetview() { viewctr.spin = cwt.spin; else centerover = cwt; cwtV = View; + nisot::local_perspective = Id; // SDL_LockSurface(s); // SDL_UnlockSurface(s); } diff --git a/models.cpp b/models.cpp index f51909a7..16c81544 100644 --- a/models.cpp +++ b/models.cpp @@ -141,7 +141,7 @@ EX namespace models { #endif 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); } diff --git a/nonisotropic.cpp b/nonisotropic.cpp index 3f939eb5..bd934689 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -12,7 +12,7 @@ EX namespace nisot { EX transmatrix local_perspective; #if HDR - inline bool local_perspective_used() { return nonisotropic; } + inline bool local_perspective_used() { return nonisotropic || prod; } #endif EX bool geodesic_movement = true; @@ -582,7 +582,8 @@ EX namespace product { heptagon *getOrigin() override { return underlying_map->getOrigin(); } template auto in_underlying(const T& t) { - pcgip = cgip; pmap = this; + pcgip = cgip; + dynamicval gpm(pmap, this); dynamicval g(geometry, underlying); dynamicval gc(cgip, underlying_cgip); dynamicval gu(currentmap, underlying_map); @@ -638,10 +639,10 @@ EX namespace product { return mscale(get_corner_position(c, i), exp(plevel * z/2)); } - EX hyperpoint where(hyperpoint h) { + EX hyperpoint inverse_exp(hyperpoint h) { hyperpoint res; res[2] = zlevel(h); - h = mscale(h, exp(-res[2])); + h = zshift(h, -res[2]); ld r = hypot_d(2, h); if(r < 1e-6 || h[2] < 1) { res[0] = h[0]; @@ -655,6 +656,16 @@ EX namespace product { 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) { ((hrmap_product*)currentmap)->in_underlying(f); } @@ -762,7 +773,11 @@ EX namespace nisot { 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) { transmatrix IV = inverse(V); nisot::fixmatrix(IV); diff --git a/screenshot.cpp b/screenshot.cpp index dcc72db1..9d5ec425 100644 --- a/screenshot.cpp +++ b/screenshot.cpp @@ -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) * - cspin(0, GDIM-1, -movement_angle * degree), View); + cspin(0, GDIM-1, -movement_angle * degree), nisot::local_perspective, View); moved(); if(clearup) { viewcenter()->wall = waNone; @@ -633,7 +633,7 @@ EX void apply() { case maTranslationRotation: 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(); View = cspin(0, GDIM-1, 2 * M_PI * t / period) * View; if(clearup) { diff --git a/shaders.cpp b/shaders.cpp index 54d86ba2..47084aaf 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -794,7 +794,7 @@ EX hyperpoint gltopoint(const glvertex& t) { EX glvertex pointtogl(const hyperpoint& t) { glvertex h; 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; }