reg3:: ultra-mirrors

This commit is contained in:
Zeno Rogue 2020-05-28 01:50:00 +02:00
parent 89bba619f0
commit 4217c7ccc7
7 changed files with 126 additions and 40 deletions

View File

@ -253,6 +253,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];

View File

@ -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

View File

@ -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];

View File

@ -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>

View File

@ -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() {
@ -2013,6 +2013,14 @@ EX namespace dq {
visited_by_matrix.insert(b);
drawqueue_c.emplace(c, T, band_shift);
}
EX void clear_all() {
visited.clear();
visited_by_matrix.clear();
visited_c.clear();
drawqueue_c = {};
drawqueue = {};
}
EX }

View File

@ -462,6 +462,19 @@ void enable_raycaster() {
fmain +=
" 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
View File

@ -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])
@ -302,6 +318,10 @@ EX namespace reg3 {
if(!do_draw(c, V)) continue;
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();
@ -887,9 +906,15 @@ EX namespace reg3 {
if(!do_draw(c, V)) continue;
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));
}
}
}