mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-24 07:56:59 +00:00
ray:: bitruncated product
This commit is contained in:
parent
5de9c4cc16
commit
02de6fa330
@ -1064,6 +1064,25 @@ EX namespace hybrid {
|
|||||||
EX geometry_information *underlying_cgip;
|
EX geometry_information *underlying_cgip;
|
||||||
|
|
||||||
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;
|
||||||
@ -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;
|
||||||
|
106
raycaster.cpp
106
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,12 +177,22 @@ 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"
|
||||||
@ -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,8 +239,12 @@ 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";
|
||||||
flat1 = bt::dirs_outer();
|
flat1 = bt::dirs_outer();
|
||||||
@ -328,6 +346,8 @@ void enable_raycaster() {
|
|||||||
else fmain +=
|
else fmain +=
|
||||||
" 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"
|
||||||
@ -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;
|
||||||
@ -949,14 +975,28 @@ EX void cast() {
|
|||||||
GLERR("uniform mediump startid");
|
GLERR("uniform mediump startid");
|
||||||
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,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++) {
|
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);
|
||||||
glUniform1iv(o->uWallstart, isize(wallstart), &wallstart[0]);
|
glUniform1iv(o->uWallstart, isize(wallstart), &wallstart[0]);
|
||||||
|
Loading…
Reference in New Issue
Block a user