mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-03-29 06:47:03 +00:00
notknot:: more spaces
This commit is contained in:
parent
242b601a51
commit
e5bbac6010
@ -14,14 +14,33 @@ compile with: mymake rogueviz/notknot
|
|||||||
|
|
||||||
the video has been created with the following options:
|
the video has been created with the following options:
|
||||||
|
|
||||||
|
older Euclidean
|
||||||
|
|
||||||
https://youtu.be/1TMY2U4_9Qg
|
https://youtu.be/1TMY2U4_9Qg
|
||||||
nk_margin=2 -noplayer -canvas-random 20 -geo notknot -sight3 0.5 -ray-cells 600000 smooth_scrolling=1 camspd=10 panini_alpha=1 fov=150 -shot-hd ray_exp_decay_poly=30 ray_fixed_map=1
|
nk_margin=2 -noplayer -canvas-random 20 -geo notknot -sight3 0.5 -ray-cells 600000 smooth_scrolling=1 camspd=10 panini_alpha=1 fov=150 -shot-hd ray_exp_decay_poly=30 ray_fixed_map=1
|
||||||
|
|
||||||
|
better Euclidean
|
||||||
|
|
||||||
https://youtu.be/eb2DhCcGH7U
|
https://youtu.be/eb2DhCcGH7U
|
||||||
nk_margin=4 -noplayer -canvas-random 20 -geo notknot -sight3 0.5 -ray-cells 600000 smooth_scrolling=1 camspd=10 panini_alpha=1 fov=150 -shot-hd ray_exp_decay_poly=30 ray_fixed_map=1 -ray-iter 100 ray_reflect_val=0.30
|
nk_margin=4 -noplayer -canvas-random 20 -geo notknot -sight3 0.5 -ray-cells 600000 smooth_scrolling=1 camspd=10 panini_alpha=1 fov=150 -shot-hd ray_exp_decay_poly=30 ray_fixed_map=1 -ray-iter 100 ray_reflect_val=0.30
|
||||||
|
|
||||||
|
self-hiding Euclidean
|
||||||
|
|
||||||
https://youtu.be/vFLZ2NGtuGw
|
https://youtu.be/vFLZ2NGtuGw
|
||||||
selfhide=1 loop=4 nk_margin=4 -noplayer -canvas-random 20 -geo notknot -sight3 0.5 -ray-cells 600000 smooth_scrolling=1 camspd=10 panini_alpha=1 fov=150 -shot-hd ray_exp_decay_poly=30 ray_fixed_map=1 -ray-iter 100 ray_reflect_val=0.30
|
selfhide=1 nk_loop=4 nk_margin=4 -noplayer -canvas-random 20 -geo notknot -sight3 0.5 -ray-cells 600000 smooth_scrolling=1 camspd=10 panini_alpha=1 fov=150 -shot-hd ray_exp_decay_poly=30 ray_fixed_map=1 -ray-iter 100 ray_reflect_val=0.30
|
||||||
|
|
||||||
|
penrose staircase in Nil
|
||||||
|
|
||||||
|
-noplayer nk_loop=6 nk_secondary=0 nk_terminate=9999999 -geo Nil -nilperiod 8 8 8 -nilwidth .25 -canvas-random 20 -nkbase -geo notknot ray_fixed_map=1 -ray-cells 600000 -sight3 1 -ray-range 1 3 -ray-random 1 -shot-1000
|
||||||
|
|
||||||
|
self-hiding knotted portal in S3
|
||||||
|
|
||||||
|
selfhide=1 -run nk_secondary=0 nk_terminate=9999999 nk_loop=4 -canvas-random 10 -load spherknot.lev -nkbase -nkbasemap spherknot.lev -PM nativ -fov 270 panini_alpha=1 -nk-volumetric -noplayer ray_fixed_map=1 -ray-cells 600000 -ray-iter 600
|
||||||
|
|
||||||
|
basic portal in S3:
|
||||||
|
|
||||||
|
nk_secondary=0 nk_terminate=99999 nk_loop=0 -nk-unloop 60 7 -canvas-random 10 -load spherring.lev -nkbase -nkbasemap spherring.lev -PM nativ -fov 270 panini_alpha=1 -nk-volumetric -noplayer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The algorithm here is as follows:
|
The algorithm here is as follows:
|
||||||
@ -47,18 +66,27 @@ namespace hr {
|
|||||||
|
|
||||||
namespace notknot {
|
namespace notknot {
|
||||||
|
|
||||||
|
void create_notknot();
|
||||||
|
|
||||||
/* how many times we need to loop around the portal frame to get back to the same space */
|
/* how many times we need to loop around the portal frame to get back to the same space */
|
||||||
/* the number of the worlds is: 1 (loop=1), 6 (loop=2), 24, 96, 600, infinity (loop>5) */
|
/* the number of the worlds is: 1 (loop=1), 6 (loop=2), 24, 96, 600, infinity (loop>5) */
|
||||||
int loop = 3;
|
int loop = 3;
|
||||||
|
|
||||||
|
/* any loop repeated loop_any times */
|
||||||
|
int loop_any = 0;
|
||||||
|
|
||||||
/* extra space around the knot */
|
/* extra space around the knot */
|
||||||
int margin = 4;
|
int margin = 4;
|
||||||
|
|
||||||
/* the scale factor for the knot */
|
/* the scale factor for the knot */
|
||||||
int knotsize = 3;
|
int knotsize = 3;
|
||||||
|
|
||||||
|
int secondary_percentage = 10;
|
||||||
|
|
||||||
int terminate_at = 500000000;
|
int terminate_at = 500000000;
|
||||||
|
|
||||||
|
string base_map = "";
|
||||||
|
|
||||||
/* make a self-hiding knot */
|
/* make a self-hiding knot */
|
||||||
bool self_hiding = false;
|
bool self_hiding = false;
|
||||||
|
|
||||||
@ -69,6 +97,8 @@ eGeometry gNotKnot(eGeometry(-1));
|
|||||||
* The generated instructions is the weird array in create_trifoil_knot()
|
* The generated instructions is the weird array in create_trifoil_knot()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
vector<vector<int> > to_unloop;
|
||||||
|
|
||||||
void gen_trifoil() {
|
void gen_trifoil() {
|
||||||
for(int len=2; len<=12; len+=2) {
|
for(int len=2; len<=12; len+=2) {
|
||||||
println(hlog, "trying len = ", len);
|
println(hlog, "trying len = ", len);
|
||||||
@ -142,6 +172,10 @@ void gen_trifoil() {
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eGeometry base = gCubeTiling;
|
||||||
|
|
||||||
|
const int arrsize = 12;
|
||||||
|
|
||||||
struct hrmap_notknot : hrmap {
|
struct hrmap_notknot : hrmap {
|
||||||
|
|
||||||
/* represents a path (may be partially identified) */
|
/* represents a path (may be partially identified) */
|
||||||
@ -153,15 +187,19 @@ struct hrmap_notknot : hrmap {
|
|||||||
/* what is has been merged into */
|
/* what is has been merged into */
|
||||||
ucover *merged_into;
|
ucover *merged_into;
|
||||||
/* connections in every direction */
|
/* connections in every direction */
|
||||||
ucover *ptr[6];
|
ucover *ptr[arrsize];
|
||||||
/* used for painting walls in a single color */
|
/* used for painting walls in a single color */
|
||||||
ucover *wall_merge;
|
ucover *wall_merge;
|
||||||
color_t wallcolor, wallcolor2;
|
color_t wallcolor, wallcolor2;
|
||||||
/* 0 = live, 1 = wall, 2 = merged, 4 = overflow */
|
/* 0 = live, 1 = wall, 2 = merged, 4 = overflow */
|
||||||
int state;
|
char state;
|
||||||
|
/* direction to the parent */
|
||||||
|
char parentdir;
|
||||||
/* index in the table `all` */
|
/* index in the table `all` */
|
||||||
int index;
|
int index;
|
||||||
ucover(heptagon *w, int s) { where = w; for(int i=0; i<6; i++) ptr[i] = nullptr; state = s; merged_into = nullptr; result = nullptr; wall_merge = this; }
|
ucover(heptagon *w, int s) { where = w; for(int i=0; i<arrsize; i++) ptr[i] = nullptr; state = s; merged_into = nullptr; result = nullptr; wall_merge = this; }
|
||||||
|
bool iswall() { return state & 1; }
|
||||||
|
bool nowall() { return !iswall(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* find-union algorithm for wall_merge */
|
/* find-union algorithm for wall_merge */
|
||||||
@ -189,7 +227,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
heptagon* at(int x, int y, int z) {
|
heptagon* at(int x, int y, int z) {
|
||||||
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
dynamicval<eGeometry> g(geometry, base);
|
||||||
dynamicval<hrmap*> m(currentmap, euc);
|
dynamicval<hrmap*> m(currentmap, euc);
|
||||||
euc::coord co = euc::basic_canonicalize({x, y, z});
|
euc::coord co = euc::basic_canonicalize({x, y, z});
|
||||||
|
|
||||||
@ -199,7 +237,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
/* make sure that where->move(d) and where->c.spin(d) are known */
|
/* make sure that where->move(d) and where->c.spin(d) are known */
|
||||||
void cmov(heptagon *where, int d) {
|
void cmov(heptagon *where, int d) {
|
||||||
if(where->move(d)) return;
|
if(where->move(d)) return;
|
||||||
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
dynamicval<eGeometry> g(geometry, base);
|
||||||
dynamicval<hrmap*> m(currentmap, euc);
|
dynamicval<hrmap*> m(currentmap, euc);
|
||||||
createStep(where, d);
|
createStep(where, d);
|
||||||
}
|
}
|
||||||
@ -238,42 +276,417 @@ struct hrmap_notknot : hrmap {
|
|||||||
|
|
||||||
return at(cmax[0], cmax[1], cmax[2]);
|
return at(cmax[0], cmax[1], cmax[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
heptagon *create_nil_knot() {
|
||||||
|
dynamicval<eGeometry> g(geometry, base);
|
||||||
|
dynamicval<hrmap*> m(currentmap, euc);
|
||||||
|
auto ac = currentmap->allcells();
|
||||||
|
for(cell *c: ac) c->master->zebraval = 0;
|
||||||
|
|
||||||
|
//ac[1]->master->zebraval = 1;
|
||||||
|
|
||||||
|
auto hept = [&] (int x, int y, int z) {
|
||||||
|
x = zgmod(x, nilv::nilperiod[0]);
|
||||||
|
y = zgmod(y, nilv::nilperiod[1]);
|
||||||
|
z = zgmod(z, nilv::nilperiod[2]);
|
||||||
|
return nilv::get_heptagon_at(nilv::mvec(x,y,z));
|
||||||
|
};
|
||||||
|
|
||||||
|
hept(-3, -3, -4)->zebraval |= 16;
|
||||||
|
|
||||||
|
heptagon* h0 = hept(-2, -2, 0);
|
||||||
|
auto h = h0;
|
||||||
|
|
||||||
|
for(int d: {4, 3, 1, 0})
|
||||||
|
for(int i=0; i<4; i++) {
|
||||||
|
h->zebraval |= 1;
|
||||||
|
h = h->cmove(d);
|
||||||
|
h->zebraval |= 1;
|
||||||
|
h = h->cmove(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(h != h0) { println(hlog, "not looped"); exit(1); }
|
||||||
|
|
||||||
|
hept(0, 0, 2)->zebraval |= 1;
|
||||||
|
hept(1, 0, 2)->zebraval |= 1;
|
||||||
|
// hept(2, 0, 2)->zebraval |= 1;
|
||||||
|
hept(-1, 0, 2)->zebraval |= 1;
|
||||||
|
// hept(-2, 0, 2)->zebraval |= 1;
|
||||||
|
// hept(0, 1, 2)->zebraval |= 1;
|
||||||
|
// hept(0, 2, 2)->zebraval |= 1;
|
||||||
|
// hept(0, -1, 2)->zebraval |= 1;
|
||||||
|
// hept(0, -2, 2)->zebraval |= 1;
|
||||||
|
|
||||||
|
for(int z=0; z<8; z++)
|
||||||
|
for(int x=-3; x<4; x++)
|
||||||
|
for(int y=-3; y<4; y++)
|
||||||
|
if(!(x>=-1 && x<=1 && y>=-1 && y<=1))
|
||||||
|
if(!(hept(x,y,z)->zebraval & 1))
|
||||||
|
hept(x, y, z)->zebraval |= 32;
|
||||||
|
|
||||||
|
return ac[0]->master;
|
||||||
|
}
|
||||||
|
|
||||||
|
heptagon *interpret_basemap() {
|
||||||
|
dynamicval<eGeometry> g(geometry, base);
|
||||||
|
dynamicval<hrmap*> m(currentmap, euc);
|
||||||
|
auto ac = currentmap->allcells();
|
||||||
|
|
||||||
|
/*
|
||||||
|
vector<cell*> wals;
|
||||||
|
|
||||||
|
for(cell *c: ac) if(c->wall == waPlatform) {
|
||||||
|
bool lone = true;
|
||||||
|
forCellEx(d, c) if(d->wall == waPlatform) lone = false;
|
||||||
|
if(!lone) wals.push_back(c);
|
||||||
|
}
|
||||||
|
cell *fst = nullptr;
|
||||||
|
|
||||||
|
for(cell *c: ac) if(c->wall != waPlatform) {
|
||||||
|
vector<int> dists;
|
||||||
|
for(cell *w: wals) dists.push_back(celldistance(w, c));
|
||||||
|
sort(dists.begin(), dists.end());
|
||||||
|
int su = 0; for(auto s: dists) su += s;
|
||||||
|
if(dists[0] >= 3 && !fst) fst = c;
|
||||||
|
c->wall = dists[0] >= 3 && (c != fst) ? waFloorA : waNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<cell*> tochg;
|
||||||
|
for(cell *c: ac) {
|
||||||
|
if(c->wall == waPlatform) continue;
|
||||||
|
if(c == fst || isNeighbor(c, fst)) continue;
|
||||||
|
bool adj = false;
|
||||||
|
forCellEx(d, c) if(d->wall == waFloorA) adj = true;
|
||||||
|
if(adj) tochg.push_back(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(cell *c: tochg) c->wall = waFloorA;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
50 000152 (1,1,2,2,3,3,4,4,4,4) SUM 28
|
||||||
|
50 000152 (2,2,2,2,3,3,3,3,4,4) SUM 28
|
||||||
|
10 000152 (3,3,3,3,3,3,3,3,3,3) SUM 30
|
||||||
|
*/
|
||||||
|
for(cell *c: ac) {
|
||||||
|
auto& m = c->master->zebraval;
|
||||||
|
m = 0;
|
||||||
|
/* if(among(c->wall, waFloorA, waFloorB))
|
||||||
|
m |= 32; */
|
||||||
|
if(c->wall == waPlatform)
|
||||||
|
m |= 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ac[0]->master;
|
||||||
|
}
|
||||||
|
|
||||||
|
heptagon *create_under() {
|
||||||
|
if(base_map != "")
|
||||||
|
return interpret_basemap();
|
||||||
|
if(base == gCubeTiling)
|
||||||
|
return create_trifoil_knot();
|
||||||
|
else if(base == gNil)
|
||||||
|
return create_nil_knot();
|
||||||
|
throw hr_exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool remove_marked_walls;
|
||||||
|
|
||||||
|
ucover *gen_adj(ucover *u, int d) {
|
||||||
|
if(u->ptr[d]) return u->ptr[d];
|
||||||
|
cmov(u->where, d);
|
||||||
|
auto x = u->where->move(d);
|
||||||
|
auto d1 = u->where->c.spin(d);
|
||||||
|
auto z = x->zebraval;
|
||||||
|
if(z & 6) {
|
||||||
|
throw hr_exception_str("zebraval failure!");
|
||||||
|
exit(3);
|
||||||
|
x->zebraval = 0;
|
||||||
|
}
|
||||||
|
if(remove_marked_walls && (z & 8))
|
||||||
|
z &=~ 9;
|
||||||
|
u->ptr[d] = new ucover(x, z & 15);
|
||||||
|
u->ptr[d]->ptr[d1] = u;
|
||||||
|
u->ptr[d]->index = isize(all);
|
||||||
|
u->ptr[d]->parentdir = d1;
|
||||||
|
all.push_back(u->ptr[d]);
|
||||||
|
return u->ptr[d];
|
||||||
|
};
|
||||||
|
|
||||||
|
void add_to_unify(ucover *a, ucover *b) {
|
||||||
|
if(a->where != b->where)
|
||||||
|
throw hr_exception_str("unification error");
|
||||||
|
unify.emplace_back(a, b);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool make_loop(ucover* u, int loopcount, const vector<int>& looplist) {
|
||||||
|
auto ux = u;
|
||||||
|
for(int iter=0; iter<loopcount; iter++)
|
||||||
|
for(int w: looplist) {
|
||||||
|
ux = gen_adj(ux, w);
|
||||||
|
if(ux->iswall()) return false;
|
||||||
|
}
|
||||||
|
add_to_unify(u, ux);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
set<heptagon*> analyzed;
|
||||||
|
|
||||||
|
transmatrix adj(ucover *u, int k) {
|
||||||
|
dynamicval<eGeometry> g(geometry, base);
|
||||||
|
dynamicval<hrmap*> m(currentmap, euc);
|
||||||
|
return currentmap->adj(u->where, k);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool adjacent_matrix(const transmatrix& Tk, const transmatrix& Tl) {
|
||||||
|
for(auto vk: cgi.vertices_only)
|
||||||
|
for(auto vl: cgi.vertices_only)
|
||||||
|
if(hdist(Tk * vk, Tl * vl) < .01)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool adjacent_face(ucover *u, int k, int l) {
|
||||||
|
if(base == gCubeTiling) return abs(k-l) != 3;
|
||||||
|
if(base == gNil) return abs(k-l) != 3;
|
||||||
|
return adjacent_matrix(adj(u, k), adj(u, l));
|
||||||
|
}
|
||||||
|
|
||||||
|
void unify_homotopies(ucover *u) {
|
||||||
|
/* unify homotopies */
|
||||||
|
if(base == gNil) {
|
||||||
|
make_loop(u, 1, {0, 2, 3, 5});
|
||||||
|
make_loop(u, 1, {1, 2, 4, 5});
|
||||||
|
make_loop(u, 1, {0, 1, 3, 4, 2});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(base == gCubeTiling) {
|
||||||
|
make_loop(u, 1, {0, 1, 3, 4});
|
||||||
|
make_loop(u, 1, {0, 2, 3, 5});
|
||||||
|
make_loop(u, 1, {1, 2, 4, 5});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& v: cgi.vertices_only) {
|
||||||
|
map<heptagon*, ucover*> visited;
|
||||||
|
vector<pair<ucover *, transmatrix>> q;
|
||||||
|
|
||||||
|
auto visit = [&] (ucover *u, const transmatrix& T) {
|
||||||
|
if(visited.count(u->where)) {
|
||||||
|
add_to_unify(u, visited[u->where]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
visited[u->where] = u;
|
||||||
|
q.emplace_back(u, T);
|
||||||
|
};
|
||||||
|
|
||||||
|
hyperpoint h = v;
|
||||||
|
visit(u, Id);
|
||||||
|
for(int i=0; i<isize(q); i++) {
|
||||||
|
auto u1 = q[i].first;
|
||||||
|
transmatrix T0 = q[i].second;
|
||||||
|
for(int i=0; i<u1->where->type; i++) {
|
||||||
|
auto u2 = gen_adj(u1, i);
|
||||||
|
if(u2->state != 0) continue;
|
||||||
|
auto T1 = T0 * adj(u1, i);
|
||||||
|
bool adjacent = false;
|
||||||
|
for(auto& v2: cgi.vertices_only)
|
||||||
|
if(hdist(T1 * v2, h) < 1e-5)
|
||||||
|
adjacent = true;
|
||||||
|
if(adjacent)
|
||||||
|
visit(u2, T1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map<heptagon*, vector<vector<int> > > uloops;
|
||||||
|
|
||||||
|
void unify_loops_general(ucover *u) {
|
||||||
|
int t = u->where->type;
|
||||||
|
if(uloops.count(u->where)) {
|
||||||
|
for(auto& ul: uloops[u->where])
|
||||||
|
make_loop(u, loop, ul);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uloops[u->where] = {};
|
||||||
|
for(int i=0; i<t; i++) {
|
||||||
|
auto u1 = gen_adj(u, i);
|
||||||
|
if(!(u1->state & 1)) continue;
|
||||||
|
if(u1->where->zebraval != 9) continue;
|
||||||
|
transmatrix M = adj(u, i);
|
||||||
|
|
||||||
|
map<heptagon*, int> camefrom;
|
||||||
|
vector<pair<ucover*, transmatrix>> visited;
|
||||||
|
|
||||||
|
auto visit = [&] (ucover *from, ucover *at, int ldir, const transmatrix& T) {
|
||||||
|
// println(hlog, from ? from->where : (heptagon*)nullptr, " -> ", at->where, " (", i, ")", " (reverse ", at->where->c.spin(i), ")");
|
||||||
|
if(camefrom.count(at->where)) {
|
||||||
|
vector<int> path;
|
||||||
|
vector<int> rpath;
|
||||||
|
|
||||||
|
while(at->where != u->where) {
|
||||||
|
int d = camefrom[at->where];
|
||||||
|
// println(hlog, "from ", at->where, " going back ", d);
|
||||||
|
rpath.push_back(at->where->c.spin(d));
|
||||||
|
at = gen_adj(at, d);
|
||||||
|
}
|
||||||
|
while(!rpath.empty()) { path.push_back(rpath.back()); rpath.pop_back(); }
|
||||||
|
path.push_back(ldir);
|
||||||
|
|
||||||
|
int st = 0;
|
||||||
|
|
||||||
|
while(from->where != u->where) {
|
||||||
|
int d = camefrom[from->where];
|
||||||
|
// println(hlog, "from ", from->where, " going ", d);
|
||||||
|
st++; if(st == 10) exit(1);
|
||||||
|
path.push_back(d);
|
||||||
|
from = gen_adj(from, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isize(path) == 8 && path[1] == path[2] && path[3] == path[4] && path[5] == path[6]) {
|
||||||
|
println(hlog, "path = ", path, " i=", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
uloops[u->where].push_back(path);
|
||||||
|
make_loop(u, loop, path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
camefrom[at->where] = ldir;
|
||||||
|
visited.emplace_back(at, T);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
visit(nullptr, u, -1, Id);
|
||||||
|
for(int vi=0; vi<isize(visited); vi++) {
|
||||||
|
auto at = visited[vi].first;
|
||||||
|
auto Ti = visited[vi].second;
|
||||||
|
|
||||||
|
for(int j=0; j<at->where->type; j++) {
|
||||||
|
if(j == camefrom[at->where]) continue;
|
||||||
|
auto u2 = gen_adj(at, j);
|
||||||
|
if(u2->state & 1) continue;
|
||||||
|
transmatrix Tj = Ti * adj(at, j);
|
||||||
|
bool adj = false;
|
||||||
|
for(auto v: cgi.vertices_only) for(auto v1: cgi.vertices_only)
|
||||||
|
if(hdist(M * v1, Tj * v) < 1e-3) adj = true;
|
||||||
|
|
||||||
|
if(adj) visit(at, u2, at->where->c.spin(j), Tj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unify_loops(ucover *u) {
|
||||||
|
/* try to make it finite */
|
||||||
|
bool special = false;
|
||||||
|
|
||||||
|
if(base_map == "" && base == gNil) {
|
||||||
|
special = true;
|
||||||
|
make_loop(u, loop, {0, 0, 2, 2, 2, 3, 3, 5, 5, 5});
|
||||||
|
if(u->where->zebraval & 16)
|
||||||
|
for(int dir: {0,1,2}) {
|
||||||
|
auto ux = u;
|
||||||
|
for(int iter=0; iter<nilv::nilperiod[dir]; iter++) {
|
||||||
|
ux = gen_adj(ux, dir);
|
||||||
|
if(ux->state != 0) goto next_dir;
|
||||||
|
}
|
||||||
|
println(hlog, "succeeded in direction ", dir);
|
||||||
|
add_to_unify(u, ux);
|
||||||
|
next_dir: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(base == gCubeTiling) {
|
||||||
|
special = true;
|
||||||
|
make_loop(u, loop, {0, 0, 1, 1, 3, 3, 4, 4});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(base == gCell120) {
|
||||||
|
special = true;
|
||||||
|
int t = u->where->type;
|
||||||
|
for(int i=0; i<t; i++)
|
||||||
|
for(int j=0; j<i; j++) {
|
||||||
|
auto u1 = u->ptr[i];
|
||||||
|
auto u2 = u->ptr[j];
|
||||||
|
if(!(u1->state & 0)) continue;
|
||||||
|
if(!(u2->state & 0)) continue;
|
||||||
|
auto ucur = u;
|
||||||
|
auto ulast = (ucover*) nullptr;
|
||||||
|
|
||||||
|
for(int step=0; step<5*loop; step++) {
|
||||||
|
for(int i=0; i<t; i++) {
|
||||||
|
auto ucand = ucur->ptr[i];
|
||||||
|
if(isNeighbor(ucand->where->c7, u1->where->c7) && isNeighbor(ucand->where->c7, u2->where->c7) && ucand != ulast) {
|
||||||
|
ulast = ucur, ucur = ucand;
|
||||||
|
goto next_step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto fail;
|
||||||
|
next_step: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_to_unify(u, ucur);
|
||||||
|
fail: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(loop && !special)
|
||||||
|
unify_loops_general(u);
|
||||||
|
|
||||||
|
if(u->where == all[0]->where)
|
||||||
|
for(auto& lo: to_unloop)
|
||||||
|
if(!make_loop(u, 1, lo))
|
||||||
|
throw hr_exception_str("given loop goes through a wall");
|
||||||
|
|
||||||
|
if(loop_any && u->where == all[0]->where) {
|
||||||
|
auto us = all[0];
|
||||||
|
for(int it=1; it<loop_any; it++) {
|
||||||
|
vector<int> pathback;
|
||||||
|
auto uc = u;
|
||||||
|
while(uc->parentdir != -1) {
|
||||||
|
pathback.push_back(uc->parentdir);
|
||||||
|
us = gen_adj(us, uc->parentdir);
|
||||||
|
uc = uc->ptr[(int) uc->parentdir];
|
||||||
|
}
|
||||||
|
if(it == 1) println(hlog, "pathback = ", pathback);
|
||||||
|
}
|
||||||
|
add_to_unify(us, u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map<heptagon*, int> indices;
|
||||||
|
|
||||||
hrmap_notknot() {
|
hrmap_notknot() {
|
||||||
|
|
||||||
if(1) {
|
try {
|
||||||
dynamicval<eGeometry> dg(geometry, gCubeTiling);
|
if(base_map != "") {
|
||||||
|
dynamicval<eGeometry> dg(geometry, geometry);
|
||||||
|
mapstream::loadMap(base_map);
|
||||||
|
base = geometry;
|
||||||
|
create_notknot();
|
||||||
|
euc = currentmap;
|
||||||
|
for(hrmap*& m: allmaps) if(m == euc) m = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dynamicval<eGeometry> dg(geometry, base);
|
||||||
initcells(); euc = currentmap;
|
initcells(); euc = currentmap;
|
||||||
for(hrmap*& m: allmaps) if(m == euc) m = NULL;
|
for(hrmap*& m: allmaps) if(m == euc) m = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
all.emplace_back(new ucover(create_trifoil_knot(), 0));
|
all.emplace_back(new ucover(create_under(), 0));
|
||||||
all[0]->index = 0;
|
all[0]->index = 0;
|
||||||
|
all[0]->parentdir = -1;
|
||||||
|
|
||||||
|
if(all[0]->where->zebraval & 1)
|
||||||
|
throw hr_exception_str("error: starting inside a wall");
|
||||||
|
|
||||||
|
remove_marked_walls = false;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
auto gen_adj = [&] (ucover *u, int d) {
|
|
||||||
if(u->ptr[d]) return u->ptr[d];
|
|
||||||
cmov(u->where, d);
|
|
||||||
auto x = u->where->move(d);
|
|
||||||
auto d1 = u->where->c.spin(d);
|
|
||||||
auto z = x->zebraval;
|
|
||||||
if(z & 6) {
|
|
||||||
println(hlog, "zebraval failure!");
|
|
||||||
exit(3);
|
|
||||||
x->zebraval = 0;
|
|
||||||
}
|
|
||||||
if(!first && (z & 8))
|
|
||||||
z &=~ 9;
|
|
||||||
u->ptr[d] = new ucover(x, z);
|
|
||||||
u->ptr[d]->ptr[d1] = u;
|
|
||||||
u->ptr[d]->index = isize(all);
|
|
||||||
all.push_back(u->ptr[d]);
|
|
||||||
return u->ptr[d];
|
|
||||||
};
|
|
||||||
|
|
||||||
back:
|
back:
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
@ -296,8 +709,8 @@ struct hrmap_notknot : hrmap {
|
|||||||
|
|
||||||
uf->state |= 2; uf->merged_into = ut;
|
uf->state |= 2; uf->merged_into = ut;
|
||||||
if(uf->where != ut->where)
|
if(uf->where != ut->where)
|
||||||
println(hlog, "where confusion");
|
throw hr_exception_str("where confusion");
|
||||||
for(int d=0; d<6; d++) {
|
for(int d=0; d<uf->where->type; d++) {
|
||||||
cmov(uf->where, d);
|
cmov(uf->where, d);
|
||||||
auto d1 = uf->where->c.spin(d);
|
auto d1 = uf->where->c.spin(d);
|
||||||
if(uf->ptr[d]) {
|
if(uf->ptr[d]) {
|
||||||
@ -309,7 +722,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* in some direction, connections for both uf and ut are already known, so unify them too */
|
/* in some direction, connections for both uf and ut are already known, so unify them too */
|
||||||
unify.emplace_back(uf->ptr[d], ut->ptr[d]);
|
add_to_unify(uf->ptr[d], ut->ptr[d]);
|
||||||
uf->ptr[d]->ptr[d1] = nullptr;
|
uf->ptr[d]->ptr[d1] = nullptr;
|
||||||
uf->ptr[d] = nullptr;
|
uf->ptr[d] = nullptr;
|
||||||
}
|
}
|
||||||
@ -324,59 +737,71 @@ struct hrmap_notknot : hrmap {
|
|||||||
auto u = all[i++];
|
auto u = all[i++];
|
||||||
if(u->state != 0) continue;
|
if(u->state != 0) continue;
|
||||||
if(i > terminate_at) { u->state |= 4; continue; }
|
if(i > terminate_at) { u->state |= 4; continue; }
|
||||||
|
|
||||||
for(int k=0; k<6; k++) gen_adj(u, k);
|
for(int k=0; k<u->where->type; k++) gen_adj(u, k);
|
||||||
|
|
||||||
/* unify homotopies */
|
if(!analyzed.count(u->where)) {
|
||||||
for(int k=0; k<6; k++)
|
analyzed.insert(u->where);
|
||||||
for(int l=0; l<6; l++) {
|
unify_homotopies(u);
|
||||||
auto uk = gen_adj(u, k);
|
unify_loops(u);
|
||||||
if(uk->state != 0) continue;
|
|
||||||
auto ul = gen_adj(u, l);
|
|
||||||
if(ul->state != 0) continue;
|
|
||||||
auto ukl = gen_adj(uk, l);
|
|
||||||
auto ulk = gen_adj(ul, k);
|
|
||||||
if(ukl->state != 0) continue;
|
|
||||||
if(ulk->state != 0) continue;
|
|
||||||
if(ukl == ulk) continue; /* okay */
|
|
||||||
if(!ukl || !ulk) println(hlog, "null returned");
|
|
||||||
unify.emplace_back(ukl, ulk);
|
|
||||||
}
|
}
|
||||||
|
unify_homotopies(u);
|
||||||
/* try to make it finite */
|
unify_loops(u);
|
||||||
auto ux = u;
|
|
||||||
for(int iter=0; iter<loop; iter++)
|
|
||||||
for(int w: {0, 0, 1, 1, 3, 3, 4, 4}) {
|
|
||||||
ux = gen_adj(ux, w);
|
|
||||||
if(ux->state != 0) goto nxt;
|
|
||||||
}
|
|
||||||
unify.emplace_back(u, ux);
|
|
||||||
|
|
||||||
nxt: ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make the walls single-colored */
|
/* make the walls single-colored */
|
||||||
|
|
||||||
|
println(hlog, "single-colored");
|
||||||
|
|
||||||
for(int i=0; i<isize(all); i++) {
|
for(int i=0; i<isize(all); i++) {
|
||||||
auto u = all[i];
|
auto u = all[i];
|
||||||
if(u->state != 0) continue;
|
if(u->state != 0) continue;
|
||||||
|
|
||||||
|
if(u->where->zebraval & 32) {
|
||||||
|
for(int k=0; k<u->where->type; k++) {
|
||||||
|
auto uk = gen_adj(u, k);
|
||||||
|
if(uk->state != 0) continue;
|
||||||
|
if(uk->where->zebraval & 32)
|
||||||
|
funion(u, uk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* convex corners */
|
/* convex corners */
|
||||||
for(int k=0; k<6; k++)
|
for(int k=0; k<u->where->type; k++)
|
||||||
for(int l=0; l<6; l++) {
|
for(int l=0; l<u->where->type; l++) {
|
||||||
auto uk = gen_adj(u, k);
|
auto uk = gen_adj(u, k);
|
||||||
if(uk->state != 0) continue;
|
if(uk->state != 0) continue;
|
||||||
auto ul = gen_adj(u, l);
|
auto ul = gen_adj(u, l);
|
||||||
if(ul->state != 0) continue;
|
if(ul->state != 0) continue;
|
||||||
auto ukl = gen_adj(uk, l);
|
if(geometry == gCubeTiling || geometry == gNil) {
|
||||||
auto ulk = gen_adj(ul, k);
|
auto ukl = gen_adj(uk, l);
|
||||||
if(ukl->state != 0)
|
auto ulk = gen_adj(ul, k);
|
||||||
funion(ukl, ulk);
|
if(ukl->where == ulk->where && ukl->state != 0)
|
||||||
|
funion(ukl, ulk);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(int k1=0; k1<u->where->type; k1++)
|
||||||
|
for(int l1=0; l1<u->where->type; l1++) {
|
||||||
|
auto ukl = gen_adj(uk, l1);
|
||||||
|
auto ulk = gen_adj(ul, k1);
|
||||||
|
if(ukl->where == ulk->where && ukl->state != 0)
|
||||||
|
funion(ukl, ulk);
|
||||||
|
if(base == gCell600 && isNeighbor(ukl->where->c7, ulk->where->c7) && ukl->state != 0 && ulk->state != 0)
|
||||||
|
funion(ukl, ulk);
|
||||||
|
|
||||||
|
if(base == gCell600 && ulk->nowall() && ukl->iswall()) {
|
||||||
|
for(int m1=0; m1<u->where->type; m1++) {
|
||||||
|
auto ulkm = gen_adj(ulk, m1);
|
||||||
|
if(ulkm->where == ukl->where) funion(ulkm, ukl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flat areas */
|
/* flat areas */
|
||||||
for(int k=0; k<6; k++)
|
for(int k=0; k<u->where->type; k++)
|
||||||
for(int l=0; l<6; l++) {
|
for(int l=0; l<u->where->type; l++) {
|
||||||
auto uk = gen_adj(u, k);
|
auto uk = gen_adj(u, k);
|
||||||
if(uk->state != 0) continue;
|
if(uk->state != 0) continue;
|
||||||
auto ul = gen_adj(u, l);
|
auto ul = gen_adj(u, l);
|
||||||
@ -387,15 +812,32 @@ struct hrmap_notknot : hrmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* concave corners */
|
/* concave corners */
|
||||||
for(int k=0; k<6; k++)
|
for(int k=0; k<u->where->type; k++)
|
||||||
for(int l=0; l<6; l++) {
|
for(int l=0; l<u->where->type; l++)
|
||||||
|
if(adjacent_face(u, k, l)) {
|
||||||
auto uk = gen_adj(u, k);
|
auto uk = gen_adj(u, k);
|
||||||
if(!(uk->state & 1)) continue;
|
if(!(uk->state & 1)) continue;
|
||||||
auto ul = gen_adj(u, l);
|
auto ul = gen_adj(u, l);
|
||||||
if(!(ul->state & 1)) continue;
|
if(!(ul->state & 1)) continue;
|
||||||
if(abs(k-l) != 3)
|
funion(ul, uk);
|
||||||
funion(ul, uk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(base == gCell600)
|
||||||
|
for(int k=0; k<u->where->type; k++)
|
||||||
|
for(int l=0; l<u->where->type; l++)
|
||||||
|
if(adjacent_face(u, k, l)) {
|
||||||
|
auto uk = gen_adj(u, k);
|
||||||
|
if(uk->nowall()) continue;
|
||||||
|
auto ul = gen_adj(u, l);
|
||||||
|
if(ul->iswall()) continue;
|
||||||
|
|
||||||
|
for(int m=0; m<u->where->type; m++)
|
||||||
|
if(adjacent_matrix(adj(u, k), adj(u, l) * adj(ul, m))) {
|
||||||
|
auto um = gen_adj(ul, m);
|
||||||
|
if(um->nowall()) continue;
|
||||||
|
funion(um, uk);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* statistics */
|
/* statistics */
|
||||||
@ -423,6 +865,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
if(u->state == 0) wheres.insert(all[i]->where);
|
if(u->state == 0) wheres.insert(all[i]->where);
|
||||||
u->result = tailored_alloc<heptagon> (S7);
|
u->result = tailored_alloc<heptagon> (S7);
|
||||||
u->result->c7 = newCell(S7, u->result);
|
u->result->c7 = newCell(S7, u->result);
|
||||||
|
indices[u->result] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
println(hlog, "wheres = ", isize(wheres), " : ", lives * 1. / isize(wheres));
|
println(hlog, "wheres = ", isize(wheres), " : ", lives * 1. / isize(wheres));
|
||||||
@ -434,7 +877,6 @@ struct hrmap_notknot : hrmap {
|
|||||||
for(int d=0; d<S7; d++) {
|
for(int d=0; d<S7; d++) {
|
||||||
cmov(u->where, d);
|
cmov(u->where, d);
|
||||||
auto d1 = u->where->c.spin(d);
|
auto d1 = u->where->c.spin(d);
|
||||||
if(abs(d-d1) != 3) println(hlog, "incorrect d1");
|
|
||||||
if(u->ptr[d] && u->ptr[d]->result == nullptr) {
|
if(u->ptr[d] && u->ptr[d]->result == nullptr) {
|
||||||
println(hlog, "connection to null in state ", u->ptr[d]->state, " from state ", u->state, " i=", i, " .. ", u->ptr[d]->index);
|
println(hlog, "connection to null in state ", u->ptr[d]->state, " from state ", u->state, " i=", i, " .. ", u->ptr[d]->index);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -444,7 +886,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
if(u->ptr[d])
|
if(u->ptr[d])
|
||||||
u->result->c.connect(d, u->ptr[d]->result, d1, false);
|
u->result->c.connect(d, u->ptr[d]->result, d1, false);
|
||||||
else
|
else
|
||||||
u->result->c.connect(d, u->result, d, false);
|
u->result->c.connect(d, u->result, gmod(d + u->result->type/2, u->result->type), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,7 +926,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
|
|
||||||
println(hlog, "removed one knot!");
|
println(hlog, "removed one knot!");
|
||||||
|
|
||||||
first = false; i = 0;
|
first = false; i = 0; remove_marked_walls = true;
|
||||||
goto back;
|
goto back;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,7 +935,21 @@ struct hrmap_notknot : hrmap {
|
|||||||
all[i]->wallcolor = hrand(0x1000000) | 0x404040,
|
all[i]->wallcolor = hrand(0x1000000) | 0x404040,
|
||||||
all[i]->wallcolor2 = hrand(0x1000000) | 0x404040;
|
all[i]->wallcolor2 = hrand(0x1000000) | 0x404040;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<isize(all); i++)
|
||||||
|
if((all[i]->where->zebraval & 32) && ufind(all[i]) == all[i]) {
|
||||||
|
auto& w = all[i]->wallcolor;
|
||||||
|
all[i]->wallcolor = (hrand(0x1000000) << 8) | 0x01;
|
||||||
|
switch(hrand(6)) {
|
||||||
|
case 0: w |= 0xFF000000; break;
|
||||||
|
case 1: w |= 0x00FF0000; break;
|
||||||
|
case 2: w |= 0x0000FF00; break;
|
||||||
|
case 3: w |= 0xC0C00000; break;
|
||||||
|
case 4: w |= 0x00C0C000; break;
|
||||||
|
case 5: w |= 0xC000C000; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(int i=0; i<isize(all); i++) {
|
for(int i=0; i<isize(all); i++) {
|
||||||
auto u = all[i];
|
auto u = all[i];
|
||||||
if(!u->result) continue;
|
if(!u->result) continue;
|
||||||
@ -502,7 +958,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
c->land = laCanvas;
|
c->land = laCanvas;
|
||||||
if(u->state & 1) {
|
if(u->state & 1) {
|
||||||
c->wall = waWaxWall;
|
c->wall = waWaxWall;
|
||||||
c->landparam = hrand(100) < 10 ? ufind(u)->wallcolor2 : ufind(u)->wallcolor;
|
c->landparam = hrand(100) < secondary_percentage ? ufind(u)->wallcolor2 : ufind(u)->wallcolor;
|
||||||
if(!(ufind(u)->state & 1)) println(hlog, "connected to state ", ufind(u)->state);
|
if(!(ufind(u)->state & 1)) println(hlog, "connected to state ", ufind(u)->state);
|
||||||
// if(!(c->landparam & 0x404040)) println(hlog, "color found ", c->landparam);
|
// if(!(c->landparam & 0x404040)) println(hlog, "color found ", c->landparam);
|
||||||
}
|
}
|
||||||
@ -510,7 +966,57 @@ struct hrmap_notknot : hrmap {
|
|||||||
c->wall = waBigTree;
|
c->wall = waBigTree;
|
||||||
else
|
else
|
||||||
c->wall = waNone;
|
c->wall = waNone;
|
||||||
|
|
||||||
|
if(all[i]->where->zebraval & 32)
|
||||||
|
ray::volumetric::vmap[c] = ufind(u)->wallcolor ^ ((hrand(0x1000000) & 0x3F3F3F) << 8);
|
||||||
|
else
|
||||||
|
ray::volumetric::vmap[c] = 0x00000001;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch(hr_exception_str& s) {
|
||||||
|
println(hlog, "exception: ", s.s);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_fog() {
|
||||||
|
vector<color_t> cols = {0xFF000001, 0xC0C00001, 0x00FF0001, 0x00C0C001, 0x0000FF01, 0xC000C001};
|
||||||
|
int id = 0;
|
||||||
|
map<cell*, pair<int, int> > dist;
|
||||||
|
vector<cell*> lst;
|
||||||
|
|
||||||
|
auto color = [&] (cell *c, color_t col, int d) {
|
||||||
|
if(!dist.count(c)) dist[c] = {d, 0};
|
||||||
|
auto& p = dist[c];
|
||||||
|
if(p.first == d) {
|
||||||
|
if(!p.second) lst.push_back(c);
|
||||||
|
p.second++;
|
||||||
|
auto& vm = ray::volumetric::vmap[c];
|
||||||
|
if(p.second == 1) vm = col;
|
||||||
|
else vm = gradient(vm, col, 0, 1, p.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for(int i=0; i<isize(all); i++)
|
||||||
|
if(all[i]->result)
|
||||||
|
if(all[i]->where->c7->wall == waFloorA)
|
||||||
|
color(all[i]->result->c7, cols[(id++) % isize(cols)], 0);
|
||||||
|
|
||||||
|
for(int i=0; i<isize(lst); i++) {
|
||||||
|
auto c = lst[i];
|
||||||
|
auto col = ray::volumetric::vmap[c];
|
||||||
|
int d = dist[c].first;
|
||||||
|
forCellCM(c1, c)
|
||||||
|
if(c1->wall == waNone)
|
||||||
|
color(c1, col, d+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<isize(lst); i++) {
|
||||||
|
auto c = lst[i];
|
||||||
|
ray::volumetric::vmap[c] ^= ((hrand(0x1000000) & 0x3F3F3F) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
ray::volumetric::enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override {
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1, const hyperpoint& hint) override {
|
||||||
@ -518,7 +1024,11 @@ struct hrmap_notknot : hrmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transmatrix adj(heptagon *h, int i) override {
|
transmatrix adj(heptagon *h, int i) override {
|
||||||
return euc->adj(h, i);
|
return adj(all[indices[h]], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix adj(cell *c, int i) override {
|
||||||
|
return adj(c->master, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
~hrmap_notknot() {
|
~hrmap_notknot() {
|
||||||
@ -543,12 +1053,14 @@ auto h = addHook(hooks_newmap, 0, [] {
|
|||||||
});
|
});
|
||||||
|
|
||||||
void create_notknot() {
|
void create_notknot() {
|
||||||
if(gNotKnot != eGeometry(-1)) return;
|
if(gNotKnot == eGeometry(-1)) {
|
||||||
ginf.push_back(ginf[gCubeTiling]);
|
ginf.push_back(ginf[base]);
|
||||||
gNotKnot = eGeometry(isize(ginf) - 1);
|
gNotKnot = eGeometry(isize(ginf) - 1);
|
||||||
|
}
|
||||||
|
else ginf[gNotKnot] = ginf[base];
|
||||||
// variation = eVariation::pure;
|
// variation = eVariation::pure;
|
||||||
auto& gi = ginf.back();
|
auto& gi = ginf.back();
|
||||||
gi.flags = qANYQ | qBOUNDED | qEXPERIMENTAL | qPORTALSPACE;
|
gi.flags |= qANYQ | qBOUNDED | qEXPERIMENTAL | qPORTALSPACE;
|
||||||
gi.quotient_name = "notknot";
|
gi.quotient_name = "notknot";
|
||||||
gi.shortname = "notknot";
|
gi.shortname = "notknot";
|
||||||
gi.menu_displayed_name = "notknot";
|
gi.menu_displayed_name = "notknot";
|
||||||
@ -588,7 +1100,48 @@ void show() {
|
|||||||
void o_key(o_funcs& v) {
|
void o_key(o_funcs& v) {
|
||||||
if(geometry == gNotKnot) v.push_back(named_dialog("notknot", show));
|
if(geometry == gNotKnot) v.push_back(named_dialog("notknot", show));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell *startcell, *current;
|
||||||
|
vector<int> dirs;
|
||||||
|
|
||||||
|
void check_cycle() {
|
||||||
|
if(!current) {
|
||||||
|
auto s = currentmap->allcells()[0];
|
||||||
|
println(hlog, "starting the cycle, ", cwt.at == s);
|
||||||
|
startcell = current = cwt.at = s;
|
||||||
|
}
|
||||||
|
if(cwt.at != current) {
|
||||||
|
forCellIdEx(c1, i, current)
|
||||||
|
if(c1 == cwt.at) {
|
||||||
|
dirs.push_back(i);
|
||||||
|
current = cwt.at;
|
||||||
|
startcell->item = itGold;
|
||||||
|
println(hlog, "dirs = ", dirs, " finished = ", startcell == current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_knot() {
|
||||||
|
for(cell *c: currentmap->allcells())
|
||||||
|
c->wall = waNone;
|
||||||
|
|
||||||
|
cell *last = nullptr;
|
||||||
|
|
||||||
|
for(int i=0; i<3600; i++) {
|
||||||
|
ld alpha = i * degree / 10;
|
||||||
|
ld q = sqrt(2)/2;
|
||||||
|
hyperpoint h = hyperpoint(q*cos(alpha*2), q*sin(alpha*2), q*cos(alpha*3), q*sin(alpha*3));
|
||||||
|
cell *b = currentmap->gamestart();
|
||||||
|
virtualRebase(b, h);
|
||||||
|
b->wall = waPlatform;
|
||||||
|
if(b != last) {
|
||||||
|
if(!last) println(hlog, "start at ", b);
|
||||||
|
if(last) println(hlog, "i=", i, ": to ", b, " isN = ", isNeighbor(last, b));
|
||||||
|
last = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto shot_hooks = addHook(hooks_initialize, 100, create_notknot)
|
auto shot_hooks = addHook(hooks_initialize, 100, create_notknot)
|
||||||
+ addHook(hooks_welcome_message, 100, [] {
|
+ addHook(hooks_welcome_message, 100, [] {
|
||||||
if(geometry == gNotKnot) {
|
if(geometry == gNotKnot) {
|
||||||
@ -597,7 +1150,44 @@ auto shot_hooks = addHook(hooks_initialize, 100, create_notknot)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
|
+ addHook(hooks_args, 100, [] {
|
||||||
|
using namespace arg;
|
||||||
|
|
||||||
|
if(0) ;
|
||||||
|
else if(argis("-nkbase")) {
|
||||||
|
base = geometry;
|
||||||
|
create_notknot();
|
||||||
|
}
|
||||||
|
else if(argis("-nkbasemap")) {
|
||||||
|
shift(); base_map = args();
|
||||||
|
set_geometry(gNotKnot);
|
||||||
|
}
|
||||||
|
else if(argis("-nk-volumetric")) {
|
||||||
|
start_game();
|
||||||
|
((hrmap_notknot*)currentmap)->add_fog();
|
||||||
|
}
|
||||||
|
else if(argis("-nk-genknot")) {
|
||||||
|
start_game();
|
||||||
|
gen_knot();
|
||||||
|
}
|
||||||
|
else if(argis("-nk-unloop")) {
|
||||||
|
shift();
|
||||||
|
int copies = argi();
|
||||||
|
shift();
|
||||||
|
vector<int> v;
|
||||||
|
for(int i=0; i<copies; i++)
|
||||||
|
for(char c: args())
|
||||||
|
if(c >= '0' && c <= '9') v.push_back(c - '0');
|
||||||
|
else v.push_back(c - 'a' + 10);
|
||||||
|
to_unloop.push_back(v);
|
||||||
|
println(hlog, "pushed to to_unloop: ", v);
|
||||||
|
}
|
||||||
|
else return 1;
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
|
||||||
+ addHook(hooks_o_key, 80, o_key)
|
+ addHook(hooks_o_key, 80, o_key)
|
||||||
|
+ addHook(hooks_frame, 100, check_cycle)
|
||||||
+ addHook(hooks_configfile, 100, [] {
|
+ addHook(hooks_configfile, 100, [] {
|
||||||
param_i(loop, "nk_loop")
|
param_i(loop, "nk_loop")
|
||||||
->editable(1, 5, 1, "notknot order", "How many times do we need to go around the knot to get back.", 'o')
|
->editable(1, 5, 1, "notknot order", "How many times do we need to go around the knot to get back.", 'o')
|
||||||
@ -612,9 +1202,11 @@ auto shot_hooks = addHook(hooks_initialize, 100, create_notknot)
|
|||||||
->set_sets([] { dialog::bound_low(2); dialog::bound_up(5); })
|
->set_sets([] { dialog::bound_low(2); dialog::bound_up(5); })
|
||||||
->set_reaction(regenerate);
|
->set_reaction(regenerate);
|
||||||
param_i(terminate_at, "nk_terminate")->set_reaction(regenerate);
|
param_i(terminate_at, "nk_terminate")->set_reaction(regenerate);
|
||||||
|
param_i(secondary_percentage, "nk_secondary");
|
||||||
param_b(self_hiding, "selfhide")
|
param_b(self_hiding, "selfhide")
|
||||||
->editable("self-hiding knot", 'h')
|
->editable("self-hiding knot", 'h')
|
||||||
->set_reaction(regenerate);
|
->set_reaction(regenerate);
|
||||||
|
param_i(loop_any, "nk_loopany");
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef NOTKNOT
|
#ifdef NOTKNOT
|
||||||
@ -636,7 +1228,7 @@ auto hook1=
|
|||||||
// fov = 150;
|
// fov = 150;
|
||||||
ray::exp_decay_poly = 30;
|
ray::exp_decay_poly = 30;
|
||||||
ray::fixed_map = true;
|
ray::fixed_map = true;
|
||||||
ray::max_iter_iso = 60;
|
ray::max_iter_iso = 80;
|
||||||
showstartmenu = false;
|
showstartmenu = false;
|
||||||
#if CAP_VR
|
#if CAP_VR
|
||||||
vrhr::hsm = vrhr::eHeadset::holonomy;
|
vrhr::hsm = vrhr::eHeadset::holonomy;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user