diff --git a/nonisotropic.cpp b/nonisotropic.cpp index d00d5caf..711d0d9d 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -1064,6 +1064,25 @@ EX namespace hybrid { EX geometry_information *underlying_cgip; EX eGeometryClass under_class() { return ginf[hybrid::underlying].cclass; } + + EX transmatrix ray_iadj(cell *c, int i) { + if(prod && i == c->type-2) return (mscale(Id, +cgi.plevel)); + if(prod && i == c->type-1) return (mscale(Id, -cgi.plevel)); + if(prod) { + transmatrix T; + cell *cw = hybrid::get_where(c).first; + hybrid::in_underlying_geometry([&] { + hyperpoint h0 = get_corner_position(cw, i); + hyperpoint h1 = get_corner_position(cw, (i+1)); + hyperpoint hm = mid(h0, h1); + ld d = hdist0(hm); + d *= 2; + T = xpush(-d) * spintox(hm); + }); + return T; + } + return currentmap->iadj(c, i); + } EX void configure(eGeometry g) { if(WDIM == 3) return; @@ -1257,11 +1276,14 @@ EX namespace hybrid { } } + EX vector samples; + EX int wall_offset(cell *c) { int id = hybrid::underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c); if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, -1); int &wo = cgi.walloffsets[id]; if(wo == -1) { + samples.push_back(c); cell *c1 = hybrid::get_where(c).first; wo = isize(cgi.shWall3D); int won = wo + c->type; diff --git a/raycaster.cpp b/raycaster.cpp index 25ff76ce..a82ddda8 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -97,6 +97,7 @@ struct raycaster : glhr::GLprogram { GLint uLinearSightRange, uExpStart, uExpDecay; GLint uBLevel; GLint uPosX, uPosY; + GLint uWallOffset, uSides; raycaster(string vsh, string fsh); }; @@ -134,6 +135,9 @@ raycaster::raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) { tWallcolor = glGetUniformLocation(_program, "tWallcolor"); tTextureMap = glGetUniformLocation(_program, "tTextureMap"); + uWallOffset = glGetUniformLocation(_program, "uWallOffset"); + uSides = glGetUniformLocation(_program, "uSides"); + uPosX = glGetUniformLocation(_program, "uPosX"); uPosY = glGetUniformLocation(_program, "uPosY"); } @@ -173,12 +177,22 @@ EX hookset hooks_rayshader; EX hookset)> hooks_rayset; void enable_raycaster() { - if(geometry != last_geometry) reset_raycaster(); + if(geometry != last_geometry) { + reset_raycaster(); + } + + deg = 0; + if(hybri) + for(auto c: hybrid::samples) deg = max(deg, c->type); + else + deg = centerover->type; + last_geometry = geometry; - deg = S7; if(prod) deg += 2; if(!our_raycaster) { bool asonov = hr::asonov::in(); bool use_reflect = reflect_val && !nil && !levellines; + + bool bi = BITRUNCATED; string vsh = "attribute mediump vec4 aPosition;\n" @@ -211,7 +225,7 @@ void enable_raycaster() { "uniform mediump vec4 uWallX["+rays+"];\n" "uniform mediump vec4 uWallY["+rays+"];\n" "uniform mediump vec4 uFogColor;\n" - "uniform mediump int uWallstart["+its(deg+1)+"];\n" + "uniform mediump int uWallstart["+its(isize(cgi.wallstart))+"];\n" "uniform mediump float uLinearSightRange, uExpStart, uExpDecay;\n"; #ifdef GLES_ONLY @@ -225,8 +239,12 @@ void enable_raycaster() { "uniform mediump float uPLevel;\n" "uniform mediump mat4 uLP;\n"; - int flat1 = 0, flat2 = S7; + if(bi) fsh += + "uniform int uWallOffset, uSides;\n"; + int flat1 = 0, flat2 = deg; + if(prod || rotspace) flat2 -= 2; + if(hyperbolic && bt::in()) { fsh += "uniform mediump float uBLevel;\n"; flat1 = bt::dirs_outer(); @@ -328,6 +346,8 @@ void enable_raycaster() { else fmain += " mediump vec4 position = vw * vec4(0., 0., 0., 1.);\n" " mediump vec4 tangent = vw * at0;\n"; + + if(bi) fmain += " walloffset = uWallOffset; sides = uSides;\n"; fmain += " mediump float go = 0.;\n" @@ -345,7 +365,7 @@ void enable_raycaster() { if(IN_ODS) fmain += " if(go == 0.) {\n" " mediump float best = len(position);\n" - " for(int i=0; i<"+its(S7)+"; i++) {\n" + " for(int i=0; i 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[2] < (uM[i] * next_tangent)[2]) continue;\n" + " if(next_tangent[2] < (uM[walloffset+i] * next_tangent)[2]) continue;\n" " d /= xspeed;\n"; else if(in_s2xe()) fmain += - " mediump float v = ((position - uM[i] * position)[2] / (uM[i] * tangent - tangent)[2]);\n" + " mediump float v = ((position - uM[walloffset+i] * position)[2] / (uM[walloffset+i] * tangent - tangent)[2]);\n" " mediump float d = atan(v);\n" " mediump vec4 next_tangent = tangent * cos(d) - position * sin(d);\n" - " if(next_tangent[2] > (uM[i] * next_tangent)[2]) continue;\n" + " if(next_tangent[2] > (uM[walloffset+i] * next_tangent)[2]) continue;\n" " d /= xspeed;\n"; else if(in_e2xe()) fmain += - " mediump float deno = dot(position, tangent) - dot(uM[i]*position, uM[i]*tangent);\n" + " mediump float deno = dot(position, tangent) - dot(uM[walloffset+i]*position, uM[walloffset+i]*tangent);\n" " if(deno < 1e-6 && deno > -1e-6) continue;\n" - " mediump float d = (dot(uM[i]*position, uM[i]*position) - dot(position, position)) / 2. / deno;\n" + " mediump float d = (dot(uM[walloffset+i]*position, uM[walloffset+i]*position) - dot(position, position)) / 2. / deno;\n" " if(d < 0.) continue;\n" " mediump vec4 next_position = position + d * tangent;\n" - " if(dot(next_position, tangent) < dot(uM[i]*next_position, uM[i]*tangent)) continue;\n" + " if(dot(next_position, tangent) < dot(uM[walloffset+i]*next_position, uM[walloffset+i]*tangent)) continue;\n" " d /= xspeed;\n"; else if(hyperbolic) fmain += " mediump float v = ((position - uM[i] * position)[3] / (uM[i] * tangent - tangent)[3]);\n" @@ -423,8 +443,8 @@ void enable_raycaster() { } if(prod) fmain += - "if(zspeed > 0.) { mediump float d = (uPLevel - zpos) / zspeed; if(d < dist) { dist = d; which = "+its(S7)+"+1; }}\n" - "if(zspeed < 0.) { mediump float d = (-uPLevel - zpos) / zspeed; if(d < dist) { dist = d; which = "+its(S7)+"; }}\n"; + "if(zspeed > 0.) { mediump float d = (uPLevel - zpos) / zspeed; if(d < dist) { dist = d; which = sides-1; }}\n" + "if(zspeed < 0.) { mediump float d = (-uPLevel - zpos) / zspeed; if(d < dist) { dist = d; which = sides-2; }}\n"; fmain += "}\n"; @@ -681,7 +701,7 @@ void enable_raycaster() { fmain += " if(go > float(" + fts(hard_limit) + ")) { gl_FragDepth = 1.; return; }\n"; if(!(levellines && disable_texture)) fmain += - " mediump vec2 inface = map_texture(position, which);\n" + " mediump vec2 inface = map_texture(position, which+walloffset);\n" " mediump vec3 tmap = texture2D(tTextureMap, u).rgb;\n" " if(tmap.z == 0.) col.xyz *= min(1., (1.-inface.x)/ tmap.x);\n" " else {\n" @@ -745,7 +765,7 @@ void enable_raycaster() { " }\n"; if(use_reflect) { - if(prod) fmain += "if(reflect && which >= "+its(S7)+") { zspeed = -zspeed; continue; }\n"; + if(prod) fmain += "if(reflect && which >= "+its(deg-2)+") { zspeed = -zspeed; continue; }\n"; if(hyperbolic && bt::in()) fmain += "if(reflect && (which < "+its(flat1)+" || which >= "+its(flat2)+")) {\n" " mediump float x = -log(position.w - position.x);\n" @@ -800,15 +820,23 @@ void enable_raycaster() { " cid = connection.xy;\n"; if(prod) fmain += - " if(which == "+its(S7)+") { zpos += uPLevel+uPLevel; }\n" - " if(which == "+its(S7)+"+1) { zpos -= uPLevel+uPLevel; }\n"; + " if(which == sides-2) { zpos += uPLevel+uPLevel; }\n" + " if(which == sides-1) { zpos -= uPLevel+uPLevel; }\n"; fmain += " int mid = int(connection.z * 1024.);\n" - " mediump mat4 m = " GET("uM", "mid") " * " GET("uM", "which") ";\n" + " mediump mat4 m = " GET("uM", "mid") " * " GET("uM", "walloffset+which") ";\n" " position = m * position;\n" " tangent = m * tangent;\n"; + if(bi) { + fmain += + "walloffset = int(connection.w * 256.);\n" + "sides = int(connection.w * 4096.) - 16 * walloffset;\n"; + + // fmain += "if(sides != 8) { gl_FragColor = vec4(.5,float(sides)/8.,.5,1); return; }"; + } + fmain += " }\n" " gl_FragColor.xyz += left * uFogColor.xyz;\n"; @@ -896,8 +924,6 @@ EX void cast() { glUniform1f(o->uPosY, -((cd->ycenter-cd->ytop)*2./cd->ysize - 1)); if(!callhandlers(false, hooks_rayset, o)) { - deg = S7; - if(prod) deg += 2; length = 4096; per_row = length / deg; @@ -949,14 +975,28 @@ EX void cast() { GLERR("uniform mediump startid"); glUniform1f(o->uIPD, vid.ipd); GLERR("uniform mediump IPD"); + + if(o->uWallOffset != -1) { + glUniform1i(o->uWallOffset, wall_offset(centerover)); + glUniform1i(o->uSides, centerover->type); + } + vector sa = {centerover}; + if(hybri) sa = hybrid::samples; + vector ms; - for(int j=0; jiadj(cwt.at, j)); - if(prod) ms.push_back(mscale(Id, +cgi.plevel)); - if(prod) ms.push_back(mscale(Id, -cgi.plevel)); + for(auto c: sa) { + for(int j=0; jtype; j++) { + if(hybri) + ms.push_back(hybrid::ray_iadj(c, j)); + else + ms.push_back(currentmap->iadj(c, j)); + } + } if(!sol && !nil && reflect_val) { - for(int j=0; jtype; j++) { transmatrix T = inverse(ms[j]); hyperpoint h = tC0(T); ld d = hdist0(h); @@ -1011,18 +1051,26 @@ EX void cast() { } } - transmatrix T = currentmap->iadj(c, i) * inverse(ms[i]); + transmatrix T = currentmap->iadj(c, i) * inverse(ms[wall_offset(c) + i]); for(int k=0; k<=isize(ms); k++) { if(k < isize(ms) && !eqmatrix(ms[k], T)) continue; if(k == isize(ms)) ms.push_back(T); connections[u][2] = (k+.5) / 1024.; break; } + connections[u][3] = (wall_offset(c1) / 256.) + (c1->type + .5) / 4096.; } } - - if(prod) ms[S7] = ms[S7+1] = Id; + if(prod) { + int id = 0; + for(auto c: sa) { + ms[id+c->type-2] = Id; + ms[id+c->type-1] = Id; + id += c->type; + } + } + vector wallstart; for(auto i: cgi.wallstart) wallstart.push_back(i); glUniform1iv(o->uWallstart, isize(wallstart), &wallstart[0]);