From 9349d08117352cf4a2fd78f15e1ac390818e9e98 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 21 Jun 2024 13:46:31 +0200 Subject: [PATCH] twisted ray now takes angle_of_zero into account --- geometry.cpp | 5 +++-- graph.cpp | 3 ++- polygons.cpp | 11 ++++++----- raycaster.cpp | 52 ++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/geometry.cpp b/geometry.cpp index 60e0074d..f0a98270 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -132,6 +132,8 @@ struct subcellshape { vector> next_dir; /** useful in product geometries */ vector walltester; + /** needed for twisted */ + ld angle_of_zero; /** compute all the properties based on `faces`, for the main heptagon cellshape */ void compute_hept(); @@ -168,8 +170,6 @@ struct geometry_information { /** distance between hexagon vertex and hexagon center */ ld hexvdist; - ld unused_value_1; /* removed */ - /** distance from heptagon center to heptagon vertex (either hexf or hcrossf) */ ld rhexf; @@ -371,6 +371,7 @@ hpcshape vector walltester; vector wallstart; + vector angle_of_zero; /* needed for twisted, especially Archimedean */ vector raywall; vector all_plain_floorshapes; diff --git a/graph.cpp b/graph.cpp index 400c58d5..8c5354fb 100644 --- a/graph.cpp +++ b/graph.cpp @@ -4355,6 +4355,7 @@ EX subcellshape& generate_subcellshape_if_needed(cell *c, int id) { for(int i=0; itype; i++) ss.faces.push_back({hybrid::get_corner(c1, i, 0, -1), hybrid::get_corner(c1, i, 0, +1), hybrid::get_corner(c1, i, 1, +1), hybrid::get_corner(c1, i, 1, -1)}); + ss.angle_of_zero = -PIU(atan2(currentmap->adj(c1, 0)*C0)); for(int a: {0,1}) { vector l; int z = a ? 1 : -1; @@ -4395,7 +4396,7 @@ int hrmap::wall_offset(cell *c) { if(!cgi.wallstart.empty()) cgi.wallstart.pop_back(); cgi.reserve_wall3d(wo + isize(ss.faces)); - kleinize_sides = isize(ss.faces) - 2; + rk_shape = &ss; for(int i=0; ifaces)-2, rk_shape->angle_of_zero, id); #if CAP_BT if(hyperbolic && bt::in()) { // ld co = vid.binary_width / log(2) / 4; @@ -945,6 +945,7 @@ void geometry_information::make_wall(int wo, int id, vector vertices int id1 = wo + id; wallstart.push_back(isize(raywall)); + angle_of_zero.push_back(mtwisted ? rk_shape->angle_of_zero : 0); // orient correctly transmatrix T; diff --git a/raycaster.cpp b/raycaster.cpp index 717ce2ee..6a402964 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -161,7 +161,7 @@ EX bool requested() { #if HDR struct raycaster : glhr::GLprogram { GLint uStart, uStartid, uM, uLength; - GLint uWallstart, uWallX, uWallY; + GLint uWallstart, uWallangle, uWallX, uWallY; GLint tConnections, tWallcolor, tTextureMap, tVolumetric, tStart; GLint uBinaryWidth, uPLevel, uLP, uStraighten, uReflectX, uReflectY; GLint uLinearSightRange, uExpStart, uExpDecay; @@ -204,6 +204,7 @@ raycaster::raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) { uProjection = glGetUniformLocation(_program, "uProjection"); uWallstart = glGetUniformLocation(_program, "uWallstart"); + uWallangle = glGetUniformLocation(_program, "uWallangle"); uWallX = glGetUniformLocation(_program, "uWallX"); uWallY = glGetUniformLocation(_program, "uWallY"); @@ -332,6 +333,13 @@ struct raygen { return "uWallstart[" + s + "]"; }; + string getWallangle(string s) { + if(wall_via_texture) + return "getWallangle(" + s + ")"; + else + return "uWallangle[" + s + "]"; + }; + void compute_which_and_dist(int flat1, int flat2); void apply_reflect(int flat1, int flat2); void move_forward(); @@ -867,7 +875,7 @@ void raygen::move_forward() { " }\n"; if(mtwisted) fmain += " if(which == -1) {\n" - " mediump float z = twist_zlevel(nposition, sides-2);\n" + " mediump float z = twist_zlevel(nposition, sides-2, walloffset);\n" " if(z > uPLevel) which = sides-1;\n" " if(z <-uPLevel) which = sides-2;\n" " }\n"; @@ -1408,8 +1416,8 @@ void raygen::emit_iterate(int gid1) { if(nilv::get_nsi() == 0) fmain += "if(which == 2 || which == 5) pos.z = 0.;\n"; if(nilv::get_nsi() == 2) fmain += "if(which == 6 || which == 7) pos.z = 0.;\n"; else if(mtwisted) { - fmain += "pos = twist_coordinates(pos, sides-2, which);\n"; - string spinner = "h = cspin(0, 1, PI) * h;\n"; + fmain += "pos = twist_coordinates(pos, sides-2, which, which+walloffset);\n"; + string spinner = "h = cspin(0, 1, getWallangle(wai)) * h;\n"; string calc_dxy = nil ? "dx = h.x; dy = -h.y;\n" : sl2 ? "dx = -2. * (h.y*h.z - h.x*h.w);\n" "dy = -2. * (h.x*h.z + h.y*h.w);\n" : @@ -1426,7 +1434,7 @@ void raygen::emit_iterate(int gid1) { "vec4 h1 = lorentz(1, 3, -vy) * lorentz(0, 2, -vy) * lorentz(0, 3, -vx) * lorentz(2, 1, vx) * h;\n" : "vec4 h1 = cspin(0, 3, vy) * cspin(1, 2, -vy) * cspin(1, 3, -vx) * cspin(0, 2, -vx) * h;\n"; fsh += - "vec4 twist_coordinates(vec4 h, int ks, int id) {\n" + "vec4 twist_coordinates(vec4 h, int ks, int id, int wai) {\n" +spinner+ "if(id < ks) h = cspin(0, 1, -TAU * float(id) / float(ks)) * h;\n" +dcalc_dxy + @@ -1439,13 +1447,13 @@ void raygen::emit_iterate(int gid1) { "return dx*dx+dy*dy;\n" "}\n"; fsh += - "mediump float twist_zlevel(vec4 h, int ks) {\n" + spinner + dcalc_dxy + + "mediump float twist_zlevel(vec4 h, int ks, int wai) {\n" + spinner + dcalc_dxy + "float alpha = (floor(atan2(dy, dx) * float(ks) / TAU + 0.5)) * TAU / float(ks);\n" "h = cspin(1, 0, alpha) * h;\n" + calc_dxy + calc_vxy + calc_h1 + calc_vz + "return vz;\n" "}\n\n"; fsh += - "mediump bool twist_dark(vec4 h, int ks) {\n" + spinner + dcalc_dxy + + "mediump bool twist_dark(vec4 h, int ks, int wai) {\n" + spinner + dcalc_dxy + "float alpha = atan2(dy, dx) * float(ks);\n" "return cos(alpha) < -0.99;\n" "}\n\n"; @@ -1458,10 +1466,10 @@ void raygen::emit_iterate(int gid1) { "pos /= pos.w;\n"; else if(gproduct && bt::in()) fmain += "pos.xy = deparabolic12(pos).xy;\n" - "pos.z = -pos.w; pos.w = 0.;\n" -; + "pos.z = -pos.w; pos.w = 0.;\n"; else if(gproduct) fmain += "pos = vec4(pos.x/pos.z, pos.y/pos.z, -pos.w, 0);\n"; + fmain += " mediump vec2 inface = map_texture(pos, which+walloffset);\n" " mediump vec3 tmap = texture2D(tTextureMap, u).rgb;\n" @@ -1483,7 +1491,7 @@ void raygen::emit_iterate(int gid1) { " col.xyz = col.xyz * d + uFogColor.xyz * (1.-d);\n"; if(mtwisted) fmain += - " if(twist_dark(position, sides-2)) col.xyz /= 2.;\n"; + " if(twist_dark(position, sides-2, walloffset)) col.xyz /= 2.;\n"; else if(nilv::get_nsi() == 0) fmain += " if(abs(abs(position.x)-abs(position.y)) < .005) col.xyz /= 2.;\n"; else if(nilv::get_nsi() == 2) { @@ -2008,11 +2016,20 @@ void raygen::create() { " mediump vec4 v = texture2D(tWall, vec2((float(x)+.5) * uInvLengthWall, 0.625));\n" " return int(v[0] / uInvLengthWall);\n" " }\n"; + if(mtwisted) fsh += + "mediump float getWallangle(mediump int x) {\n" + " mediump vec4 v = texture2D(tWall, vec2((float(x)+.5) * uInvLengthWall, 0.625));\n" + " return v[1] * TAU;\n" + " }\n"; } - else fsh += + else { + fsh += "uniform mediump vec4 uWallX["+rays+"];\n" "uniform mediump vec4 uWallY["+rays+"];\n" "uniform mediump int uWallstart["+its(isize(cgi.wallstart))+"];\n"; + if(mtwisted) fsh += + "uniform mediump int uWallangle["+its(isize(cgi.wallstart))+"];\n"; + } if(m_via_texture) { fsh += @@ -2647,13 +2664,14 @@ EX void reset_raycaster_map() { rmap = nullptr; } -EX void load_walls(vector& wallx, vector& wally, vector& wallstart) { +EX void load_walls(vector& wallx, vector& wally, vector& wallstart, vector& wallangle) { int q = 0; if(isize(wallx)) { q = isize(wallx); wallstart.pop_back(); } for(auto i: cgi.wallstart) wallstart.push_back(q + i); + for(auto i: cgi.angle_of_zero) wallangle.push_back(frac(i / TAU)); dynamicval g(geometry, gCubeTiling); for(auto& m: cgi.raywall) { wallx.push_back(glhr::pointtogl(m[0])); @@ -2794,16 +2812,17 @@ EX void cast() { vector wallx, wally; vector wallstart; + vector wallangle; if(intra::in) { intra::resetter ir; for(int i=0; i