mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-02 12:19:18 +00:00
reg3:: ultra-mirrors
This commit is contained in:
parent
89bba619f0
commit
4217c7ccc7
2
fake.cpp
2
fake.cpp
@ -254,6 +254,8 @@ EX ld compute_around(bool setup) {
|
||||
h2 = gpushxto0(u) * h2;
|
||||
u = gpushxto0(u) * u;
|
||||
|
||||
reg3::compute_ultra();
|
||||
|
||||
ld x = hypot(h2[1], h2[2]);
|
||||
ld y = h2[0];
|
||||
return 360 / (90 + atan(y/x) / degree);
|
||||
|
11
geom-exp.cpp
11
geom-exp.cpp
@ -770,6 +770,14 @@ EX void showEuclideanMenu() {
|
||||
}
|
||||
#endif
|
||||
|
||||
if(cgflags & qULTRA) {
|
||||
dialog::addBoolItem(XLAT("truncate ultra-vertices with mirrors"), reg3::ultra_mirror_on, 'Z');
|
||||
dialog::add_action([] {
|
||||
reg3::ultra_mirror_on = !reg3::ultra_mirror_on;
|
||||
ray::reset_raycaster();
|
||||
});
|
||||
}
|
||||
|
||||
if(prod) {
|
||||
dialog::addSelItem(XLAT("Z-level height factor"), fts(vid.plevel_factor), 'Z');
|
||||
dialog::add_action([] {
|
||||
@ -1072,6 +1080,9 @@ int read_geom_args() {
|
||||
cheat();
|
||||
shift(); currfp.qpaths.push_back(args());
|
||||
}
|
||||
else if(argis("-truncate-ultra")) {
|
||||
shift(); reg3::ultra_mirror_on = argi();
|
||||
}
|
||||
else if(argis("-d:quotient"))
|
||||
launch_dialog(showQuotientConfig);
|
||||
#endif
|
||||
|
@ -133,6 +133,10 @@ struct geometry_information {
|
||||
ld strafedist;
|
||||
bool dirs_adjacent[32][32];
|
||||
|
||||
ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part;
|
||||
|
||||
vector<transmatrix> ultra_mirrors;
|
||||
|
||||
/** \brief for adjacent directions a,b, next_dir[a][b] is the next direction adjacent to a, in (counter?)clockwise order from b */
|
||||
int next_dir[32][32];
|
||||
|
||||
|
@ -282,6 +282,18 @@ void virtualRebase_cell(cell*& base, T& at, const U& check) {
|
||||
base = newbase;
|
||||
at = best_at;
|
||||
}
|
||||
if(reg3::ultra_mirror_in()) {
|
||||
again:
|
||||
for(auto& v: cgi.mirror_matrices) {
|
||||
T cand_at = v * at;
|
||||
horo_distance newz(check(cand_at));
|
||||
if(newz < currz) {
|
||||
currz = newz;
|
||||
at = cand_at;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
|
10
hypgraph.cpp
10
hypgraph.cpp
@ -997,7 +997,7 @@ EX ld spherity(const transmatrix& V) {
|
||||
}
|
||||
|
||||
EX bool confusingGeometry() {
|
||||
return quotient || elliptic;
|
||||
return quotient || elliptic || reg3::ultra_mirror_in();
|
||||
}
|
||||
|
||||
EX ld master_to_c7_angle() {
|
||||
@ -2014,6 +2014,14 @@ EX namespace dq {
|
||||
drawqueue_c.emplace(c, T, band_shift);
|
||||
}
|
||||
|
||||
EX void clear_all() {
|
||||
visited.clear();
|
||||
visited_by_matrix.clear();
|
||||
visited_c.clear();
|
||||
drawqueue_c = {};
|
||||
drawqueue = {};
|
||||
}
|
||||
|
||||
|
||||
EX }
|
||||
|
||||
|
@ -463,6 +463,19 @@ void enable_raycaster() {
|
||||
" if(d < dist) { dist = d; which = i; }\n"
|
||||
"}\n";
|
||||
|
||||
if(hyperbolic && reg3::ultra_mirror_in()) {
|
||||
fmain += "for(int i="+its(S7*2)+"; i<"+its(S7*2+isize(cgi.vertices_only))+"; i++) {\n";
|
||||
fmain +=
|
||||
" mediump float v = ((position - uM[i] * position)[3] / (uM[i] * tangent - tangent)[3]);\n"
|
||||
" if(v > 1. || v < -1.) continue;\n"
|
||||
" mediump float d = atanh(v);\n"
|
||||
" mediump vec4 next_tangent = position * sinh(d) + tangent * cosh(d);\n"
|
||||
" if(next_tangent[3] < (uM[i] * next_tangent)[3]) continue;\n"
|
||||
" if(d < dist) { dist = d; which = i; }\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
|
||||
// 20: get to horosphere +uBLevel (take smaller root)
|
||||
// 21: get to horosphere -uBLevel (take larger root)
|
||||
|
||||
@ -831,6 +844,12 @@ void enable_raycaster() {
|
||||
|
||||
if(prod) fmain += "position.w = -zpos;\n";
|
||||
|
||||
if(reg3::ultra_mirror_in()) fmain +=
|
||||
"if(which >= " + its(S7) + ") {"
|
||||
" tangent = uM[which] * tangent;\n"
|
||||
" continue;\n"
|
||||
" }\n";
|
||||
|
||||
// apply wall color
|
||||
fmain +=
|
||||
" mediump vec2 u = cid + vec2(float(which) / float(uLength), 0);\n"
|
||||
@ -1137,7 +1156,7 @@ EX void cast() {
|
||||
|
||||
// println(hlog, ms);
|
||||
|
||||
if(!sol && !nil && reflect_val) {
|
||||
if(!sol && !nil && (reflect_val || reg3::ultra_mirror_in())) {
|
||||
if(BITRUNCATED) exit(1);
|
||||
for(int j=0; j<centerover->type; j++) {
|
||||
transmatrix T = inverse(ms[j]);
|
||||
@ -1146,6 +1165,11 @@ EX void cast() {
|
||||
transmatrix U = rspintox(h) * xpush(d/2) * MirrorX * xpush(-d/2) * spintox(h);
|
||||
ms.push_back(U);
|
||||
}
|
||||
|
||||
if(reg3::ultra_mirror_in()) {
|
||||
for(auto v: cgi.ultra_mirrors)
|
||||
ms.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
vector<array<float, 4>> connections(length * rows);
|
||||
|
101
reg3.cpp
101
reg3.cpp
@ -27,11 +27,58 @@ EX namespace reg3 {
|
||||
inline short& altdist(heptagon *h) { return h->emeraldval; }
|
||||
#endif
|
||||
|
||||
EX bool ultra_mirror_on;
|
||||
|
||||
EX bool ultra_mirror_in() { return (cgflags & qULTRA) && ultra_mirror_on; }
|
||||
|
||||
EX bool in() {
|
||||
if(fake::in()) return FPIU(in());
|
||||
return GDIM == 3 && !euclid && !bt::in() && !nonisotropic && !hybri && !kite::in();
|
||||
}
|
||||
|
||||
EX void compute_ultra() {
|
||||
cgi.ultra_mirror_part = .99;
|
||||
cgi.ultra_material_part = .99;
|
||||
|
||||
if(cgflags & qULTRA) {
|
||||
transmatrix T = spintox(cgi.cellshape[0]);
|
||||
hyperpoint a = T * cgi.cellshape[0];
|
||||
hyperpoint b = T * cgi.cellshape[1];
|
||||
ld f0 = 0.5;
|
||||
ld f1 = binsearch(0.5, 1, [&] (ld d) {
|
||||
hyperpoint c = lerp(b, a, d);
|
||||
if(debugflags & DF_GEOM)
|
||||
println(hlog, "d=", d, " c= ", c, " material = ", material(c));
|
||||
return material(c) <= 0;
|
||||
});
|
||||
cgi.ultra_material_part = f1;
|
||||
auto f = [&] (ld d) {
|
||||
hyperpoint c = lerp(b, a, d);
|
||||
c = normalize(c);
|
||||
return c[1] * c[1] + c[2] * c[2];
|
||||
};
|
||||
for(int it=0; it<100; it++) {
|
||||
ld fa = (f0*2+f1) / 3;
|
||||
ld fb = (f0*1+f1*2) / 3;
|
||||
if(debugflags & DF_GEOM)
|
||||
println(hlog, "f(", fa, ") = ", f(fa), " f(", fb, ") = ", f(fb));
|
||||
if(f(fa) > f(fb)) f0 = fa;
|
||||
else f1 = fb;
|
||||
}
|
||||
|
||||
cgi.ultra_mirror_part = f0;
|
||||
|
||||
hyperpoint c = lerp(b, a, f0);
|
||||
c = normalize(c);
|
||||
c[1] = c[2] = 0;
|
||||
c = normalize(c);
|
||||
cgi.ultra_mirror_dist = hdist0(c);
|
||||
}
|
||||
|
||||
if(cgflags & qULTRA) for(auto v: cgi.vertices_only)
|
||||
cgi.ultra_mirrors.push_back(rspintox(v) * xpush(cgi.ultra_mirror_dist*2) * MirrorX * spintox(v));
|
||||
}
|
||||
|
||||
EX void generate() {
|
||||
|
||||
if(fake::in()) {
|
||||
@ -129,39 +176,6 @@ EX namespace reg3 {
|
||||
ld between_centers = 2 * hdist0(midface);
|
||||
DEBB(DF_GEOM, ("between_centers = ", between_centers));
|
||||
|
||||
if(hyperbolic && klein_scale > 1) {
|
||||
transmatrix T = spintox(h012);
|
||||
hyperpoint a = T * (C0 + klein_scale * h012);
|
||||
hyperpoint b = T * (C0 + klein_scale * h013);
|
||||
ld f0 = 0.5;
|
||||
println(hlog, "a=", a, " b=", b);
|
||||
ld f1 = binsearch(0.5, 1, [&] (ld d) {
|
||||
hyperpoint c = lerp(b, a, d);
|
||||
println(hlog, "d=", d, " c= ", c, " material = ", material(c));
|
||||
return material(c) <= 0;
|
||||
});
|
||||
println(hlog, "f1 = ", f1);
|
||||
auto f = [&] (ld d) {
|
||||
hyperpoint c = lerp(b, a, d);
|
||||
c = normalize(c);
|
||||
return c[1] * c[1] + c[2] * c[2];
|
||||
};
|
||||
for(int it=0; it<100; it++) {
|
||||
ld fa = (f0*2+f1) / 3;
|
||||
ld fb = (f0*1+f1*2) / 3;
|
||||
println(hlog, "f(", fa, ") = ", f(fa), " f(", fb, ") = ", f(fb));
|
||||
if(f(fa) > f(fb)) f0 = fa;
|
||||
else f1 = fb;
|
||||
}
|
||||
|
||||
hyperpoint c = lerp(b, a, f0);
|
||||
c = normalize(c);
|
||||
c[1] = c[2] = 0;
|
||||
c = normalize(c);
|
||||
mirrordist = hdist0(c);
|
||||
println(hlog, "mirrordist = ", mirrordist);
|
||||
}
|
||||
|
||||
if(S7 == 20) {
|
||||
spins[0] = Id;
|
||||
spins[1] = cspin(0, 1, angle_between_faces) * cspin(1, 2, M_PI);
|
||||
@ -233,6 +247,8 @@ EX namespace reg3 {
|
||||
if(!found) vertices_only.push_back(h);
|
||||
}
|
||||
|
||||
compute_ultra();
|
||||
|
||||
for(int a=0; a<12; a++)
|
||||
for(int b=0; b<12; b++)
|
||||
if(cgi.dirs_adjacent[a][b])
|
||||
@ -303,6 +319,10 @@ EX namespace reg3 {
|
||||
drawcell(c, V);
|
||||
if(in_wallopt() && isWall3(c) && isize(dq::drawqueue) > 1000) continue;
|
||||
|
||||
if(ultra_mirror_in())
|
||||
for(auto& T: cgi.ultra_mirrors)
|
||||
dq::enqueue_by_matrix(h, V * T);
|
||||
|
||||
for(int d=0; d<S7; d++)
|
||||
dq::enqueue_by_matrix(h->move(d), V * tmatrices[h->fieldval][d]);
|
||||
}
|
||||
@ -869,10 +889,9 @@ EX namespace reg3 {
|
||||
void draw() override {
|
||||
sphereflip = Id;
|
||||
|
||||
// for(int i=0; i<S6; i++) queuepoly(ggmatrix(cwt.at), shWall3D[i], 0xFF0000FF);
|
||||
|
||||
dq::visited.clear();
|
||||
dq::enqueue(centerover->master, cview());
|
||||
dq::clear_all();
|
||||
auto& enq = (ultra_mirror_in() ? dq::enqueue_by_matrix : dq::enqueue);
|
||||
enq(centerover->master, cview());
|
||||
|
||||
while(!dq::drawqueue.empty()) {
|
||||
auto& p = dq::drawqueue.front();
|
||||
@ -888,8 +907,14 @@ EX namespace reg3 {
|
||||
drawcell(c, V);
|
||||
if(in_wallopt() && isWall3(c) && isize(dq::drawqueue) > 1000) continue;
|
||||
|
||||
if(sightranges[geometry] == 0) return;
|
||||
|
||||
if(ultra_mirror_in())
|
||||
for(auto& T: cgi.ultra_mirrors)
|
||||
dq::enqueue_by_matrix(h, V * T);
|
||||
|
||||
for(int i=0; i<S7; i++) if(h->move(i)) {
|
||||
dq::enqueue(h->move(i), V * adj(h, i));
|
||||
enq(h->move(i), V * adj(h, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user