mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	ray:: horospherical hyperbolic honeycombs
This commit is contained in:
		| @@ -558,6 +558,21 @@ EX namespace binary { | ||||
|     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() { | ||||
|     if(among(geometry, gBinaryTiling, gSol)) return; // unused | ||||
|     use_direct = (1 << (S7-1)) - 1; | ||||
|   | ||||
| @@ -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) { | ||||
|   transmatrix T = Id; | ||||
|   ld R = hypot(H[f], H[t]); | ||||
|   | ||||
							
								
								
									
										15
									
								
								polygons.cpp
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								polygons.cpp
									
									
									
									
									
								
							| @@ -709,6 +709,11 @@ void geometry_information::compute_cornerbonus() { } | ||||
|  | ||||
| hyperpoint ray_kleinize(hyperpoint h, int id, ld pz) { | ||||
|   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) { | ||||
|     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; | ||||
|     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); | ||||
|  | ||||
|       hyperpoint hcenter = point3(0,0,-z); | ||||
| @@ -929,10 +934,10 @@ void geometry_information::create_wall3d() { | ||||
|       hyperpoint hcn = T*point3(-h*2,0,  -z); | ||||
|       hyperpoint hun = T*point3(-h*3,+r3,-z); | ||||
|       hyperpoint hdn = T*point3(-h*3,-r3,-z); | ||||
|       make_wall(i, {hcenter, hu0, hu1, hd1, hd0}); | ||||
|       make_wall(i+3, {hcn, hun, hdn}); | ||||
|       make_wall(i+6, make4(hd1, hu1, hd1+down)); | ||||
|       make_wall(i+9, make4(hun, hdn, hun+down)); | ||||
|       if(j == 0) make_wall(i, {hcenter, hu0, hu1, hd1, hd0}); | ||||
|       if(j == 1) make_wall(i+3, {hcn, hun, hdn}); | ||||
|       if(j == 2) make_wall(i+6, make4(hd1, hu1, hd1+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)}); | ||||
|   | ||||
| @@ -54,7 +54,7 @@ eGeometry last_geometry; | ||||
| /** is the raycaster available? */ | ||||
| EX bool available() { | ||||
|   if(WDIM == 2) return false; | ||||
|   if(hyperbolic && pmodel == mdPerspective && !binarytiling) | ||||
|   if(hyperbolic && pmodel == mdPerspective && !penrose) | ||||
|     return true; | ||||
|   if((sol || nil) && pmodel == mdGeodesic) | ||||
|     return true; | ||||
| @@ -79,6 +79,7 @@ struct raycaster : glhr::GLprogram { | ||||
|   GLint tConnections, tWallcolor, tTextureMap; | ||||
|   GLint uBinaryWidth, uPLevel, uLP; | ||||
|   GLint uLinearSightRange, uExpStart, uExpDecay; | ||||
|   GLint uBLevel; | ||||
|    | ||||
|   raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) { | ||||
|     println(hlog, "assigning"); | ||||
| @@ -102,6 +103,8 @@ struct raycaster : glhr::GLprogram { | ||||
|     uExpDecay = glGetUniformLocation(_program, "uExpDecay"); | ||||
|     uExpStart = glGetUniformLocation(_program, "uExpStart"); | ||||
|  | ||||
|     uBLevel = glGetUniformLocation(_program, "uBLevel"); | ||||
|    | ||||
|     tConnections = glGetUniformLocation(_program, "tConnections"); | ||||
|     tWallcolor = glGetUniformLocation(_program, "tWallcolor"); | ||||
|     tTextureMap = glGetUniformLocation(_program, "tTextureMap"); | ||||
| @@ -158,14 +161,24 @@ void enable_raycaster() { | ||||
|       "uniform float uPLevel;\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(" | ||||
|          "cosh(x), 0., 0., sinh(x),\n" | ||||
|          "0., 1., 0., 0.,\n" | ||||
|          "0., 0., 1., 0.,\n" | ||||
|          "sinh(x), 0., 0., cosh(x)" | ||||
|          ");}\n" | ||||
|          ");}\n"; | ||||
|      | ||||
|     if(IN_ODS) fsh +=  | ||||
|  | ||||
|     "mat4 xzspin(float x) { return mat4(" | ||||
|          "cos(x), 0., sin(x), 0.,\n" | ||||
| @@ -184,6 +197,9 @@ void enable_raycaster() { | ||||
|    fsh +=  | ||||
|      "vec2 map_texture(vec4 pos, int which) {\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 +=  | ||||
|        "pos /= pos.w;\n"; | ||||
|    else if(prod) fsh += | ||||
| @@ -269,7 +285,7 @@ void enable_raycaster() { | ||||
|       fmain += | ||||
|         "  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 += | ||||
|           "    float v = ((position - uM[i] * position)[2] / (uM[i] * tangent - tangent)[2]);\n" | ||||
| @@ -302,6 +318,31 @@ void enable_raycaster() { | ||||
|           "  if(d < dist) { dist = d; which = i; }\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(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)+"; }}\n"; | ||||
| @@ -461,6 +502,25 @@ void enable_raycaster() { | ||||
|     else fmain +=  | ||||
|       "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 += "if(which == -1) continue;\n"; | ||||
| @@ -525,6 +585,17 @@ void enable_raycaster() { | ||||
|  | ||||
|     if(use_reflect) { | ||||
|       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(reflect) {\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); | ||||
|   if(o->uPLevel != -1) | ||||
|     glUniform1f(o->uPLevel, cgi.plevel / 2); | ||||
|   if(o->uBLevel != -1) | ||||
|     glUniform1f(o->uBLevel, log(binary::expansion()) / 2); | ||||
|    | ||||
|   glUniform1f(o->uLinearSightRange, sightranges[geometry]); | ||||
|   glUniform1f(o->uExpDecay, exp_decay_current()); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue