3D:: elliptic space

This commit is contained in:
? 2019-02-25 18:13:09 +01:00 committed by Zeno Rogue
parent fb71d4fd15
commit fe174d8873
9 changed files with 64 additions and 24 deletions

View File

@ -1729,6 +1729,7 @@ vector<eLand> randlands = {
};
static const flagtype qsNONOR = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE;
static const flagtype qsNONORE = qsNONOR | qELLIPTIC;
static const flagtype qsBQ = qANYQ | qSMALL | qBOUNDED;
static const flagtype qsSMALL = qANYQ | qSMALL | qBOUNDED;
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 qsDOCKS = qANYQ | qSMALL | qBOUNDED | qDOCKS;
static const flagtype qsSMALLB = qSMALL | qBOUNDED;
static const flagtype qsSMALLBE = qsSMALLB | qELLIPTIC;
vector<geometryinfo> ginf = {
{"{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},
{"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},
{"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

View File

@ -214,7 +214,7 @@ enum eLand { laNone, laBarrier, laCrossroads, laDesert, laIce, laCaves, laJungle
enum eGeometry {
gNormal, gEuclid, gSphere, gElliptic, gZebraQuotient, gFieldQuotient, gTorus, gOctagon, g45, g46, g47, gSmallSphere, gTinySphere, gEuclidSquare, gSmallElliptic,
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};
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere };
@ -244,6 +244,8 @@ static const flagtype qFIELD = 16;
static const flagtype qDOCKS = 32;
static const flagtype qZEBRA = 64;
static const flagtype qELLIPTIC = 128;
// note: dnext assumes that x&7 equals 7
static const int SEE_ALL = 50;
static const int FORBIDDEN = -1;

View File

@ -361,6 +361,7 @@ void initConfig() {
addsaver(sightranges[gBinary3], "sight-binary3", 3);
addsaver(sightranges[gCubeTiling], "sight-cubes", 7);
addsaver(sightranges[gCell120], "sight-120cell", 2 * M_PI);
addsaver(sightranges[gECell120], "sight-120cell-elliptic", M_PI);
addsaver(vid.consider_shader_projection, "shader-projection", true);

View File

@ -8,15 +8,15 @@ namespace hr {
transmatrix &ggmatrix(cell *c);
void fixelliptic(transmatrix& at) {
if(elliptic && at[2][2] < 0) {
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
if(elliptic && at[DIM][DIM] < 0) {
for(int i=0; i<MDIM; i++) for(int j=0; j<MDIM; j++)
at[i][j] = -at[i][j];
}
}
void fixelliptic(hyperpoint& h) {
if(elliptic && h[2] < 0)
for(int i=0; i<3; i++) h[i] = -h[i];
if(elliptic && h[DIM] < 0)
for(int i=0; i<MDIM; i++) h[i] = -h[i];
}
transmatrix master_relative(cell *c, bool get_inverse) {

View File

@ -103,7 +103,7 @@ void addMessage(string s, char spamtype = 0);
#define sphere (cgclass == gcSphere)
#define hyperbolic (cgclass == gcHyperbolic)
#define nonorientable (ginf[geometry].flags & qNONORIENTABLE)
#define elliptic (sphere && nonorientable)
#define elliptic (ginf[geometry].flags & qELLIPTIC)
#define quotient (ginf[geometry].flags & qANYQ)
#define euwrap (quotient && euclid)
#define fulltorus (bounded && euclid)
@ -192,7 +192,7 @@ typedef complex<ld> cld;
#if MAXDIM == 3
#define DIM 2
#else
#define DIM ((geometry == gBinary3 || geometry == gCubeTiling || geometry == gCell120) ? 3 : 2)
#define DIM ((geometry == gBinary3 || geometry == gCubeTiling || geometry == gCell120 || geometry == gECell120) ? 3 : 2)
#endif
#define MDIM (DIM+1)

View File

@ -265,7 +265,7 @@ bool haveOrbPower() {
cell *c = dcal[i];
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;
if(itemclass(c->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)) {
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;
playSeenSound(c);
continue;

View File

@ -497,8 +497,15 @@ void glapplymatrix(const transmatrix& V) {
GLfloat mat[16];
int id = 0;
if(DIM == 3) {
for(int y=0; y<4; y++) {
for(int x=0; x<4; x++) mat[id++] = V[x][y];
if(elliptic && spherephase < 2) {
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));
return;
@ -1483,6 +1490,7 @@ void drawqueue() {
if(sphere && DIM == 3) {
for(int p: {0, 1, 2, 3}) {
if(elliptic && p < 2) continue;
if(p == 1 || p == 3) {
#ifdef GL_ES
glClearDepthf(1.0f);
@ -1504,6 +1512,10 @@ void drawqueue() {
spherephase = p;
current_display->set_projection(0, true);
for(auto& ptd: ptds) ptd->draw();
if(elliptic) {
spherephase = p - 2;
for(auto& ptd: ptds) ptd->draw();
}
// glflush();
}
}

View File

@ -172,6 +172,8 @@ vector<int> adj0;
array<array<int, 4>, 120> js;
array<hyperpoint, 60> dodefaces;
int opposite[120];
hyperpoint zero4;
int root;
@ -183,6 +185,7 @@ ld norm(hyperpoint a, hyperpoint b) {
}
void gen600() {
dynamicval<eGeometry> gp(geometry, gCell120);
vertices120.clear();
root = 23;
@ -274,6 +277,10 @@ void gen600() {
adj0.clear();
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;
@ -303,12 +310,26 @@ void gen600() {
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 {
heptagon* cells[120];
hrmap_spherical3() {
gen600();
for(int i=0; i<120; i++) {
if(!goodside(i)) {
cells[i] = NULL;
continue;
}
cells[i] = tailored_alloc<heptagon> (12);
heptagon& h = *(cells[i]);
h.s = hsOrigin;
@ -323,12 +344,14 @@ struct hrmap_spherical3 : hrmap {
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++) {
hyperpoint which = vmatrix120[i] * inverse(vmatrix120[root]) * vertices120[adj0[k]];
for(int s=0; s<120; s++) if(hdist(which, vertices120[s]) < 1e-6) {
cells[i]->move(k) = cells[s];
println(hlog, i,".",k, " -> ", s, " ; ", js[i], " distance = ", hdist(vertices120[i], vertices120[s]));
int s1 = 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 k=0; k<12; k++)
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);
}
heptagon *getOrigin() { return cells[root]; }
~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() {
auto m = (hrmap_spherical3*) currentmap;
int old = viewctr.at->zebraval;
for(int i=0; i<120; i++)
for(int i=0; i<120; i++) if(m->cells[i])
drawcell(m->cells[i]->c7, View * relative_matrix(m->cells[i], viewctr.at), 0, false);
}
void makewax(int x) {
int waxcenter = 63;
auto m = (hrmap_spherical3*) currentmap;
for(int i=0; i<120; i++) m->cells[i]->c7->wall = waNone;
m->cells[70]->c7->wall = waDune;
for(int i=0; i<120; i++) if(m->cells[i]) m->cells[i]->c7->wall = waNone;
m->cells[waxcenter]->c7->wall = waDune;
int cols[16] = {0x202020, 0x2020A0, 0x20A020, 0x20A0A0, 0xA02020, 0xA020A0, 0xA0A020, 0xA0A0A0,
0x606060, 0x6060FF, 0x60FF60, 0x60FFFF, 0xFF6060, 0xFF60FF, 0xFFFF60, 0xFFFFFF };
if(x) for(int i=0; i<12; i++) {
m->cells[70]->c7->move(i)->wall = waWaxWall;
m->cells[70]->c7->move(i)->landparam = cols[i];
m->cells[waxcenter]->c7->move(i)->wall = waWaxWall;
m->cells[waxcenter]->c7->move(i)->landparam = cols[i];
}
}

View File

@ -1194,7 +1194,7 @@ void set_geometry(eGeometry target) {
if(DUAL && geometry != gArchimedean)
variation = ginf[geometry].default_variation;
#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
need_reset_geometry = true;