diff --git a/graph.cpp b/graph.cpp index 92b37085..00664865 100644 --- a/graph.cpp +++ b/graph.cpp @@ -7405,6 +7405,8 @@ EX void drawthemap() { use_raycasting = false; if(WDIM == 3 && hyperbolic && pmodel == mdPerspective && !binarytiling) use_raycasting = true; + if(WDIM == 3 && sol && pmodel == mdGeodesic) + use_raycasting = true; if(WDIM == 3 && euclid && pmodel == mdPerspective && !binarytiling) use_raycasting = true; diff --git a/raycaster.cpp b/raycaster.cpp index fdf9f3c8..ad1319e7 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -17,6 +17,7 @@ struct raycaster : glhr::GLprogram { GLint uStart, uStartid, uN, uM, uLength, uFovX, uFovY, uIPD; GLint uWallstart, uWallX, uWallY; GLint tConnections, tWallcolor, tMatrixid; + GLint uBinaryWidth; raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) { println(hlog, "assigning"); @@ -32,6 +33,8 @@ struct raycaster : glhr::GLprogram { uWallstart = glGetUniformLocation(_program, "uWallstart"); uWallX = glGetUniformLocation(_program, "uWallX"); uWallY = glGetUniformLocation(_program, "uWallY"); + + uBinaryWidth = glGetUniformLocation(_program, "uBinaryWidth"); tConnections = glGetUniformLocation(_program, "tConnections"); tWallcolor = glGetUniformLocation(_program, "tWallcolor"); @@ -137,44 +140,103 @@ void enable_raycaster() { " vec4 tangent = vw * at0;\n" " float go = 0.;\n" " float cid = uStartid;\n" - " for(int iter=0; iter<60; iter++) {\n" - " float dist = 100.;\n" - " int which = -1;\n" - + " for(int iter=0; iter<600; iter++) {\n"; + + if(sol) fmain += + " float dist = .01;\n"; + else fmain += + " float dist = 100.;\n"; + + fmain += + " int which = -1;\n"; + + if(IN_ODS) fmain += " if(go == 0.) {\n" " float best = len(position);\n" " for(int i=0; i 1. || v < -1.) continue;\n" - " float d = atanh(v);\n" - " vec4 next_tangent = position * sinh(d) + tangent * cosh(d);\n" - " if(next_tangent[3] < (uM[i] * next_tangent)[3]) continue;\n"; - else fmain += - " float deno = dot(position, tangent) - dot(uM[i]*position, uM[i]*tangent);\n" - " if(deno < 1e-6 && deno > -1e-6) continue;\n" - " float d = (dot(uM[i]*position, uM[i]*position) - dot(position, position)) / 2. / deno;\n" - " if(d < 0.) continue;\n" - " vec4 next_position = position + d * tangent;\n" - " if(dot(next_position, tangent) < dot(uM[i]*next_position, uM[i]*tangent)) continue;\n"; + if(sol) { + fsh += "uniform float uBinaryWidth;\n"; - fmain += - " if(d < dist) { dist = d; which = i; }\n" + fsh += + "vec4 christoffel(vec4 pos, vec4 vel, vec4 tra) {\n" + " return vec4(-vel.z*tra.x - vel.x*tra.z, vel.z*tra.y + vel.y * tra.z, vel.x*tra.x * exp(2.*pos.z) - vel.y * tra.y * exp(-2.*pos.z), 0.);\n" + " }\n"; + + fsh += + "vec4 get_pos(vec4 pos, vec4 tan) {\n" + "vec4 acc = christoffel(pos, tan, tan);\n" + "vec4 pos2 = pos + tan / 2.;\n" + "vec4 tan2 = tan + acc / 2.;\n" + "vec4 acc2 = christoffel(pos2, tan2, tan2);\n" + "return pos + tan + acc2 / 2.;\n" "}\n"; - fmain += - " if(which == -1) { gl_FragColor = vec4(0., 0., 0., 1.); return; }"; + fsh += + "float hp_distance(vec4 pos, vec4 tan, int axis, float value) {\n" + " if(value > 0. && pos[axis] > value) return 0.;\n" + " if(value < 0. && pos[axis] < value) return 0.;\n" + " if(tan[axis] == 0.) return .5;\n" + " float approx = (value - pos[axis]) / tan[axis];\n" + " for(int it=0; it<3; it++) {\n" + " if(approx <= 0. || approx > .5) return .5;\n" + " vec4 npos = get_pos(pos, tan * approx);\n" + " approx = approx * (value - pos[axis]) / (npos[axis] - pos[axis]);\n" + " }\n" + " if(approx < .001) approx = .001;\n" + " return approx;\n" + " }\n"; + + fmain += + " float d;\n" + " d = hp_distance(position, tangent, 0, uBinaryWidth);\n" + " if(d < dist) { dist = d; which = 0; }\n" + " d = hp_distance(position, tangent, 0, -uBinaryWidth);\n" + " if(d < dist) { dist = d; which = 4; }\n" + " d = hp_distance(position, tangent, 1, uBinaryWidth);\n" + " if(d < dist) { dist = d; which = 1; }\n" + " d = hp_distance(position, tangent, 1, -uBinaryWidth);\n" + " if(d < dist) { dist = d; which = 5; }\n" + " d = hp_distance(position, tangent, 2, log(2.)/2.);\n" + " if(d < dist) { dist = d; which = 2; }\n" + " d = hp_distance(position, tangent, 2, -log(2.)/2.);\n" + " if(d < dist) { dist = d; which = 6; }\n"; + } + else { + + fmain += + " if(which == -1) for(int i=0; i 1. || v < -1.) continue;\n" + " float d = atanh(v);\n" + " vec4 next_tangent = position * sinh(d) + tangent * cosh(d);\n" + " if(next_tangent[3] < (uM[i] * next_tangent)[3]) continue;\n"; + else fmain += + " float deno = dot(position, tangent) - dot(uM[i]*position, uM[i]*tangent);\n" + " if(deno < 1e-6 && deno > -1e-6) continue;\n" + " float d = (dot(uM[i]*position, uM[i]*position) - dot(position, position)) / 2. / deno;\n" + " if(d < 0.) continue;\n" + " vec4 next_position = position + d * tangent;\n" + " if(dot(next_position, tangent) < dot(uM[i]*next_position, uM[i]*tangent)) continue;\n"; + + fmain += + " if(d < dist) { dist = d; which = i; }\n" + "}\n"; + } + fmain += " if(dist < 0.) { dist = 0.; }\n"; + fmain += + " if(which == -1 && dist == 0.) { gl_FragColor = vec4(0., 0., 0., 1.); return; }"; + // shift d units fmain += " go = go + dist;\n"; @@ -184,8 +246,25 @@ void enable_raycaster() { " vec4 v = position * ch + tangent * sh;\n" " tangent = tangent * ch + position * sh;\n" " position = v;\n"; + else if(sol) { + fmain += + "vec4 acc = christoffel(position, tangent, tangent);\n" + "vec4 pos2 = position + tangent * dist / 2.;\n" + "vec4 tan2 = tangent + acc * dist / 2.;\n" + "vec4 acc2 = christoffel(pos2, tan2, tan2);\n" + "position = position + tangent * dist + acc2 / 2. * dist * dist;\n" + "tangent = tangent + acc * dist;\n"; + } else fmain += "position = position + tangent * dist;\n"; + + fmain += "if(which == -1) continue;\n"; + + if(sol) { + fmain += + "if(which == 2 && position.x > 0.) which = 3;\n" + "if(which == 6 && position.y > 0.) which = 7;\n"; + } // apply wall color fmain += @@ -299,7 +378,7 @@ EX void do_raycast() { GLERR("uniform IPD"); vector ms; - if(euclid) + if(euclid || sol) for(int j=0; jrelative_matrix(cwt.at->master, cwt.at->cmove(j)->master)); else for(int j=0; juWallX, isize(wallx), &wallx[0][0]); glUniform4fv(o->uWallY, isize(wally), &wally[0][0]); + if(o->uBinaryWidth != -1) + glUniform1f(o->uBinaryWidth, vid.binary_width * log(2) / 2); + vector gms; for(auto& m: ms) gms.push_back(glhr::tmtogl_transpose(m)); glUniformMatrix4fv(o->uM, isize(gms), 0, gms[0].as_array());