mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	3D:: elliptic space
This commit is contained in:
		| @@ -1729,6 +1729,7 @@ vector<eLand> randlands = { | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
| static const flagtype qsNONOR           = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE; | static const flagtype qsNONOR           = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE; | ||||||
|  | static const flagtype qsNONORE          = qsNONOR | qELLIPTIC; | ||||||
| static const flagtype qsBQ              = qANYQ | qSMALL | qBOUNDED; | static const flagtype qsBQ              = qANYQ | qSMALL | qBOUNDED; | ||||||
| static const flagtype qsSMALL           = qANYQ | qSMALL | qBOUNDED; | static const flagtype qsSMALL           = qANYQ | qSMALL | qBOUNDED; | ||||||
| static const flagtype qsSMALLN          = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE; | static const flagtype qsSMALLN          = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE; | ||||||
| @@ -1736,6 +1737,7 @@ static const flagtype qsZEBRA           = qANYQ | qSMALL | qBOUNDED | qZEBRA; | |||||||
| static const flagtype qsFIELD           = qANYQ | qFIELD | qBOUNDED; | static const flagtype qsFIELD           = qANYQ | qFIELD | qBOUNDED; | ||||||
| static const flagtype qsDOCKS           = qANYQ | qSMALL | qBOUNDED | qDOCKS; | static const flagtype qsDOCKS           = qANYQ | qSMALL | qBOUNDED | qDOCKS; | ||||||
| static const flagtype qsSMALLB          = qSMALL | qBOUNDED; | static const flagtype qsSMALLB          = qSMALL | qBOUNDED; | ||||||
|  | static const flagtype qsSMALLBE         = qsSMALLB | qELLIPTIC; | ||||||
|  |  | ||||||
| vector<geometryinfo> ginf = { | vector<geometryinfo> ginf = { | ||||||
|   {"{7,3}", "none",     "{7,3} (standard HyperRogue map)",            "HR",       7, 3, 0,         gcHyperbolic,       0, {{7, 5}}, eVariation::bitruncated}, |   {"{7,3}", "none",     "{7,3} (standard HyperRogue map)",            "HR",       7, 3, 0,         gcHyperbolic,       0, {{7, 5}}, eVariation::bitruncated}, | ||||||
| @@ -1768,6 +1770,7 @@ vector<geometryinfo> ginf = { | |||||||
|   {"bin3",  "none",     "3D binary tiling",                           "binary3",  9, 4, 0,         gcHyperbolic,       0, {{7, 3}}, eVariation::pure}, |   {"bin3",  "none",     "3D binary tiling",                           "binary3",  9, 4, 0,         gcHyperbolic,       0, {{7, 3}}, eVariation::pure}, | ||||||
|   {"cube",  "none",     "3D cube tiling",                             "cube",     6, 4, 0,         gcEuclid,           0, {{7, 5}}, eVariation::pure}, |   {"cube",  "none",     "3D cube tiling",                             "cube",     6, 4, 0,         gcEuclid,           0, {{7, 5}}, eVariation::pure}, | ||||||
|   {"120c",  "none",     "120-cell",                                   "120c",    12, 4, qsSMALLB,  gcSphere,           0, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, |   {"120c",  "none",     "120-cell",                                   "120c",    12, 4, qsSMALLB,  gcSphere,           0, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, | ||||||
|  |   {"e120c", "elliptic", "120-cell (elliptic space)",                  "e120c",   12, 4, qsSMALLBE, gcSphere,           0, {{SEE_ALL, SEE_ALL}}, eVariation::pure}, | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| // remember to match the following mask when specifying codes for extra geometries: 0x78600 | // remember to match the following mask when specifying codes for extra geometries: 0x78600 | ||||||
|   | |||||||
| @@ -214,7 +214,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle | |||||||
| enum eGeometry { | enum eGeometry { | ||||||
|   gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,  |   gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,  | ||||||
|   gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,  |   gKleinQuartic, gBolza, gBolza2, gMinimal, gBinaryTiling, gArchimedean,  | ||||||
|   gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling, gCell120, |   gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling, gCell120, gECell120, | ||||||
|   gGUARD}; |   gGUARD}; | ||||||
|  |  | ||||||
| enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; | enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; | ||||||
| @@ -244,6 +244,8 @@ static const flagtype qFIELD           = 16; | |||||||
| static const flagtype qDOCKS           = 32; | static const flagtype qDOCKS           = 32; | ||||||
| static const flagtype qZEBRA           = 64; | static const flagtype qZEBRA           = 64; | ||||||
|  |  | ||||||
|  | static const flagtype qELLIPTIC        = 128; | ||||||
|  |  | ||||||
| // note: dnext assumes that x&7 equals 7 | // note: dnext assumes that x&7 equals 7 | ||||||
| static const int SEE_ALL = 50; | static const int SEE_ALL = 50; | ||||||
| static const int FORBIDDEN = -1; | static const int FORBIDDEN = -1; | ||||||
|   | |||||||
| @@ -361,6 +361,7 @@ void initConfig() { | |||||||
|   addsaver(sightranges[gBinary3], "sight-binary3", 3); |   addsaver(sightranges[gBinary3], "sight-binary3", 3); | ||||||
|   addsaver(sightranges[gCubeTiling], "sight-cubes", 7); |   addsaver(sightranges[gCubeTiling], "sight-cubes", 7); | ||||||
|   addsaver(sightranges[gCell120], "sight-120cell", 2 * M_PI); |   addsaver(sightranges[gCell120], "sight-120cell", 2 * M_PI); | ||||||
|  |   addsaver(sightranges[gECell120], "sight-120cell-elliptic", M_PI); | ||||||
|  |  | ||||||
|   addsaver(vid.consider_shader_projection, "shader-projection", true); |   addsaver(vid.consider_shader_projection, "shader-projection", true); | ||||||
|    |    | ||||||
|   | |||||||
| @@ -8,15 +8,15 @@ namespace hr { | |||||||
| transmatrix &ggmatrix(cell *c); | transmatrix &ggmatrix(cell *c); | ||||||
|  |  | ||||||
| void fixelliptic(transmatrix& at) { | void fixelliptic(transmatrix& at) { | ||||||
|   if(elliptic && at[2][2] < 0) { |   if(elliptic && at[DIM][DIM] < 0) { | ||||||
|     for(int i=0; i<3; i++) for(int j=0; j<3; j++) |     for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++) | ||||||
|       at[i][j] = -at[i][j]; |       at[i][j] = -at[i][j]; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void fixelliptic(hyperpoint& h) { | void fixelliptic(hyperpoint& h) { | ||||||
|   if(elliptic && h[2] < 0) |   if(elliptic && h[DIM] < 0) | ||||||
|     for(int i=0; i<3; i++) h[i] = -h[i]; |     for(int i=0; i<MDIM; i++) h[i] = -h[i]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| transmatrix master_relative(cell *c, bool get_inverse) { | transmatrix master_relative(cell *c, bool get_inverse) { | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -103,7 +103,7 @@ void addMessage(string s, char spamtype = 0); | |||||||
| #define sphere (cgclass == gcSphere) | #define sphere (cgclass == gcSphere) | ||||||
| #define hyperbolic (cgclass == gcHyperbolic) | #define hyperbolic (cgclass == gcHyperbolic) | ||||||
| #define nonorientable (ginf[geometry].flags & qNONORIENTABLE) | #define nonorientable (ginf[geometry].flags & qNONORIENTABLE) | ||||||
| #define elliptic (sphere && nonorientable) | #define elliptic (ginf[geometry].flags & qELLIPTIC) | ||||||
| #define quotient (ginf[geometry].flags & qANYQ) | #define quotient (ginf[geometry].flags & qANYQ) | ||||||
| #define euwrap (quotient && euclid) | #define euwrap (quotient && euclid) | ||||||
| #define fulltorus (bounded && euclid) | #define fulltorus (bounded && euclid) | ||||||
| @@ -192,7 +192,7 @@ typedef complex<ld> cld; | |||||||
| #if MAXDIM == 3 | #if MAXDIM == 3 | ||||||
| #define DIM 2 | #define DIM 2 | ||||||
| #else | #else | ||||||
| #define DIM ((geometry == gBinary3 || geometry == gCubeTiling || geometry == gCell120) ? 3 : 2) | #define DIM ((geometry == gBinary3 || geometry == gCubeTiling || geometry == gCell120 || geometry == gECell120) ? 3 : 2) | ||||||
| #endif | #endif | ||||||
| #define MDIM (DIM+1) | #define MDIM (DIM+1) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -265,7 +265,7 @@ bool haveOrbPower() { | |||||||
|     cell *c = dcal[i]; |     cell *c = dcal[i]; | ||||||
|     if(itemclass(c->item) == IC_ORB) return true; |     if(itemclass(c->item) == IC_ORB) return true; | ||||||
|     } |     } | ||||||
|   else if(sphere_narcm) for(int i=0; i<spherecells(); i++) { |   else if(sphere_narcm && DIM == 2) for(int i=0; i<spherecells(); i++) { | ||||||
|     cell *c = getDodecahedron(i)->c7; |     cell *c = getDodecahedron(i)->c7; | ||||||
|     if(itemclass(c->item) == IC_ORB) return true; |     if(itemclass(c->item) == IC_ORB) return true; | ||||||
|     forCellEx(c2, c) if(itemclass(c2->item) == IC_ORB) return true; |     forCellEx(c2, c) if(itemclass(c2->item) == IC_ORB) return true; | ||||||
| @@ -466,7 +466,7 @@ void wandering() { | |||||||
|         } |         } | ||||||
|       if(!peace::on && c->land == laKraken && ((sphere && !hrand(15)) || wchance(items[itKraken], 240)) && !kraken_pseudohept(c)) { |       if(!peace::on && c->land == laKraken && ((sphere && !hrand(15)) || wchance(items[itKraken], 240)) && !kraken_pseudohept(c)) { | ||||||
|         bool b = sphere || canReachPlayer(c, moKrakenH); |         bool b = sphere || canReachPlayer(c, moKrakenH); | ||||||
|         if(sphere_narcm && (haveKraken() || !items[itOrbFish])) {  |         if(sphere_narcm && DIM == 2 && (haveKraken() || !items[itOrbFish])) {  | ||||||
|           c->monst = moViking; c->wall = waBoat; c->item = itOrbFish;  |           c->monst = moViking; c->wall = waBoat; c->item = itOrbFish;  | ||||||
|           playSeenSound(c); |           playSeenSound(c); | ||||||
|           continue; |           continue; | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								polygons.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								polygons.cpp
									
									
									
									
									
								
							| @@ -497,8 +497,15 @@ void glapplymatrix(const transmatrix& V) { | |||||||
|   GLfloat mat[16]; |   GLfloat mat[16]; | ||||||
|   int id = 0; |   int id = 0; | ||||||
|   if(DIM == 3) { |   if(DIM == 3) { | ||||||
|     for(int y=0; y<4; y++) { |     if(elliptic && spherephase < 2) { | ||||||
|       for(int x=0; x<4; x++) mat[id++] = V[x][y]; |       for(int y=0; y<4; y++) { | ||||||
|  |         for(int x=0; x<4; x++) mat[id++] = -V[x][y]; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     else { | ||||||
|  |       for(int y=0; y<4; y++) { | ||||||
|  |         for(int x=0; x<4; x++) mat[id++] = V[x][y]; | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|     glhr::set_modelview(glhr::as_glmatrix(mat)); |     glhr::set_modelview(glhr::as_glmatrix(mat)); | ||||||
|     return; |     return; | ||||||
| @@ -1483,6 +1490,7 @@ void drawqueue() { | |||||||
|      |      | ||||||
|   if(sphere && DIM == 3) { |   if(sphere && DIM == 3) { | ||||||
|     for(int p: {0, 1, 2, 3}) { |     for(int p: {0, 1, 2, 3}) { | ||||||
|  |       if(elliptic && p < 2) continue; | ||||||
|       if(p == 1 || p == 3) { |       if(p == 1 || p == 3) { | ||||||
|   #ifdef GL_ES |   #ifdef GL_ES | ||||||
|         glClearDepthf(1.0f); |         glClearDepthf(1.0f); | ||||||
| @@ -1504,6 +1512,10 @@ void drawqueue() { | |||||||
|       spherephase = p; |       spherephase = p; | ||||||
|       current_display->set_projection(0, true); |       current_display->set_projection(0, true); | ||||||
|       for(auto& ptd: ptds) ptd->draw(); |       for(auto& ptd: ptds) ptd->draw(); | ||||||
|  |       if(elliptic) { | ||||||
|  |         spherephase = p - 2; | ||||||
|  |         for(auto& ptd: ptds) ptd->draw(); | ||||||
|  |         } | ||||||
|       // glflush(); |       // glflush(); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								sphere.cpp
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								sphere.cpp
									
									
									
									
									
								
							| @@ -172,6 +172,8 @@ vector<int> adj0; | |||||||
| array<array<int, 4>, 120> js; | array<array<int, 4>, 120> js; | ||||||
| array<hyperpoint, 60> dodefaces; | array<hyperpoint, 60> dodefaces; | ||||||
|  |  | ||||||
|  | int opposite[120]; | ||||||
|  |  | ||||||
| hyperpoint zero4; | hyperpoint zero4; | ||||||
|  |  | ||||||
| int root; | int root; | ||||||
| @@ -183,6 +185,7 @@ ld norm(hyperpoint a, hyperpoint b) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| void gen600() { | void gen600() { | ||||||
|  |   dynamicval<eGeometry> gp(geometry, gCell120); | ||||||
|   vertices120.clear(); |   vertices120.clear(); | ||||||
|   root = 23; |   root = 23; | ||||||
|    |    | ||||||
| @@ -274,6 +277,10 @@ void gen600() { | |||||||
|    |    | ||||||
|   adj0.clear(); |   adj0.clear(); | ||||||
|   for(int i=0; i<120; i++) if(inedge[root][i]) adj0.push_back(i); |   for(int i=0; i<120; i++) if(inedge[root][i]) adj0.push_back(i); | ||||||
|  |  | ||||||
|  |   for(int i=0; i<120; i++) for(int j=0; j<120; j++) | ||||||
|  |     if(hdist(vertices120[i], vertices120[j]) > 3) | ||||||
|  |       opposite[i] = j; | ||||||
|    |    | ||||||
|   using namespace hyperpoint_vec; |   using namespace hyperpoint_vec; | ||||||
|    |    | ||||||
| @@ -303,12 +310,26 @@ void gen600() { | |||||||
|   printf("id = %d\n", id); |   printf("id = %d\n", id); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | bool goodside(int i) { | ||||||
|  |   if(!elliptic) return true; | ||||||
|  |   hyperpoint& h = vertices120[i]; | ||||||
|  |   for(int k=3; k>=0; k--) { | ||||||
|  |     if(h[k] > 1e-3) return true; | ||||||
|  |     if(h[k] < -1e-3) return false; | ||||||
|  |     } | ||||||
|  |   return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
| struct hrmap_spherical3 : hrmap { | struct hrmap_spherical3 : hrmap { | ||||||
|   heptagon* cells[120]; |   heptagon* cells[120]; | ||||||
|  |  | ||||||
|   hrmap_spherical3() { |   hrmap_spherical3() { | ||||||
|     gen600(); |     gen600(); | ||||||
|     for(int i=0; i<120; i++) { |     for(int i=0; i<120; i++) { | ||||||
|  |       if(!goodside(i)) { | ||||||
|  |         cells[i] = NULL; | ||||||
|  |         continue; | ||||||
|  |         } | ||||||
|       cells[i] = tailored_alloc<heptagon> (12); |       cells[i] = tailored_alloc<heptagon> (12); | ||||||
|       heptagon& h = *(cells[i]); |       heptagon& h = *(cells[i]); | ||||||
|       h.s = hsOrigin; |       h.s = hsOrigin; | ||||||
| @@ -323,12 +344,14 @@ struct hrmap_spherical3 : hrmap { | |||||||
|       h.c7 = newCell(12, &h);       |       h.c7 = newCell(12, &h);       | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     for(int i=0; i<120; i++) { |     for(int i=0; i<120; i++) if(cells[i]) { | ||||||
|       for(int k=0; k<12; k++) { |       for(int k=0; k<12; k++) { | ||||||
|         hyperpoint which = vmatrix120[i] * inverse(vmatrix120[root]) * vertices120[adj0[k]]; |         hyperpoint which = vmatrix120[i] * inverse(vmatrix120[root]) * vertices120[adj0[k]]; | ||||||
|         for(int s=0; s<120; s++) if(hdist(which, vertices120[s]) < 1e-6) { |         for(int s=0; s<120; s++) if(hdist(which, vertices120[s]) < 1e-6) { | ||||||
|           cells[i]->move(k) = cells[s]; |           int s1 = s; | ||||||
|           println(hlog, i,".",k, " -> ", s, " ; ", js[i], " distance = ", hdist(vertices120[i], vertices120[s])); |           if(!cells[s1]) continue; | ||||||
|  |           cells[i]->move(k) = cells[s1]; | ||||||
|  |           println(hlog, i,".",k, " -> ", s1, " ; ", js[i], " distance = ", hdist(vertices120[i], vertices120[s])); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -336,14 +359,14 @@ struct hrmap_spherical3 : hrmap { | |||||||
|     for(int i=0; i<120; i++) |     for(int i=0; i<120; i++) | ||||||
|       for(int k=0; k<12; k++)  |       for(int k=0; k<12; k++)  | ||||||
|         for(int l=0; l<12; l++) |         for(int l=0; l<12; l++) | ||||||
|           if(cells[i]->move(k)->move(l) == cells[i]) |           if(cells[i] && cells[i]->move(k)->move(l) == cells[i]) | ||||||
|             cells[i]->c.setspin(k, l, false); |             cells[i]->c.setspin(k, l, false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   heptagon *getOrigin() { return cells[root]; } |   heptagon *getOrigin() { return cells[root]; } | ||||||
|  |  | ||||||
|   ~hrmap_spherical3() { |   ~hrmap_spherical3() { | ||||||
|     for(int i=0; i<120; i++) tailored_delete(cells[i]); |     for(int i=0; i<120; i++) if(cells[i]) tailored_delete(cells[i]); | ||||||
|     }     |     }     | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| @@ -358,21 +381,20 @@ transmatrix relative_matrix(heptagon *h2, heptagon *h1) { | |||||||
| void draw() { | void draw() { | ||||||
|   auto m = (hrmap_spherical3*) currentmap; |   auto m = (hrmap_spherical3*) currentmap; | ||||||
|  |  | ||||||
|   int old = viewctr.at->zebraval; |   for(int i=0; i<120; i++) if(m->cells[i]) | ||||||
|  |  | ||||||
|   for(int i=0; i<120; i++) |  | ||||||
|     drawcell(m->cells[i]->c7, View * relative_matrix(m->cells[i], viewctr.at), 0, false); |     drawcell(m->cells[i]->c7, View * relative_matrix(m->cells[i], viewctr.at), 0, false); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void makewax(int x) { | void makewax(int x) { | ||||||
|  |   int waxcenter = 63; | ||||||
|   auto m = (hrmap_spherical3*) currentmap; |   auto m = (hrmap_spherical3*) currentmap; | ||||||
|   for(int i=0; i<120; i++) m->cells[i]->c7->wall = waNone; |   for(int i=0; i<120; i++) if(m->cells[i]) m->cells[i]->c7->wall = waNone; | ||||||
|   m->cells[70]->c7->wall = waDune; |   m->cells[waxcenter]->c7->wall = waDune; | ||||||
|   int cols[16] = {0x202020, 0x2020A0, 0x20A020, 0x20A0A0, 0xA02020, 0xA020A0, 0xA0A020, 0xA0A0A0, |   int cols[16] = {0x202020, 0x2020A0, 0x20A020, 0x20A0A0, 0xA02020, 0xA020A0, 0xA0A020, 0xA0A0A0, | ||||||
|     0x606060, 0x6060FF, 0x60FF60, 0x60FFFF, 0xFF6060, 0xFF60FF, 0xFFFF60, 0xFFFFFF }; |     0x606060, 0x6060FF, 0x60FF60, 0x60FFFF, 0xFF6060, 0xFF60FF, 0xFFFF60, 0xFFFFFF }; | ||||||
|   if(x) for(int i=0; i<12; i++) { |   if(x) for(int i=0; i<12; i++) { | ||||||
|     m->cells[70]->c7->move(i)->wall = waWaxWall; |     m->cells[waxcenter]->c7->move(i)->wall = waWaxWall; | ||||||
|     m->cells[70]->c7->move(i)->landparam = cols[i]; |     m->cells[waxcenter]->c7->move(i)->landparam = cols[i]; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1194,7 +1194,7 @@ void set_geometry(eGeometry target) { | |||||||
|     if(DUAL && geometry != gArchimedean)  |     if(DUAL && geometry != gArchimedean)  | ||||||
|       variation = ginf[geometry].default_variation; |       variation = ginf[geometry].default_variation; | ||||||
|     #if CAP_BT |     #if CAP_BT | ||||||
|     if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling, gCell120)) variation = eVariation::pure; |     if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling, gCell120, gECell120)) variation = eVariation::pure; | ||||||
|     #endif |     #endif | ||||||
|     |     | ||||||
|     need_reset_geometry = true;  |     need_reset_geometry = true;  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ?
					?