mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	3D:: cube tiling
This commit is contained in:
		
							
								
								
									
										4
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -1236,6 +1236,7 @@ void initcells() { | |||||||
|   else if(archimedean) currentmap = arcm::new_map(); |   else if(archimedean) currentmap = arcm::new_map(); | ||||||
|   #endif |   #endif | ||||||
|   else if(fulltorus) currentmap = new hrmap_torus; |   else if(fulltorus) currentmap = new hrmap_torus; | ||||||
|  |   else if(euclid && DIM == 3) currentmap = space::new_map(); | ||||||
|   else if(euclid) currentmap = new hrmap_euclidean; |   else if(euclid) currentmap = new hrmap_euclidean; | ||||||
|   else if(sphere) currentmap = new hrmap_spherical; |   else if(sphere) currentmap = new hrmap_spherical; | ||||||
|   else if(quotient) currentmap = new quotientspace::hrmap_quotient; |   else if(quotient) currentmap = new quotientspace::hrmap_quotient; | ||||||
| @@ -1871,6 +1872,9 @@ int celldistance(cell *c1, cell *c2) { | |||||||
|   if(binarytiling && DIM == 3)  |   if(binarytiling && DIM == 3)  | ||||||
|     return binary::celldistance3(c1, c2); |     return binary::celldistance3(c1, c2); | ||||||
|  |  | ||||||
|  |   if(euclid && DIM == 3)  | ||||||
|  |     return space::celldistance(c1, c2); | ||||||
|  |  | ||||||
|   return hyperbolic_celldistance(c1, c2); |   return hyperbolic_celldistance(c1, c2); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1765,7 +1765,8 @@ vector<geometryinfo> ginf = { | |||||||
|   {"{12,3}","M4",       "Schmutz's M(4)",                             "M4",      12, 3, qsSMALL,   gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated}, |   {"{12,3}","M4",       "Schmutz's M(4)",                             "M4",      12, 3, qsSMALL,   gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated}, | ||||||
|   {"{6,4}", "Crystal",  "dimensional crystal",                        "Crystal",  6, 4, qANYQ,     gcHyperbolic, 0x28000, {{5, 3}}, eVariation::pure}, |   {"{6,4}", "Crystal",  "dimensional crystal",                        "Crystal",  6, 4, qANYQ,     gcHyperbolic, 0x28000, {{5, 3}}, eVariation::pure}, | ||||||
|   {"{3,4}", "none",     "{3,4} (octahedron)",                         "4x3",      3, 4, qsSMALLB,  gcSphere,     0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, |   {"{3,4}", "none",     "{3,4} (octahedron)",                         "4x3",      3, 4, qsSMALLB,  gcSphere,     0x28200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, | ||||||
|   {"bin3",  "none",     "3D binary tiling",                           "binary3",  9, 3, 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}, | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| // 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, |   gMacbeath, gBring, gSchmutzM2, gSchmutzM3, gCrystal, gOctahedron, gBinary3, gCubeTiling, | ||||||
|   gGUARD}; |   gGUARD}; | ||||||
|  |  | ||||||
| enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; | enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere }; | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ | |||||||
| #include "heptagon.cpp" | #include "heptagon.cpp" | ||||||
| #include "binary-tiling.cpp" | #include "binary-tiling.cpp" | ||||||
| #include "archimedean.cpp" | #include "archimedean.cpp" | ||||||
|  | #include "space.cpp" | ||||||
| #include "crystal.cpp" | #include "crystal.cpp" | ||||||
| #include "language.cpp" | #include "language.cpp" | ||||||
| #include "cell.cpp" | #include "cell.cpp" | ||||||
|   | |||||||
| @@ -371,7 +371,7 @@ void ge_land_selection() { | |||||||
| vector<eGeometry> tilinglist = { | vector<eGeometry> tilinglist = { | ||||||
|   gTinySphere, gSmallSphere, gSphere, gEuclid, gNormal, gOctagon, |   gTinySphere, gSmallSphere, gSphere, gEuclid, gNormal, gOctagon, | ||||||
|   gOctahedron, gEuclidSquare, g45, g46, g47, |   gOctahedron, gEuclidSquare, g45, g46, g47, | ||||||
|   gArchimedean, gBinaryTiling, gBinary3 |   gArchimedean, gBinaryTiling, gBinary3, gCubeTiling | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| vector<eGeometry> quotientlist = { | vector<eGeometry> quotientlist = { | ||||||
|   | |||||||
| @@ -92,6 +92,9 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin | |||||||
|   #if CAP_BT |   #if CAP_BT | ||||||
|   if(binarytiling) return binary::relative_matrix(c2->master, c1->master); |   if(binarytiling) return binary::relative_matrix(c2->master, c1->master); | ||||||
|   #endif |   #endif | ||||||
|  |   #if MAXDIM == 4 | ||||||
|  |   if(euclid && DIM == 3) return space::relative_matrix(c2->master, c1->master); | ||||||
|  |   #endif | ||||||
|   #if CAP_ARCM |   #if CAP_ARCM | ||||||
|   if(archimedean) return arcm::relative_matrix(c2->master, c1->master); |   if(archimedean) return arcm::relative_matrix(c2->master, c1->master); | ||||||
|   #endif |   #endif | ||||||
|   | |||||||
| @@ -4598,9 +4598,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|  |  | ||||||
|           const int darkval[9] = {0,1,1,0,3,3,4,4,0}; |           const int darkval[9] = {0,1,1,0,3,3,4,4,0}; | ||||||
|           int d = (asciicol & 0xF0F0F0) >> 3; |           int d = (asciicol & 0xF0F0F0) >> 3; | ||||||
|           for(int a=0; a<9; a++) |           for(int a=0; a<c->type; a++) | ||||||
|             if(c->move(a) && !isWall(c->move(a))) { |             if(c->move(a) && !isWall(c->move(a))) { | ||||||
|               if(a < 4) { |               if(a < 4 && hyperbolic) { | ||||||
|                 if(celldistAlt(c) >= celldistAlt(viewctr.at->c7)) continue; |                 if(celldistAlt(c) >= celldistAlt(viewctr.at->c7)) continue; | ||||||
|                 dynamicval<color_t> p (poly_outline, 0); |                 dynamicval<color_t> p (poly_outline, 0); | ||||||
|                 queuepoly(V, shBinaryWall[a], darkena(asciicol - d * darkval[a], 0, 0xFF)); |                 queuepoly(V, shBinaryWall[a], darkena(asciicol - d * darkval[a], 0, 0xFF)); | ||||||
| @@ -5709,6 +5709,10 @@ void drawthemap() { | |||||||
|   else if(archimedean) |   else if(archimedean) | ||||||
|     arcm::draw(); |     arcm::draw(); | ||||||
|   #endif |   #endif | ||||||
|  |   #if MAXDIM == 4 | ||||||
|  |   else if(euclid && DIM == 3) | ||||||
|  |     space::draw(); | ||||||
|  |   #endif | ||||||
|   else |   else | ||||||
|     drawStandard(); |     drawStandard(); | ||||||
|   drawWormSegments(); |   drawWormSegments(); | ||||||
|   | |||||||
| @@ -231,6 +231,10 @@ heptagon *createStep(heptagon *h, int d) { | |||||||
|   if(!h->move(d) && binarytiling && DIM == 3)  |   if(!h->move(d) && binarytiling && DIM == 3)  | ||||||
|     return binary::createStep3(h, d); |     return binary::createStep3(h, d); | ||||||
|   #endif |   #endif | ||||||
|  |   #if MAXDIM == 4 | ||||||
|  |   if(!h->move(d) && euclid && DIM == 3)  | ||||||
|  |     return space::createStep(h, d); | ||||||
|  |   #endif | ||||||
|   #if CAP_ARCM |   #if CAP_ARCM | ||||||
|   if(!h->move(d) && archimedean) { |   if(!h->move(d) && archimedean) { | ||||||
|     arcm::create_adjacent(h, d);  |     arcm::create_adjacent(h, d);  | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -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 ? 3 : 2) | #define DIM ((geometry == gBinary3 || geometry == gCubeTiling) ? 3 : 2) | ||||||
| #endif | #endif | ||||||
| #define MDIM (DIM+1) | #define MDIM (DIM+1) | ||||||
|  |  | ||||||
| @@ -4238,6 +4238,14 @@ namespace binary { | |||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if MAXDIM == 4 | ||||||
|  | namespace space { | ||||||
|  |   heptagon *createStep(heptagon *parent, int d); | ||||||
|  |   hrmap* new_map(); | ||||||
|  |   void draw(); | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| namespace arcm { | namespace arcm { | ||||||
|   #if CAP_ARCM |   #if CAP_ARCM | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								hypgraph.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								hypgraph.cpp
									
									
									
									
									
								
							| @@ -1107,9 +1107,9 @@ void optimizeview() { | |||||||
|    |    | ||||||
|   if(0) ; |   if(0) ; | ||||||
|  |  | ||||||
|   #if CAP_BT || CAP_ARCM |   #if CAP_BT || CAP_ARCM || MAXDIM == 4 | ||||||
|   else if(binarytiling || archimedean) { |   else if(binarytiling || archimedean || (euclid && DIM == 3)) { | ||||||
|     turn = -1, best = View[DIM][DIM]; |     turn = -1, best = hdist0(tC0(View)); | ||||||
|     for(int i=0; i<viewctr.at->c7->type; i++) { |     for(int i=0; i<viewctr.at->c7->type; i++) { | ||||||
|       int i1 = i * DUALMUL; |       int i1 = i * DUALMUL; | ||||||
|       heptagon *h2 = createStep(viewctr.at, i1); |       heptagon *h2 = createStep(viewctr.at, i1); | ||||||
| @@ -1117,11 +1117,14 @@ void optimizeview() { | |||||||
|       #if CAP_BT |       #if CAP_BT | ||||||
|       if(binarytiling) T = binary::relative_matrix(h2, viewctr.at); |       if(binarytiling) T = binary::relative_matrix(h2, viewctr.at); | ||||||
|       #endif |       #endif | ||||||
|  |       #if MAXDIM == 4 | ||||||
|  |       if(euclid && DIM == 3) T = space::relative_matrix(h2, viewctr.at); | ||||||
|  |       #endif | ||||||
|       #if CAP_ARCM |       #if CAP_ARCM | ||||||
|       if(archimedean)  T = arcm::relative_matrix(h2, viewctr.at); |       if(archimedean)  T = arcm::relative_matrix(h2, viewctr.at); | ||||||
|       #endif |       #endif | ||||||
|       hyperpoint H = View * tC0(T); |       hyperpoint H = View * tC0(T); | ||||||
|       ld quality = euclid ? hdist0(H) : H[DIM]; |       ld quality = hdist0(H); | ||||||
|       if(quality < best) best = quality, turn = i1, TB = T; |       if(quality < best) best = quality, turn = i1, TB = T; | ||||||
|       } |       } | ||||||
|     if(turn >= 0) { |     if(turn >= 0) { | ||||||
| @@ -1590,8 +1593,8 @@ bool do_draw(cell *c) { | |||||||
|  |  | ||||||
| bool do_draw(cell *c, const transmatrix& T) { | bool do_draw(cell *c, const transmatrix& T) { | ||||||
|   if(DIM == 3) { |   if(DIM == 3) { | ||||||
|     if(hyperbolic && V[DIM][DIM] > btrange_cosh) return false; |     if(hyperbolic && T[DIM][DIM] > binary::btrange_cosh) return false; | ||||||
|     if(euclid && hypot_d(tC0(T), 3)) return false; |     if(euclid && hypot_d(tC0(T), 3) > 10) return false; | ||||||
|     setdist(c, 7, c); |     setdist(c, 7, c); | ||||||
|     return true; |     return true; | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								polygons.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								polygons.cpp
									
									
									
									
									
								
							| @@ -2436,7 +2436,7 @@ void buildpolys() { | |||||||
|   bshape(shDragonNostril, PPR::ONTENTACLE_EYES, scalefactor, 241); |   bshape(shDragonNostril, PPR::ONTENTACLE_EYES, scalefactor, 241); | ||||||
|   bshape(shDragonHead, PPR::ONTENTACLE, scalefactor, 242); |   bshape(shDragonHead, PPR::ONTENTACLE, scalefactor, 242); | ||||||
|    |    | ||||||
|   if(DIM == 3) { |   if(DIM == 3 && binarytiling) { | ||||||
|     make_wall(shBinaryWall[0], 0,0,-1, -1,0,-1, 0,-1,-1, 2); |     make_wall(shBinaryWall[0], 0,0,-1, -1,0,-1, 0,-1,-1, 2); | ||||||
|     make_wall(shBinaryWall[1], 0,0,-1, +1,0,-1, 0,-1,-1, 2); |     make_wall(shBinaryWall[1], 0,0,-1, +1,0,-1, 0,-1,-1, 2); | ||||||
|     make_wall(shBinaryWall[2], 0,0,-1, -1,0,-1, 0,+1,-1, 2); |     make_wall(shBinaryWall[2], 0,0,-1, -1,0,-1, 0,+1,-1, 2); | ||||||
| @@ -2448,6 +2448,22 @@ void buildpolys() { | |||||||
|     make_wall(shBinaryWall[8], 1,1,+1, -1,1,+1, 1,-1,+1, 0); |     make_wall(shBinaryWall[8], 1,1,+1, -1,1,+1, 1,-1,+1, 0); | ||||||
|     } |     } | ||||||
|    |    | ||||||
|  |   if(DIM == 3 && euclid) { | ||||||
|  |     for(int w=0; w<6; w++) { | ||||||
|  |       bshape(shBinaryWall[w], PPR::WALL); | ||||||
|  |       for(int a=0; a<=4; a++) { | ||||||
|  |         int t[3]; | ||||||
|  |         t[0] = (w&1) ? -1 : 1; | ||||||
|  |         t[1] = among(a, 0, 3, 4) ? -1 : 1; | ||||||
|  |         t[2] = among(a, 2, 3) ? -1 : 1; | ||||||
|  |         int x = w/2; | ||||||
|  |         int y = (x+2)%3; | ||||||
|  |         int z = (y+2)%3; | ||||||
|  |         hpcpush(hpxy3(t[x]/2., t[y]/2., t[z]/2.)); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |    | ||||||
|   ld krsc = 1; |   ld krsc = 1; | ||||||
|   if(sphere) krsc *= 1.4; |   if(sphere) krsc *= 1.4; | ||||||
|   if(S7 ==8) krsc *= 1.3; |   if(S7 ==8) krsc *= 1.3; | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								space.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								space.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | // Hyperbolic Rogue -- euclidean 3D geometry | ||||||
|  | // Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details | ||||||
|  |  | ||||||
|  | namespace hr { | ||||||
|  |  | ||||||
|  | #if DIM == 3 | ||||||
|  | namespace space { | ||||||
|  |  | ||||||
|  |   typedef long long coord; | ||||||
|  |    | ||||||
|  |   struct hrmap_cube : hrmap { | ||||||
|  |     map<coord, heptagon*> spacemap; | ||||||
|  |     map<heptagon*, coord> ispacemap; | ||||||
|  |     hrmap_cube() { | ||||||
|  |       getOrigin(); | ||||||
|  |       } | ||||||
|  |     heptagon *getOrigin() { | ||||||
|  |       return get_at(0); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     heptagon *get_at(coord at) { | ||||||
|  |       if(spacemap.count(at))  | ||||||
|  |         return spacemap[at]; | ||||||
|  |       else { | ||||||
|  |         auto h = tailored_alloc<heptagon> (6); | ||||||
|  |         h->c7 = newCell(6, h); | ||||||
|  |         h->distance = 0; | ||||||
|  |         h->cdata = NULL; | ||||||
|  |         spacemap[at] = h; | ||||||
|  |         ispacemap[h] = at; | ||||||
|  |         return h; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     heptagon *build(heptagon *parent, int d, coord at) { | ||||||
|  |       auto h = get_at(at); | ||||||
|  |       h->c.connect(d^1, parent, d, false); | ||||||
|  |       return h; | ||||||
|  |       } | ||||||
|  |    | ||||||
|  |     heptagon *createStep(heptagon *parent, int d) { | ||||||
|  |       int at = ispacemap[parent]; | ||||||
|  |       coord shifttable[6] = { +1, -1, +1000, -1000, +1000000, -1000000 }; | ||||||
|  |       return build(parent, d, at + shifttable[d]); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  |    | ||||||
|  |   hrmap_cube* cubemap() { | ||||||
|  |     return ((hrmap_cube*) currentmap); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   hrmap* new_map() { | ||||||
|  |     return new hrmap_cube; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   heptagon *createStep(heptagon *parent, int d) { | ||||||
|  |     return cubemap()->createStep(parent, d); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   int getcoord(coord x, int a) {  | ||||||
|  |     for(int k=0; k<a; k++) { x -= getcoord(x, 0); x /= 1000; } | ||||||
|  |     x %= 1000;  | ||||||
|  |     if(x>500) x -= 1000;  | ||||||
|  |     if(x<-500) x += 500;  | ||||||
|  |     return x;  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   void draw() { | ||||||
|  |     dq::visited.clear(); | ||||||
|  |     dq::enqueue(viewctr.at, cview()); | ||||||
|  |      | ||||||
|  |     while(!dq::drawqueue.empty()) { | ||||||
|  |       auto& p = dq::drawqueue.front(); | ||||||
|  |       heptagon *h = get<0>(p); | ||||||
|  |       transmatrix V = get<1>(p); | ||||||
|  |       dynamicval<ld> b(band_shift, get<2>(p)); | ||||||
|  |       bandfixer bf(V); | ||||||
|  |       dq::drawqueue.pop(); | ||||||
|  |              | ||||||
|  |       cell *c = h->c7; | ||||||
|  |       if(!do_draw(c, V)) continue; | ||||||
|  |       drawcell(c, V, 0, false); | ||||||
|  |  | ||||||
|  |       for(int i=0; i<6; i++) | ||||||
|  |         dq::enqueue(h->move(i), V * cpush(i>>1, (i&1) ? -1 : 1)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   transmatrix relative_matrix(heptagon *h2, heptagon *h1) { | ||||||
|  |     auto cm = cubemap(); | ||||||
|  |     coord a = cm->ispacemap[h2] - cm->ispacemap[h1]; | ||||||
|  |     return eupush3(getcoord(a, 0), getcoord(a, 1), getcoord(a, 2)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   int celldistance(cell *c1, cell *c2) { | ||||||
|  |     auto cm = cubemap(); | ||||||
|  |     coord a = cm->ispacemap[c1->master] - cm->ispacemap[c2->master]; | ||||||
|  |     return getcoord(a, 0) + getcoord(a, 1) + getcoord(a, 2); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  | } | ||||||
| @@ -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)) variation = eVariation::pure; |     if(among(geometry, gBinaryTiling, gBinary3, gCubeTiling)) variation = eVariation::pure; | ||||||
|     #endif |     #endif | ||||||
|     |     | ||||||
|     need_reset_geometry = true;  |     need_reset_geometry = true;  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 ?
					?