diff --git a/basegraph.cpp b/basegraph.cpp index 8b4e7c04..ee78a6ee 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -235,7 +235,7 @@ void display_data::set_projection(int ed, bool apply_models) { } else { - if(hyperbolic && vid.alpha > -1) { + if(hyperbolic && vid.alpha > -1 && DIM == 2) { // Because of the transformation from H3 to the Minkowski hyperboloid, // points with negative Z can be generated in some 3D settings. // This happens for points below the camera, but above the plane. @@ -299,7 +299,7 @@ void display_data::set_viewport(int ed) { } bool model_needs_depth() { - return pmodel == mdBall; + return DIM == 3 || pmodel == mdBall; } void setGLProjection(color_t col) { diff --git a/conformal.cpp b/conformal.cpp index 44b759c5..63612a8c 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -644,16 +644,16 @@ namespace conformal { "the point z is mapped to f(z). You can also use the underlying coordinates ux, uy, uz." ) + "\n\n" + parser_help() ); - #if CAP_POLY + #if CAP_QUEUE && CAP_CURVE dialog::extra_options = [] () { initquickqueue(); queuereset(mdUnchanged, PPR::LINE); for(int a=-1; a<=1; a++) { - curvepoint(hpxyz(-M_PI/2 * current_display->radius, a*current_display->radius, 0)); - curvepoint(hpxyz(+M_PI/2 * current_display->radius, a*current_display->radius, 0)); + curvepoint(point2(-M_PI/2 * current_display->radius, a*current_display->radius)); + curvepoint(point2(+M_PI/2 * current_display->radius, a*current_display->radius)); queuecurve(forecolor, 0, PPR::LINE); - curvepoint(hpxyz(a*current_display->radius, -M_PI/2*current_display->radius, 0)); - curvepoint(hpxyz(a*current_display->radius, +M_PI/2*current_display->radius, 0)); + curvepoint(point2(a*current_display->radius, -M_PI/2*current_display->radius)); + curvepoint(point2(a*current_display->radius, +M_PI/2*current_display->radius)); queuecurve(forecolor, 0, PPR::LINE); } queuereset(pmodel, PPR::LINE); diff --git a/control.cpp b/control.cpp index 7a656f4a..e1c7573e 100644 --- a/control.cpp +++ b/control.cpp @@ -177,6 +177,7 @@ void closeJoysticks() { } void checkjoy() { + #if DIM == 2 DEBB(DF_GRAPH, (debugfile,"check joy\n")); if(!DEFAULTCONTROL) return; ld joyvalue1 = sqr(vid.joyvalue); @@ -199,10 +200,11 @@ void checkjoy() { } joydir = vectodir(hpxy(jx, jy)); + #endif } void checkpanjoy(double t) { - + #if DIM == 2 if(shmup::on) return; if(vid.joypanspeed < 1e-7) return; @@ -215,6 +217,7 @@ void checkpanjoy(double t) { playermoved = false; View = gpushxto0(hpxy(jx, jy)) * View; + #endif } #endif @@ -245,27 +248,38 @@ void handlePanning(int sym, int uni) { if(rug::rugged) return; #if !ISPANDORA + if(sym == SDLK_END && DIM == 3) { + View = cpush(2, -0.2*shiftmul) * View, didsomething = true, playermoved = false; + } if(sym == SDLK_RIGHT) { if(conformal::on) conformal::lvspeed += 0.1 * shiftmul; + else if(DIM == 3) + View = cspin(0, 2, -0.2*shiftmul) * View, didsomething = true; else View = xpush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; } if(sym == SDLK_LEFT) { if(conformal::on) conformal::lvspeed -= 0.1 * shiftmul; + else if(DIM == 3) + View = cspin(0, 2, 0.2*shiftmul) * View, didsomething = true; else View = xpush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; } if(sym == SDLK_UP) { if(conformal::on) conformal::lvspeed += 0.1 * shiftmul; + else if(DIM == 3) + View = cspin(1, 2, 0.2*shiftmul) * View, didsomething = true; else View = ypush(+0.2*shiftmul) * View, playermoved = false, didsomething = true; } if(sym == SDLK_DOWN) { if(conformal::on) conformal::lvspeed -= 0.1 * shiftmul; + else if(DIM == 3) + View = cspin(1, 2, -0.2*shiftmul) * View, didsomething = true; else View = ypush(-0.2*shiftmul) * View, playermoved = false, didsomething = true; } @@ -286,6 +300,7 @@ void handlePanning(int sym, int uni) { if(sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN) if(isGravityLand(cwt.at->land)) playermoved = false; + #if DIM == 2 if(sym == PSEUDOKEY_WHEELUP) { ld jx = (mousex - current_display->xcenter - .0) / current_display->radius / 10; ld jy = (mousey - current_display->ycenter - .0) / current_display->radius / 10; @@ -293,6 +308,7 @@ void handlePanning(int sym, int uni) { View = gpushxto0(hpxy(jx, jy)) * View; sym = 1; } + #endif } #ifdef SCALETUNER @@ -760,7 +776,7 @@ void handle_event(SDL_Event& ev) { vid.xposition += (mousex - lmousex) * 1. / current_display->scrsize, vid.yposition += (mousey - lmousey) * 1. / current_display->scrsize; } - else if(mouseh[2] < 50 && mouseoh[2] < 50) { + else if(mouseh[DIM] < 50 && mouseoh[DIM] < 50) { panning(mouseoh, mouseh); } } @@ -892,6 +908,7 @@ bool haveMobileCompass() { } bool handleCompass() { +#if DIM == 2 if(!haveMobileCompass()) return false; using namespace shmupballs; @@ -913,6 +930,9 @@ bool handleCompass() { } return false; +#else + return false; +#endif } // orientation sensitivity diff --git a/geometry.cpp b/geometry.cpp index 2381b356..59911e56 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -197,7 +197,7 @@ void precalc() { transmatrix xspinpush(ld dir, ld dist) { if(euclid) - return eupush(cos(dir) * dist, -sin(dir) * dist); + return eupush(cos(dir) * dist, -sin(dir) * dist DC(,0)); else return spin(dir) * xpush(dist) * spin(-dir); } diff --git a/geometry2.cpp b/geometry2.cpp index 2fb4fd7f..a411fd56 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -362,7 +362,7 @@ void virtualRebase(cell*& base, transmatrix& at, bool tohex) { void virtualRebase(cell*& base, hyperpoint& h, bool tohex) { // we perform fixing in check, so that it works with larger range - virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return hyperbolic ? hpxy(h[0], h[1]) :h; }); + virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return hyperbolic ? hpxy(h[0], h[1] DC(,h[2])) :h; }); } // works only in geometries similar to the standard one, and only on heptagons diff --git a/graph.cpp b/graph.cpp index 36af051c..7e866177 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3777,10 +3777,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(!inmirrorcount) { transmatrix& gm = gmatrix[c]; orig = - gm[2][2] == 0 ? true : - euwrap ? hypot(gm[0][2], gm[1][2]) >= hypot(V[0][2], V[1][2]) : - sphereflipped() ? fabs(gm[2][2]-1) <= fabs(V[2][2]-1) : - fabs(gm[2][2]-1) >= fabs(V[2][2]-1) - 1e-8; + gm[DIM][DIM] == 0 ? true : + euwrap ? hypot(gm[0][DIM], gm[1][DIM]) >= hypot(V[0][DIM], V[1][DIM]) : + sphereflipped() ? fabs(gm[DIM][DIM]-1) <= fabs(V[DIM][DIM]-1) : + fabs(gm[DIM][DIM]-1) >= fabs(V[DIM][DIM]-1) - 1e-8; if(orig) gm = V; } @@ -3853,7 +3853,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } if(!euclid) { - double dfc = euclid ? intval(VC0, C0) : VC0[2]; + double dfc = euclid ? intval(VC0, C0) : VC0[DIM]; if(dfc < centdist) { centdist = dfc; @@ -5553,7 +5553,7 @@ purehookset hooks_drawmap; transmatrix cview() { sphereflip = Id; - if(sphereflipped()) sphereflip[2][2] = -1; + if(sphereflipped()) sphereflip[DIM][DIM] = -1; return ypush(vid.yshift) * sphereflip * View; } @@ -5768,10 +5768,10 @@ void drawmovestar(double dx, double dy) { transmatrix Centered = Id; if(masterless) - Centered = eupush(H[0], H[1]); + Centered = eupush(H); else if(R > 1e-9) Centered = rgpushxto0(H); - Centered = Centered * rgpushxto0(hpxy(dx*5, dy*5)); + Centered = Centered * rgpushxto0(hpxy0(dx*5, dy*5)); if(multi::cpid >= 0) multi::crosscenter[multi::cpid] = Centered; int rax = vid.axes; diff --git a/hyper.h b/hyper.h index bc0fd94c..048db6a7 100644 --- a/hyper.h +++ b/hyper.h @@ -189,7 +189,6 @@ typedef complex cld; #define DEBSM(x) -#define DIM 2 #define MDIM (DIM+1) #if DIM == 2 @@ -224,7 +223,7 @@ inline transmatrix operator * (const transmatrix& T, const transmatrix& U) { transmatrix R; // for(int i=0; i<3; i++) for(int j=0; j<3; j++) R[i][j] = 0; for(int i=0; i void print(hstream& hs, const array& a) { print(hs, "("); comma_printer c(hs); for(const T& t: a) c(t); print(hs, ")"); } template void print(hstream& hs, const vector& a) { print(hs, "("); comma_printer c(hs); for(const T& t: a) c(t); print(hs, ")"); } -inline void print(hstream& hs, const hyperpoint h) { print(hs, (const array&)h); } +inline void print(hstream& hs, const hyperpoint h) { print(hs, (const array&)h); } inline void print(hstream& hs, const transmatrix T) { print(hs, "("); comma_printer c(hs); - for(int i=0; i<3; i++) - for(int j=0; j<3; j++) c(T[i][j]); + for(int i=0; i void print(hstream& hs, const pair & t) { print(hs, "(", t.first, ",", t.second, ")"); } @@ -4740,6 +4748,7 @@ extern int cells_drawn; void menuitem_sightrange(char c = 'r'); +bool invis_point(const hyperpoint h); bool invalid_point(const hyperpoint h); bool invalid_point(const transmatrix T); bool in_smart_range(const transmatrix& T); diff --git a/hyperpoint.cpp b/hyperpoint.cpp index 43976bfe..b77c0408 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -438,7 +438,7 @@ void fixmatrix(transmatrix& T) { // show the matrix on screen ld det(const transmatrix& T) { - #if DIM == 3 + #if DIM == 2 ld det = 0; for(int i=0; i<3; i++) det += T[0][i] * T[1][(i+1)%3] * T[2][(i+2)%3]; @@ -472,7 +472,7 @@ void inverse_error(const transmatrix& T) { transmatrix inverse(const transmatrix& T) { profile_start(7); - #if DIM == 3 + #if DIM == 2 ld d = det(T); transmatrix T2; if(d == 0) { @@ -493,8 +493,7 @@ transmatrix inverse(const transmatrix& T) { if(T1[b][a]) { if(b != a) for(int c=0; c 1e8 || std::isinf(h[2]); } @@ -1040,7 +1051,7 @@ void centerpc(ld aspd) { ors::unrotate(cwtV); ors::unrotate(View); hyperpoint H = ypush(-vid.yshift) * sphereflip * tC0(cwtV); - ld R = H[0] == 0 && H[1] == 0 ? 0 : hdist0(H); // = sqrt(H[0] * H[0] + H[1] * H[1]); + ld R = zero2(H) ? 0 : hdist0(H); // = sqrt(H[0] * H[0] + H[1] * H[1]); if(R < 1e-9) { // either already centered or direction unknown /* if(playerfoundL && playerfoundR) { @@ -1057,8 +1068,8 @@ void centerpc(ld aspd) { aspd *= (2+3*R*R); if(aspd > R) aspd = R; - View[0][2] -= cwtV[0][2] * aspd / R; - View[1][2] -= cwtV[1][2] * aspd / R; + for(int i=0; ic7->type; i++) { int i1 = i * DUALMUL; heptagon *h2 = createStep(viewctr.at, i1); @@ -1110,7 +1121,7 @@ void optimizeview() { if(archimedean) T = arcm::relative_matrix(h2, viewctr.at); #endif hyperpoint H = View * tC0(T); - ld quality = euclid ? hdist0(H) : H[2]; + ld quality = euclid ? hdist0(H) : H[DIM]; if(quality < best) best = quality, turn = i1, TB = T; } if(turn >= 0) { @@ -1128,7 +1139,7 @@ void optimizeview() { ld trot = -i * M_PI * 2 / (S7+.0); transmatrix T = i < 0 ? Id : spin(trot) * xpush(tessf) * pispin; hyperpoint H = View * tC0(T); - if(H[2] < best) best = H[2], turn = i, TB = T; + if(H[DIM] < best) best = H[DIM], turn = i, TB = T; } if(turn >= 0) { @@ -1267,8 +1278,8 @@ void draw_model_elements() { case mdHyperboloid: { if(hyperbolic) { #if CAP_QUEUE - curvepoint(hpxyz(0,0,1)); - curvepoint(hpxyz(0,0,-vid.alpha)); + curvepoint(point3(0,0,1)); + curvepoint(point3(0,0,-vid.alpha)); queuecurve(ringcolor, 0, PPR::CIRCLE); ld& tz = conformal::top_z; @@ -1281,16 +1292,16 @@ void draw_model_elements() { a[1] = sb * a[2] / -cb; a[0] = sqrt(-1 + a[2] * a[2] - a[1] * a[1]); - curvepoint(hpxyz(0,0,-vid.alpha)); + curvepoint(point3(0,0,-vid.alpha)); curvepoint(a); - curvepoint(hpxyz(0,0,0)); + curvepoint(point3(0,0,0)); a[0] = -a[0]; curvepoint(a); - curvepoint(hpxyz(0,0,-vid.alpha)); + curvepoint(point3(0,0,-vid.alpha)); queuecurve(ringcolor, 0, PPR::CIRCLE); - curvepoint(hpxyz(-1,0,0)); - curvepoint(hpxyz(1,0,0)); + curvepoint(point3(-1,0,0)); + curvepoint(point3(1,0,0)); queuecurve(ringcolor, 0, PPR::CIRCLE); a[1] = sb * tz / -cb; @@ -1298,7 +1309,7 @@ void draw_model_elements() { a[2] = tz - vid.alpha; curvepoint(a); - curvepoint(hpxyz(0,0,-vid.alpha)); + curvepoint(point3(0,0,-vid.alpha)); a[0] = -a[0]; curvepoint(a); queuecurve(ringcolor, 0, PPR::CIRCLE); @@ -1374,7 +1385,7 @@ void draw_boundary(int w) { ld z = -sqrt(1 - x*x); conformal::apply_orientation(y, x); hyperpoint h1; - applymodel(hpxyz(x,y,z), h1); + applymodel(hpxyz(x,y,DC(0,) z), h1); conformal::apply_orientation(h1[0], h1[1]); h1[1] = abs(h1[1]) * b; @@ -1424,7 +1435,7 @@ void draw_boundary(int w) { queuereset(mdUnchanged, p); for(int i=0; i<=360; i++) { ld s = sin(i * degree); - curvepoint(hpxyz(current_display->radius * cos(i * degree), current_display->radius * s * (conformal::cos_ball * s >= 0 - 1e-6 ? 1 : abs(conformal::sin_ball)), 0)); + curvepoint(point3(current_display->radius * cos(i * degree), current_display->radius * s * (conformal::cos_ball * s >= 0 - 1e-6 ? 1 : abs(conformal::sin_ball)), 0)); } queuecurve(lc, fc, p); queuereset(pmodel, p); @@ -1433,7 +1444,7 @@ void draw_boundary(int w) { for(int i=0; i<=360; i++) { ld s = sin(i * degree); - curvepoint(hpxyz(current_display->radius * cos(i * degree), current_display->radius * s * conformal::sin_ball, 0)); + curvepoint(point3(current_display->radius * cos(i * degree), current_display->radius * s * conformal::sin_ball, 0)); } queuecurve(lc, fc, p); queuereset(pmodel, p); @@ -1441,7 +1452,7 @@ void draw_boundary(int w) { if(euclid || sphere) { queuereset(mdUnchanged, p); for(int i=0; i<=360; i++) { - curvepoint(hpxyz(current_display->radius * cos(i * degree), current_display->radius * sin(i * degree), 0)); + curvepoint(point3(current_display->radius * cos(i * degree), current_display->radius * sin(i * degree), 0)); } queuecurve(lc, fc, p); queuereset(pmodel, p); @@ -1511,7 +1522,7 @@ void draw_boundary(int w) { queuereset(mdUnchanged, p); for(ld a=-10; a<=10; a+=0.01 / (1 << vid.linequality) / u) { cld z = exp(cld(a, a * imag(sm) / real(sm) + M_PI)); - hyperpoint ret = hpxyz(real(z), imag(z), 0); + hyperpoint ret = point2(real(z), imag(z)); ret = mobius(ret, vid.skiprope, 1); ret *= current_display->radius; curvepoint(ret); diff --git a/polygons.cpp b/polygons.cpp index 6267cb2c..9c8c3ffd 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -490,6 +490,9 @@ vector line_vertices; #endif void glapplymatrix(const transmatrix& V) { + #if DIM == 3 + glhr::set_modelview(glhr::id); + #else GLfloat mat[16]; int id = 0; @@ -509,6 +512,7 @@ void glapplymatrix(const transmatrix& V) { conformal::apply_orientation(mat[a*4], mat[a*4+1]); glhr::set_modelview(glhr::as_glmatrix(mat)); + #endif } void dqi_poly::gldraw() { @@ -632,12 +636,16 @@ void dqi_poly::gldraw() { #endif double scale_at(const transmatrix& T) { + #if DIM==3 + return 1 / (tC0(T))[2]; + #else using namespace hyperpoint_vec; hyperpoint h1, h2, h3; applymodel(tC0(T), h1); applymodel(T * xpush0(.01), h2); applymodel(T * ypush(.01) * C0, h3); return sqrt(hypot2(h2-h1) * hypot2(h3-h1) / .0001); + #endif } double linewidthat(const hyperpoint& h) { @@ -1262,7 +1270,7 @@ void dqi_string::draw() { svg::text(x, y, size, str, frame, color, align); return; } - #elseif ISMOBILE==0 + #elif ISMOBILE==0 int fr = frame & 255; displayfrSP(x, y, shift, fr, size, str, color, align, frame >> 8); #else @@ -2872,12 +2880,14 @@ void queuechr(const transmatrix& V, double size, char chr, color_t col, int fram void queuestr(const hyperpoint& h, int size, const string& chr, color_t col, int frame) { if(invalid_point(h)) return; + if(DIM == 3 && invis_point(h)) return; int xc, yc, sc; getcoord0(h, xc, yc, sc); queuestr(xc, yc, sc, size, chr, col, frame); } void queuestr(const transmatrix& V, double size, const string& chr, color_t col, int frame, int align) { if(invalid_point(V)) return; + if(DIM == 3 && invis_point(tC0(V))) return; int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); // int xs, ys, ss; getcoord0(V * xpush0(.01), xs, ys, ss); @@ -2886,6 +2896,7 @@ void queuestr(const transmatrix& V, double size, const string& chr, color_t col, void queuecircle(const transmatrix& V, double size, color_t col) { if(invalid_point(V)) return; + if(DIM == 3 && invis_point(tC0(V))) return; int xc, yc, sc; getcoord0(tC0(V), xc, yc, sc); int xs, ys, ss; getcoord0(V * xpush0(.01), xs, ys, ss); queuecircle(xc, yc, scale_in_pixels(V) * size, col); diff --git a/shmup.cpp b/shmup.cpp index be9f6ab7..2fa206e9 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -845,11 +845,15 @@ void handleInput(int delta) { multi::mdx[i] = multi::mdx[i] * (1 - delta / 1000.) + mdx * delta / 2000.; multi::mdy[i] = multi::mdy[i] * (1 - delta / 1000.) + mdy * delta / 2000.; + #if DIM == 2 if(mdx != 0 || mdy != 0) if(!multi::combo[i]) { cwtV = multi::whereis[i]; cwt = multi::player[i]; flipplayer = multi::flipped[i]; multi::whereto[i] = vectodir(hpxy(multi::mdx[i], multi::mdy[i])); } + #else + ignore(mdx); ignore(mdy); + #endif if(multi::actionspressed[b+pcFire] || (multi::actionspressed[b+pcMoveLeft] && multi::actionspressed[b+pcMoveRight])) @@ -1536,6 +1540,7 @@ void movePlayer(monster *m, int delta) { #endif double mturn = 0, mgo = 0, mdx = 0, mdy = 0; + ignore(mdx); ignore(mdy); bool shotkey = false, dropgreen = false, facemouse = false; if(facemouse) { @@ -1621,6 +1626,7 @@ void movePlayer(monster *m, int delta) { playerturn[cpid] = mturn * delta / 150.0; + #if DIM == 2 double mdd = hypot(mdx, mdy); if(mdd > 1e-6) { @@ -1634,6 +1640,7 @@ void movePlayer(monster *m, int delta) { playerturn[cpid] = -atan2(h[1], h[0]); mgo += mdd; } + #endif #if CAP_SDL Uint8 *keystate = SDL_GetKeyState(NULL); diff --git a/sysconfig.h b/sysconfig.h index 96c2668a..b6706d9c 100644 --- a/sysconfig.h +++ b/sysconfig.h @@ -443,6 +443,8 @@ union SDL_Event; #endif #endif +#define DIM 3 + #ifndef CAP_GEOMETRY #define CAP_GEOMETRY (!(ISMINI)) #endif