mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	ray:: bitruncated product
This commit is contained in:
		| @@ -1065,6 +1065,25 @@ EX namespace hybrid { | |||||||
|  |  | ||||||
|   EX eGeometryClass under_class() { return ginf[hybrid::underlying].cclass; }   |   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) { |   EX void configure(eGeometry g) { | ||||||
|     if(WDIM == 3) return; |     if(WDIM == 3) return; | ||||||
|     ray::reset_raycaster(); |     ray::reset_raycaster(); | ||||||
| @@ -1257,11 +1276,14 @@ EX namespace hybrid { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|    |    | ||||||
|  |   EX vector<cell*> samples; | ||||||
|  |    | ||||||
|   EX int wall_offset(cell *c) { |   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); |     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); |     if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, -1); | ||||||
|     int &wo = cgi.walloffsets[id]; |     int &wo = cgi.walloffsets[id]; | ||||||
|     if(wo == -1) { |     if(wo == -1) { | ||||||
|  |       samples.push_back(c); | ||||||
|       cell *c1 = hybrid::get_where(c).first; |       cell *c1 = hybrid::get_where(c).first; | ||||||
|       wo = isize(cgi.shWall3D); |       wo = isize(cgi.shWall3D); | ||||||
|       int won = wo + c->type; |       int won = wo + c->type; | ||||||
|   | |||||||
							
								
								
									
										104
									
								
								raycaster.cpp
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								raycaster.cpp
									
									
									
									
									
								
							| @@ -97,6 +97,7 @@ struct raycaster : glhr::GLprogram { | |||||||
|   GLint uLinearSightRange, uExpStart, uExpDecay; |   GLint uLinearSightRange, uExpStart, uExpDecay; | ||||||
|   GLint uBLevel; |   GLint uBLevel; | ||||||
|   GLint uPosX, uPosY; |   GLint uPosX, uPosY; | ||||||
|  |   GLint uWallOffset, uSides; | ||||||
|    |    | ||||||
|   raycaster(string vsh, string fsh); |   raycaster(string vsh, string fsh); | ||||||
|   }; |   }; | ||||||
| @@ -134,6 +135,9 @@ raycaster::raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) { | |||||||
|     tWallcolor = glGetUniformLocation(_program, "tWallcolor"); |     tWallcolor = glGetUniformLocation(_program, "tWallcolor"); | ||||||
|     tTextureMap = glGetUniformLocation(_program, "tTextureMap"); |     tTextureMap = glGetUniformLocation(_program, "tTextureMap"); | ||||||
|      |      | ||||||
|  |     uWallOffset = glGetUniformLocation(_program, "uWallOffset"); | ||||||
|  |     uSides = glGetUniformLocation(_program, "uSides"); | ||||||
|  |      | ||||||
|     uPosX = glGetUniformLocation(_program, "uPosX"); |     uPosX = glGetUniformLocation(_program, "uPosX"); | ||||||
|     uPosY = glGetUniformLocation(_program, "uPosY"); |     uPosY = glGetUniformLocation(_program, "uPosY"); | ||||||
|     } |     } | ||||||
| @@ -173,13 +177,23 @@ EX hookset<void(string&, string&)> hooks_rayshader; | |||||||
| EX hookset<bool(shared_ptr<raycaster>)> hooks_rayset; | EX hookset<bool(shared_ptr<raycaster>)> hooks_rayset; | ||||||
|  |  | ||||||
| void enable_raycaster() { | 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<int>(deg, c->type); | ||||||
|  |   else | ||||||
|  |     deg = centerover->type; | ||||||
|  |    | ||||||
|   last_geometry = geometry; |   last_geometry = geometry; | ||||||
|   deg = S7; if(prod) deg += 2; |  | ||||||
|   if(!our_raycaster) {  |   if(!our_raycaster) {  | ||||||
|     bool asonov = hr::asonov::in(); |     bool asonov = hr::asonov::in(); | ||||||
|     bool use_reflect = reflect_val && !nil && !levellines; |     bool use_reflect = reflect_val && !nil && !levellines; | ||||||
|      |      | ||||||
|  |     bool bi = BITRUNCATED; | ||||||
|  |  | ||||||
|     string vsh =  |     string vsh =  | ||||||
|       "attribute mediump vec4 aPosition;\n" |       "attribute mediump vec4 aPosition;\n" | ||||||
|       "uniform mediump float uFovX, uFovY, uPosX, uPosY, uShift;\n" |       "uniform mediump float uFovX, uFovY, uPosX, uPosY, uShift;\n" | ||||||
| @@ -211,7 +225,7 @@ void enable_raycaster() { | |||||||
|     "uniform mediump vec4 uWallX["+rays+"];\n" |     "uniform mediump vec4 uWallX["+rays+"];\n" | ||||||
|     "uniform mediump vec4 uWallY["+rays+"];\n" |     "uniform mediump vec4 uWallY["+rays+"];\n" | ||||||
|     "uniform mediump vec4 uFogColor;\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"; |     "uniform mediump float uLinearSightRange, uExpStart, uExpDecay;\n"; | ||||||
|      |      | ||||||
|     #ifdef GLES_ONLY |     #ifdef GLES_ONLY | ||||||
| @@ -225,7 +239,11 @@ void enable_raycaster() { | |||||||
|       "uniform mediump float uPLevel;\n" |       "uniform mediump float uPLevel;\n" | ||||||
|       "uniform mediump mat4 uLP;\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()) { |     if(hyperbolic && bt::in()) { | ||||||
|       fsh += "uniform mediump float uBLevel;\n"; |       fsh += "uniform mediump float uBLevel;\n"; | ||||||
| @@ -329,6 +347,8 @@ void enable_raycaster() { | |||||||
|       "  mediump vec4 position = vw * vec4(0., 0., 0., 1.);\n" |       "  mediump vec4 position = vw * vec4(0., 0., 0., 1.);\n" | ||||||
|       "  mediump vec4 tangent = vw * at0;\n"; |       "  mediump vec4 tangent = vw * at0;\n"; | ||||||
|        |        | ||||||
|  |     if(bi) fmain += "  walloffset = uWallOffset; sides = uSides;\n"; | ||||||
|  |      | ||||||
|     fmain +=      |     fmain +=      | ||||||
|       "  mediump float go = 0.;\n" |       "  mediump float go = 0.;\n" | ||||||
|       "  mediump vec2 cid = uStartid;\n" |       "  mediump vec2 cid = uStartid;\n" | ||||||
| @@ -345,7 +365,7 @@ void enable_raycaster() { | |||||||
|     if(IN_ODS) fmain +=  |     if(IN_ODS) fmain +=  | ||||||
|       "  if(go == 0.) {\n" |       "  if(go == 0.) {\n" | ||||||
|       "    mediump float best = len(position);\n" |       "    mediump float best = len(position);\n" | ||||||
|       "    for(int i=0; i<"+its(S7)+"; i++) {\n" |       "    for(int i=0; i<sides; i++) {\n" | ||||||
|       "      mediump float cand = len(uM[i] * position);\n" |       "      mediump float cand = len(uM[i] * position);\n" | ||||||
|       "      if(cand < best - .001) { dist = 0.; best = cand; which = i; }\n" |       "      if(cand < best - .001) { dist = 0.; best = cand; which = i; }\n" | ||||||
|       "      }\n" |       "      }\n" | ||||||
| @@ -356,28 +376,28 @@ void enable_raycaster() { | |||||||
|       fmain += |       fmain += | ||||||
|         "  if(which == -1) {\n"; |         "  if(which == -1) {\n"; | ||||||
|        |        | ||||||
|       fmain += "for(int i="+its(flat1)+"; i<"+its(flat2)+"; i++) {\n"; |       fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : its(flat2))+"; i++) {\n"; | ||||||
|        |        | ||||||
|       if(in_h2xe()) fmain += |       if(in_h2xe()) 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" | ||||||
|           "    if(v > 1. || v < -1.) continue;\n" |           "    if(v > 1. || v < -1.) continue;\n" | ||||||
|           "    mediump float d = atanh(v);\n" |           "    mediump float d = atanh(v);\n" | ||||||
|           "    mediump vec4 next_tangent = position * sinh(d) + tangent * cosh(d);\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"; |           "    d /= xspeed;\n"; | ||||||
|       else if(in_s2xe()) fmain += |       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 float d = atan(v);\n" | ||||||
|           "    mediump vec4 next_tangent = tangent * cos(d) - position * sin(d);\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"; |           "    d /= xspeed;\n"; | ||||||
|       else if(in_e2xe()) fmain += |       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" |           "    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" |           "    if(d < 0.) continue;\n" | ||||||
|           "    mediump vec4 next_position = position + d * tangent;\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"; |           "    d /= xspeed;\n"; | ||||||
|       else if(hyperbolic) fmain += |       else if(hyperbolic) fmain += | ||||||
|           "    mediump float v = ((position - uM[i] * position)[3] / (uM[i] * tangent - tangent)[3]);\n" |           "    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(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 = sides-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-2; }}\n"; | ||||||
|        |        | ||||||
|       fmain += "}\n"; |       fmain += "}\n"; | ||||||
|  |  | ||||||
| @@ -681,7 +701,7 @@ void enable_raycaster() { | |||||||
|       fmain += "    if(go > float(" + fts(hard_limit) + ")) { gl_FragDepth = 1.; return; }\n"; |       fmain += "    if(go > float(" + fts(hard_limit) + ")) { gl_FragDepth = 1.; return; }\n"; | ||||||
|      |      | ||||||
|     if(!(levellines && disable_texture)) fmain += |     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" |       "    mediump vec3 tmap = texture2D(tTextureMap, u).rgb;\n" | ||||||
|       "    if(tmap.z == 0.) col.xyz *= min(1., (1.-inface.x)/ tmap.x);\n" |       "    if(tmap.z == 0.) col.xyz *= min(1., (1.-inface.x)/ tmap.x);\n" | ||||||
|       "    else {\n" |       "    else {\n" | ||||||
| @@ -745,7 +765,7 @@ void enable_raycaster() { | |||||||
|       "    }\n"; |       "    }\n"; | ||||||
|  |  | ||||||
|     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(deg-2)+") { zspeed = -zspeed; continue; }\n"; | ||||||
|       if(hyperbolic && bt::in()) fmain += |       if(hyperbolic && bt::in()) fmain += | ||||||
|         "if(reflect && (which < "+its(flat1)+" || which >= "+its(flat2)+")) {\n" |         "if(reflect && (which < "+its(flat1)+" || which >= "+its(flat2)+")) {\n" | ||||||
|         "  mediump float x = -log(position.w - position.x);\n" |         "  mediump float x = -log(position.w - position.x);\n" | ||||||
| @@ -800,15 +820,23 @@ void enable_raycaster() { | |||||||
|       "  cid = connection.xy;\n"; |       "  cid = connection.xy;\n"; | ||||||
|      |      | ||||||
|     if(prod) fmain += |     if(prod) fmain += | ||||||
|       "  if(which == "+its(S7)+") { zpos += uPLevel+uPLevel; }\n" |       "  if(which == sides-2) { zpos += uPLevel+uPLevel; }\n" | ||||||
|       "  if(which == "+its(S7)+"+1) { zpos -= uPLevel+uPLevel; }\n"; |       "  if(which == sides-1) { zpos -= uPLevel+uPLevel; }\n"; | ||||||
|      |      | ||||||
|     fmain += |     fmain += | ||||||
|       "  int mid = int(connection.z * 1024.);\n" |       "  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" |       "  position = m * position;\n" | ||||||
|       "  tangent = m *  tangent;\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 +=  |     fmain +=  | ||||||
|       "  }\n" |       "  }\n" | ||||||
|       "  gl_FragColor.xyz += left * uFogColor.xyz;\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)); |   glUniform1f(o->uPosY, -((cd->ycenter-cd->ytop)*2./cd->ysize - 1)); | ||||||
|    |    | ||||||
|   if(!callhandlers(false, hooks_rayset, o)) { |   if(!callhandlers(false, hooks_rayset, o)) { | ||||||
|   deg = S7; |  | ||||||
|   if(prod) deg += 2; |  | ||||||
|    |    | ||||||
|   length = 4096; |   length = 4096; | ||||||
|   per_row = length / deg; |   per_row = length / deg; | ||||||
| @@ -950,13 +976,27 @@ EX void cast() { | |||||||
|   glUniform1f(o->uIPD, vid.ipd); |   glUniform1f(o->uIPD, vid.ipd); | ||||||
|   GLERR("uniform mediump IPD"); |   GLERR("uniform mediump IPD"); | ||||||
|    |    | ||||||
|  |   if(o->uWallOffset != -1) { | ||||||
|  |     glUniform1i(o->uWallOffset, wall_offset(centerover)); | ||||||
|  |     glUniform1i(o->uSides, centerover->type); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   vector<cell*> sa = {centerover}; | ||||||
|  |   if(hybri) sa = hybrid::samples; | ||||||
|  |    | ||||||
|   vector<transmatrix> ms; |   vector<transmatrix> ms; | ||||||
|   for(int j=0; j<S7; j++) ms.push_back(currentmap->iadj(cwt.at, j)); |   for(auto c: sa) { | ||||||
|   if(prod) ms.push_back(mscale(Id, +cgi.plevel)); |     for(int j=0; j<c->type; j++) { | ||||||
|   if(prod) ms.push_back(mscale(Id, -cgi.plevel)); |       if(hybri) | ||||||
|  |         ms.push_back(hybrid::ray_iadj(c, j)); | ||||||
|  |       else | ||||||
|  |         ms.push_back(currentmap->iadj(c, j)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|    |    | ||||||
|   if(!sol && !nil && reflect_val) { |   if(!sol && !nil && reflect_val) { | ||||||
|     for(int j=0; j<S7; j++) { |     if(BITRUNCATED) exit(1); | ||||||
|  |     for(int j=0; j<centerover->type; j++) { | ||||||
|       transmatrix T = inverse(ms[j]); |       transmatrix T = inverse(ms[j]); | ||||||
|       hyperpoint h = tC0(T); |       hyperpoint h = tC0(T); | ||||||
|       ld d = hdist0(h); |       ld d = hdist0(h); | ||||||
| @@ -1011,17 +1051,25 @@ 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++) { |       for(int k=0; k<=isize(ms); k++) { | ||||||
|         if(k < isize(ms) && !eqmatrix(ms[k], T)) continue; |         if(k < isize(ms) && !eqmatrix(ms[k], T)) continue; | ||||||
|         if(k == isize(ms)) ms.push_back(T); |         if(k == isize(ms)) ms.push_back(T); | ||||||
|         connections[u][2] = (k+.5) / 1024.; |         connections[u][2] = (k+.5) / 1024.; | ||||||
|         break; |         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<GLint> wallstart; |   vector<GLint> wallstart; | ||||||
|   for(auto i: cgi.wallstart) wallstart.push_back(i); |   for(auto i: cgi.wallstart) wallstart.push_back(i); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue