ray:: horospherical hyperbolic honeycombs

This commit is contained in:
Zeno Rogue 2019-11-02 10:40:22 +01:00
parent bde53b5c78
commit 272c628229
4 changed files with 117 additions and 11 deletions

View File

@ -558,6 +558,21 @@ EX namespace binary {
return S7-1; return S7-1;
} }
EX int dirs_outer() {
switch(geometry) {
case gBinary3: return 4;
case gHoroTris: return 4;
case gHoroRec: return 2;
case gHoroHex: return 6;
default: return -1;
}
}
EX int dirs_inner() {
if(among(geometry, gBinaryTiling, gHoroHex)) return 2;
return 1;
}
EX void build_tmatrix() { EX void build_tmatrix() {
if(among(geometry, gBinaryTiling, gSol)) return; // unused if(among(geometry, gBinaryTiling, gSol)) return; // unused
use_direct = (1 << (S7-1)) - 1; use_direct = (1 << (S7-1)) - 1;

View File

@ -586,6 +586,19 @@ EX transmatrix parabolic13(ld u, ld v) {
} }
} }
EX hyperpoint parabolic10(hyperpoint h) {
if(euclid) { h[MDIM] = 1; return h; }
else if(MDIM == 4) return hyperpoint(sinh(h[0]), h[1]/exp(h[0]), h[2]/exp(h[0]), cosh(h[0]));
else return hyperpoint(sinh(h[0]), h[1]/exp(h[0]), cosh(h[0]), 0);
}
EX hyperpoint deparabolic10(const hyperpoint h) {
if(euclid) return h;
ld x = -log(h[LDIM] - h[0]);
if(MDIM == 3) return hyperpoint(x, h[1] * exp(x), 1, 0);
return point31(x, h[1] * exp(x), h[2] * exp(x));
}
EX transmatrix spintoc(const hyperpoint& H, int t, int f) { EX transmatrix spintoc(const hyperpoint& H, int t, int f) {
transmatrix T = Id; transmatrix T = Id;
ld R = hypot(H[f], H[t]); ld R = hypot(H[f], H[t]);

View File

@ -709,6 +709,11 @@ void geometry_information::compute_cornerbonus() { }
hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) { hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) {
if(geometry == gNil && among(id, 2, 5)) h[2] = 0; if(geometry == gNil && among(id, 2, 5)) h[2] = 0;
if(hyperbolic && binarytiling) {
// ld co = vid.binary_width / log(2) / 4;
// hyperpoint res = point31(h[2]*log(2)/2, h[0]*co, h[1]*co);
return deparabolic10(binary::parabolic3(h[0], h[1]) * xpush0(log(2)/2*h[2]));
}
if(prod) { if(prod) {
return point3(h[0]/h[2], h[1]/h[2], pz); return point3(h[0]/h[2], h[1]/h[2], pz);
} }
@ -918,7 +923,7 @@ void geometry_information::create_wall3d() {
ld h = binary::horohex_scale / 2; ld h = binary::horohex_scale / 2;
hyperpoint down = point3(0,0,2*z); hyperpoint down = point3(0,0,2*z);
for(int i=0; i<3; i++) { for(int j=0; j<4; j++) for(int i=0; i<3; i++) {
transmatrix T = cspin(0, 1, 2*M_PI*i/3); transmatrix T = cspin(0, 1, 2*M_PI*i/3);
hyperpoint hcenter = point3(0,0,-z); hyperpoint hcenter = point3(0,0,-z);
@ -929,10 +934,10 @@ void geometry_information::create_wall3d() {
hyperpoint hcn = T*point3(-h*2,0, -z); hyperpoint hcn = T*point3(-h*2,0, -z);
hyperpoint hun = T*point3(-h*3,+r3,-z); hyperpoint hun = T*point3(-h*3,+r3,-z);
hyperpoint hdn = T*point3(-h*3,-r3,-z); hyperpoint hdn = T*point3(-h*3,-r3,-z);
make_wall(i, {hcenter, hu0, hu1, hd1, hd0}); if(j == 0) make_wall(i, {hcenter, hu0, hu1, hd1, hd0});
make_wall(i+3, {hcn, hun, hdn}); if(j == 1) make_wall(i+3, {hcn, hun, hdn});
make_wall(i+6, make4(hd1, hu1, hd1+down)); if(j == 2) make_wall(i+6, make4(hd1, hu1, hd1+down));
make_wall(i+9, make4(hun, hdn, hun+down)); if(j == 3) make_wall(i+9, make4(hun, hdn, hun+down));
} }
make_wall(12, {point3(3*h,r3,z), point3(0,2*r3,z), point3(-3*h,r3,z)}); make_wall(12, {point3(3*h,r3,z), point3(0,2*r3,z), point3(-3*h,r3,z)});

View File

@ -54,7 +54,7 @@ eGeometry last_geometry;
/** is the raycaster available? */ /** is the raycaster available? */
EX bool available() { EX bool available() {
if(WDIM == 2) return false; if(WDIM == 2) return false;
if(hyperbolic && pmodel == mdPerspective && !binarytiling) if(hyperbolic && pmodel == mdPerspective && !penrose)
return true; return true;
if((sol || nil) && pmodel == mdGeodesic) if((sol || nil) && pmodel == mdGeodesic)
return true; return true;
@ -79,6 +79,7 @@ struct raycaster : glhr::GLprogram {
GLint tConnections, tWallcolor, tTextureMap; GLint tConnections, tWallcolor, tTextureMap;
GLint uBinaryWidth, uPLevel, uLP; GLint uBinaryWidth, uPLevel, uLP;
GLint uLinearSightRange, uExpStart, uExpDecay; GLint uLinearSightRange, uExpStart, uExpDecay;
GLint uBLevel;
raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) { raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) {
println(hlog, "assigning"); println(hlog, "assigning");
@ -101,6 +102,8 @@ struct raycaster : glhr::GLprogram {
uLinearSightRange = glGetUniformLocation(_program, "uLinearSightRange"); uLinearSightRange = glGetUniformLocation(_program, "uLinearSightRange");
uExpDecay = glGetUniformLocation(_program, "uExpDecay"); uExpDecay = glGetUniformLocation(_program, "uExpDecay");
uExpStart = glGetUniformLocation(_program, "uExpStart"); uExpStart = glGetUniformLocation(_program, "uExpStart");
uBLevel = glGetUniformLocation(_program, "uBLevel");
tConnections = glGetUniformLocation(_program, "tConnections"); tConnections = glGetUniformLocation(_program, "tConnections");
tWallcolor = glGetUniformLocation(_program, "tWallcolor"); tWallcolor = glGetUniformLocation(_program, "tWallcolor");
@ -158,14 +161,24 @@ void enable_raycaster() {
"uniform float uPLevel;\n" "uniform float uPLevel;\n"
"uniform mat4 uLP;\n"; "uniform mat4 uLP;\n";
if(IN_ODS) fsh += int flat1 = 0, flat2 = S7;
if(hyperbolic && binarytiling) {
fsh += "uniform float uBLevel;\n";
flat1 = binary::dirs_outer();
flat2 -= binary::dirs_inner();
}
if(IN_ODS || hyperbolic) fsh +=
"mat4 xpush(float x) { return mat4(" "mat4 xpush(float x) { return mat4("
"cosh(x), 0., 0., sinh(x),\n" "cosh(x), 0., 0., sinh(x),\n"
"0., 1., 0., 0.,\n" "0., 1., 0., 0.,\n"
"0., 0., 1., 0.,\n" "0., 0., 1., 0.,\n"
"sinh(x), 0., 0., cosh(x)" "sinh(x), 0., 0., cosh(x)"
");}\n" ");}\n";
if(IN_ODS) fsh +=
"mat4 xzspin(float x) { return mat4(" "mat4 xzspin(float x) { return mat4("
"cos(x), 0., sin(x), 0.,\n" "cos(x), 0., sin(x), 0.,\n"
@ -184,6 +197,9 @@ void enable_raycaster() {
fsh += fsh +=
"vec2 map_texture(vec4 pos, int which) {\n"; "vec2 map_texture(vec4 pos, int which) {\n";
if(nil) fsh += "if(which == 2 || which == 5) pos.z = 0.;\n"; if(nil) fsh += "if(which == 2 || which == 5) pos.z = 0.;\n";
else if(hyperbolic && binarytiling) fsh +=
"pos = vec4(-log(pos.w-pos.x), pos.y, pos.z, 1);\n"
"pos.yz *= exp(pos.x);\n";
else if(hyperbolic) fsh += else if(hyperbolic) fsh +=
"pos /= pos.w;\n"; "pos /= pos.w;\n";
else if(prod) fsh += else if(prod) fsh +=
@ -269,7 +285,7 @@ void enable_raycaster() {
fmain += fmain +=
" if(which == -1) {\n"; " if(which == -1) {\n";
fmain += "for(int i=0; i<"+its(S7)+"; i++) {\n"; fmain += "for(int i="+its(flat1)+"; i<"+its(flat2)+"; i++) {\n";
if(in_h2xe()) fmain += if(in_h2xe()) fmain +=
" float v = ((position - uM[i] * position)[2] / (uM[i] * tangent - tangent)[2]);\n" " float v = ((position - uM[i] * position)[2] / (uM[i] * tangent - tangent)[2]);\n"
@ -301,6 +317,31 @@ void enable_raycaster() {
fmain += fmain +=
" if(d < dist) { dist = d; which = i; }\n" " if(d < dist) { dist = d; which = i; }\n"
"}\n"; "}\n";
// 20: get to horosphere +uBLevel (take smaller root)
// 21: get to horosphere -uBLevel (take larger root)
if(hyperbolic && binarytiling) {
fmain +=
"for(int i=20; i<22; i++) {\n"
"float sgn = i == 20 ? -1. : 1.;\n"
"vec4 zpos = xpush(uBLevel*sgn) * position;\n"
"vec4 ztan = xpush(uBLevel*sgn) * tangent;\n"
"float Mp = zpos.w - zpos.x;\n"
"float Mt = ztan.w - ztan.x;\n"
"float a = (Mp*Mp-Mt*Mt);\n"
"float b = Mp/a;\n"
"float c = (1.+Mt*Mt) / a;\n"
"if(b*b < c) continue;\n"
"if(sgn < 0. && Mt > 0.) continue;\n"
"float zsgn = (Mt > 0. ? -sgn : sgn);\n"
"float u = sqrt(b*b-c)*zsgn + b;\n"
"float v = -(Mp*u-1.) / Mt;\n"
"float d = asinh(v);\n"
"if(d < 0. && abs(log(position.w*position.w-position.x*position.x)) < uBLevel) continue;\n"
"if(d < dist) { dist = d; which = i; }\n"
"}\n";
}
if(prod) fmain += if(prod) fmain +=
"if(zspeed > 0.) { float d = (uPLevel - zpos) / zspeed; if(d < dist) { dist = d; which = "+its(S7)+"+1; }}\n" "if(zspeed > 0.) { float d = (uPLevel - zpos) / zspeed; if(d < dist) { dist = d; which = "+its(S7)+"+1; }}\n"
@ -461,10 +502,29 @@ void enable_raycaster() {
else fmain += else fmain +=
"position = position + tangent * dist;\n"; "position = position + tangent * dist;\n";
if(hyperbolic && binarytiling) {
fmain +=
"if(which == 20) {\n"
" float best = 999.;\n"
" for(int i="+its(flat2)+"; i<"+its(S7)+"; i++) {\n"
" float cand = len(uM[i] * position);\n"
" if(cand < best) { best = cand; which = i; }\n"
" }\n"
"}\n"
"if(which == 21) {\n"
"float best = 999.;\n"
"for(int i=0; i<"+its(flat1)+"; i++) {\n"
" float cand = len(uM[i] * position);\n"
" if(cand < best) { best = cand; which = i; }\n"
" }\n"
// "gl_FragColor = vec4(.5 + .5 * sin((go+dist)*100.), 1, float(which)/3., 1); return;\n"
"}\n";
}
fmain += " go = go + dist;\n"; fmain += " go = go + dist;\n";
fmain += "if(which == -1) continue;\n"; fmain += "if(which == -1) continue;\n";
if(prod) fmain += "position.w = -zpos;\n"; if(prod) fmain += "position.w = -zpos;\n";
// apply wall color // apply wall color
@ -525,6 +585,17 @@ void enable_raycaster() {
if(use_reflect) { if(use_reflect) {
if(prod) fmain += "if(reflect && which >= "+its(S7)+") { zspeed = -zspeed; continue; }\n"; if(prod) fmain += "if(reflect && which >= "+its(S7)+") { zspeed = -zspeed; continue; }\n";
if(hyperbolic && binarytiling) fmain +=
"if(reflect && (which < "+its(flat1)+" || which >= "+its(flat2)+")) {\n"
" float x = -log(position.w - position.x);\n"
" vec4 xtan = xpush(-x) * tangent;\n"
" float diag = (position.y*position.y+position.z*position.z)/2.;\n"
" vec4 normal = vec4(1.-diag, -position.y, -position.z, -diag);\n"
" float mdot = dot(xtan.xyz, normal.xyz) - xtan.w * normal.w;\n"
" xtan = xtan - normal * mdot * 2.;\n"
" tangent = xpush(x) * xtan;\n"
" continue;\n"
" }\n";
if(sol) fmain += if(sol) fmain +=
" if(reflect) {\n" " if(reflect) {\n"
" if(which == 0 || which == 4) tangent.x = -tangent.x;\n" " if(which == 0 || which == 4) tangent.x = -tangent.x;\n"
@ -765,6 +836,8 @@ EX void cast() {
glUniform1f(o->uBinaryWidth, vid.binary_width * log(2) / 2); glUniform1f(o->uBinaryWidth, vid.binary_width * log(2) / 2);
if(o->uPLevel != -1) if(o->uPLevel != -1)
glUniform1f(o->uPLevel, cgi.plevel / 2); glUniform1f(o->uPLevel, cgi.plevel / 2);
if(o->uBLevel != -1)
glUniform1f(o->uBLevel, log(binary::expansion()) / 2);
glUniform1f(o->uLinearSightRange, sightranges[geometry]); glUniform1f(o->uLinearSightRange, sightranges[geometry]);
glUniform1f(o->uExpDecay, exp_decay_current()); glUniform1f(o->uExpDecay, exp_decay_current());