1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-20 11:54:48 +00:00

intra:: more portal combinations are working (product upwards, portal to self)

This commit is contained in:
Zeno Rogue 2021-09-30 16:13:47 +02:00
parent b3fc40a8fc
commit 8b6a745a8f
2 changed files with 89 additions and 62 deletions

View File

@ -49,6 +49,7 @@ hyperpoint portal_data::to_poco(hyperpoint h) const {
h[1] /= h[2]; h[1] /= h[2];
h[2] = dec.first - d; h[2] = dec.first - d;
h[3] = 1; h[3] = 1;
if(d<0) h[2] = -h[2];
return h; return h;
} }
else if(prod && kind == 0) { else if(prod && kind == 0) {
@ -72,6 +73,7 @@ hyperpoint portal_data::to_poco(hyperpoint h) const {
hyperpoint portal_data::from_poco(hyperpoint h) const { hyperpoint portal_data::from_poco(hyperpoint h) const {
if(prod && kind == 1) { if(prod && kind == 1) {
ld xd = h[2]; ld xd = h[2];
if(d<0) xd = -xd;
h[2] = 1; h[2] = 1;
auto z = product_decompose(h).first; auto z = product_decompose(h).first;
return h * exp(d+xd-z); return h * exp(d+xd-z);
@ -101,7 +103,9 @@ EX portal_data make_portal(cellwalker cw, int spin) {
id.v0 = C0 * exp(id.d); id.v0 = C0 * exp(id.d);
} }
else if(prod && cw.spin == cw.at->type - 2) { else if(prod && cw.spin == cw.at->type - 2) {
throw hr_exception("cannot construct a portal in this direction"); id.kind = 1;
id.d = product_decompose(fac[0]).first;
id.v0 = C0 * exp(id.d);
} }
else if(prod) { else if(prod) {
id.kind = 0; id.kind = 0;

View File

@ -15,7 +15,7 @@ EX namespace ray {
#if CAP_RAY #if CAP_RAY
/** texture IDs */ /** texture IDs */
GLuint txConnections = 0, txWallcolor = 0, txTextureMap = 0, txVolumetric = 0, txM = 0, txWall = 0; GLuint txConnections = 0, txWallcolor = 0, txTextureMap = 0, txVolumetric = 0, txM = 0, txWall = 0, txPortalConnections = 0;
EX bool in_use; EX bool in_use;
EX bool comparison_mode; EX bool comparison_mode;
@ -169,6 +169,7 @@ struct raycaster : glhr::GLprogram {
GLint tM, uInvLengthM; GLint tM, uInvLengthM;
GLint tWall, uInvLengthWall; GLint tWall, uInvLengthWall;
GLint tPortalConnections;
raycaster(string vsh, string fsh); raycaster(string vsh, string fsh);
}; };
#endif #endif
@ -219,6 +220,8 @@ raycaster::raycaster(string vsh, string fsh) : GLprogram(vsh, fsh) {
tTextureMap = glGetUniformLocation(_program, "tTextureMap"); tTextureMap = glGetUniformLocation(_program, "tTextureMap");
tVolumetric = glGetUniformLocation(_program, "tVolumetric"); tVolumetric = glGetUniformLocation(_program, "tVolumetric");
tPortalConnections = glGetUniformLocation(_program, "tPortalConnections");
tM = glGetUniformLocation(_program, "tM"); tM = glGetUniformLocation(_program, "tM");
uInvLengthM = glGetUniformLocation(_program, "uInvLengthM"); uInvLengthM = glGetUniformLocation(_program, "uInvLengthM");
@ -965,32 +968,36 @@ void raygen::apply_reflect() {
void raygen::emit_intra_portal(int gid1, int gid2) { void raygen::emit_intra_portal(int gid1, int gid2) {
int they_curvature = false;
if(1) { if(1) {
intra::resetter ir; intra::resetter ir;
intra::switch_to(gid2); intra::switch_to(gid2);
they_curvature = hyperbolic ? -1 : sphere ? 1 : 0;
/* product also has 0 */
} }
if(prod && they_curvature) { if(prod) {
string fn = in_h2xe() ? "to_poco_h2xr_h" : "to_poco_s2xr_s"; fmain += "mediump vec4 nposition;\n";
fmain += fmain += "if(pconnection.x != .5) {\n"; // kind != 0
" mediump vec4 nposition = position + tangent * xspeed * 1e-3;\n" if(1) {
" position = "+fn+"(position);\n" string fn = in_h2xe() ? "to_poco_h2xr_h" : "to_poco_s2xr_s";
" position.z = 0.;\n" // zpos - uPLevel;\n" fmain +=
" nposition = "+fn+"(nposition);\n" " nposition = position + tangent * xspeed * 1e-3;\n"
" nposition.z = zspeed * 1e-3;\n"; " position = "+fn+"(position);\n"
} " position.z = 0.;\n" // zpos - uPLevel;\n"
else if(prod) { " nposition = "+fn+"(nposition);\n"
string fn = in_h2xe() ? "to_poco_h2xr_e" : "to_poco_s2xr_e"; " nposition.z = zspeed * 1e-3;\n"
fmain += " if(pconnection.y < .5) { nposition.z = -nposition.z; }\n";
" mediump vec4 nposition = position + tangent * xspeed * 1e-3;\n" }
" mediump mat4 tkt = " + getM("mid+1") + ";\n" fmain += " } else {\n";
" position = "+fn+"(tkt * position);\n" if(1) {
" position.y = zpos;\n" string fn = in_h2xe() ? "to_poco_h2xr_e" : "to_poco_s2xr_e";
" nposition = "+fn+"(tkt * nposition);\n" fmain +=
" nposition.y = zpos + zspeed * 1e-3;\n"; " nposition = position + tangent * xspeed * 1e-3;\n"
" mediump mat4 tkt = " + getM("mid+1") + ";\n"
" position = "+fn+"(tkt * position);\n"
" position.y = zpos;\n"
" nposition = "+fn+"(tkt * nposition);\n"
" nposition.y = zpos + zspeed * 1e-3;\n";
}
fmain += " }\n";
} }
else { else {
fmain += fmain +=
@ -1012,43 +1019,47 @@ void raygen::emit_intra_portal(int gid1, int gid2) {
" position = m * position;\n" " position = m * position;\n"
" nposition = m * nposition;\n"; " nposition = m * nposition;\n";
int we_curvature = hyperbolic ? -1 : sphere ? 1 : 0;
intra::resetter ir; intra::resetter ir;
intra::switch_to(gid2); intra::switch_to(gid2);
if(prod && we_curvature) { if(prod) {
string sgn = in_h2xe() ? "-" : "+"; fmain += "if(pconnection.z != .5) {\n"; // kind != 0
string fn = in_h2xe() ? "from_poco_h2xr_h" : "from_poco_s2xr_s"; if(1) {
ld their_plevel = cgi.plevel / 2; string sgn = in_h2xe() ? "-" : "+";
fmain += string fn = in_h2xe() ? "from_poco_h2xr_h" : "from_poco_s2xr_s";
" zspeed = (nposition.z - position.z) * 1e3;\n"
" zpos = position.z + " + glhr::to_glsl(their_plevel) + ";\n" fmain +=
" position = "+fn+"(position);\n" " if(pconnection.w < .5) { position.z = -position.z; nposition.z = -nposition.z; }\n"
" nposition = "+fn+"(nposition);\n" " zspeed = (nposition.z - position.z) * 1e3;\n"
" tangent = (nposition - position) * 1e3;\n" " zpos = position.z + (pconnection.w - .5) * 16.;\n"
" mediump float pnorm = tangent.z * position.z "+sgn+" tangent.x * position.x "+sgn+" tangent.y * position.y;\n" " position = "+fn+"(position);\n"
" tangent -= position * pnorm;\n" " nposition = "+fn+"(nposition);\n"
" xspeed = sqrt(tangent.x * tangent.x + tangent.y * tangent.y "+sgn+" tangent.z * tangent.z);\n" " tangent = (nposition - position) * 1e3;\n"
" tangent /= xspeed;\n"; " mediump float pnorm = tangent.z * position.z "+sgn+" tangent.x * position.x "+sgn+" tangent.y * position.y;\n"
} " tangent -= position * pnorm;\n"
else if(prod) { " xspeed = sqrt(tangent.x * tangent.x + tangent.y * tangent.y "+sgn+" tangent.z * tangent.z);\n"
string sgn = in_h2xe() ? "-" : "+"; " tangent /= xspeed;\n";
string fn = in_h2xe() ? "from_poco_h2xr_e" : "from_poco_s2xr_e"; }
fmain += fmain += " } else {\n";
" mediump mat4 itkt = " + getM("mid+2") + ";\n"; if(1) {
fmain += string sgn = in_h2xe() ? "-" : "+";
" zpos = position.y;\n" string fn = in_h2xe() ? "from_poco_h2xr_e" : "from_poco_s2xr_e";
" zspeed = (nposition.y - zpos) * 1e3;\n" fmain +=
" position = itkt * "+fn+"(position);\n" " mediump mat4 itkt = " + getM("mid+2") + ";\n";
" nposition = itkt * "+fn+"(nposition);\n" fmain +=
" tangent = (nposition - position) * 1e3;\n" " zpos = position.y;\n"
" mediump float pnorm = tangent.z * position.z "+sgn+" dot(position.xy, tangent.xy);\n" " zspeed = (nposition.y - zpos) * 1e3;\n"
" tangent -= position * pnorm;\n" " position = itkt * "+fn+"(position);\n"
" xspeed = sqrt(dot(tangent.xy, tangent.xy) "+sgn+" tangent.z * tangent.z);\n" " nposition = itkt * "+fn+"(nposition);\n"
" tangent /= xspeed;\n" " tangent = (nposition - position) * 1e3;\n"
" mediump float l = xspeed*xspeed+zspeed*zspeed;\n" " mediump float pnorm = tangent.z * position.z "+sgn+" dot(position.xy, tangent.xy);\n"
" xspeed /= sqrt(l); zspeed /= sqrt(l);\n"; " tangent -= position * pnorm;\n"
" xspeed = sqrt(dot(tangent.xy, tangent.xy) "+sgn+" tangent.z * tangent.z);\n"
" tangent /= xspeed;\n"
" mediump float l = xspeed*xspeed+zspeed*zspeed;\n"
" xspeed /= sqrt(l); zspeed /= sqrt(l);\n";
}
fmain += "}\n";
} }
else { else {
string sgn = hyperbolic ? "-" : "+"; string sgn = hyperbolic ? "-" : "+";
@ -1388,16 +1399,18 @@ void raygen::emit_iterate(int gid1) {
if(intra::in) { if(intra::in) {
int q = isize(intra::data); int q = isize(intra::data);
fmain +=" mediump vec4 pconnection = texture2D(tPortalConnections, u);\n";
fmain += "if(pconnection.x == 0.) {\n";
fmain += no_intra_portal;
fmain += " } else\n";
for(int gid2=0; gid2<q; gid2++) { for(int gid2=0; gid2<q; gid2++) {
if(gid2 == q-1) if(gid2 == q-1)
fmain += " {\n"; fmain += " {\n";
else { else {
fmain += " if(nwalloffset < " + its(intra::data[gid2+1].wallindex) + ") {\n"; fmain += " if(nwalloffset < " + its(intra::data[gid2+1].wallindex) + ") {\n";
} }
if(gid1 == gid2) emit_intra_portal(gid1, gid2);
fmain += no_intra_portal;
else
emit_intra_portal(gid1, gid2);
if(gid2 == q-1) if(gid2 == q-1)
fmain += " }\n"; fmain += " }\n";
else else
@ -1487,6 +1500,9 @@ void raygen::create() {
"uniform mediump vec4 uFogColor;\n" "uniform mediump vec4 uFogColor;\n"
"uniform mediump float uLinearSightRange, uExpStart, uExpDecay;\n"; "uniform mediump float uLinearSightRange, uExpStart, uExpDecay;\n";
if(intra::in) fsh +=
"uniform mediump sampler2D tPortalConnections;\n";
if(wall_via_texture) { if(wall_via_texture) {
fsh += fsh +=
"uniform mediump sampler2D tWall;\n" "uniform mediump sampler2D tWall;\n"
@ -1878,7 +1894,7 @@ struct raycast_map {
int length, per_row, rows, mirror_shift, deg; int length, per_row, rows, mirror_shift, deg;
vector<array<float, 4>> connections, wallcolor, texturemap, volumetric; vector<array<float, 4>> connections, wallcolor, texturemap, volumetric, portal_connections;
void apply_shape() { void apply_shape() {
length = 4096; length = 4096;
@ -1887,6 +1903,7 @@ struct raycast_map {
rows = next_p2((isize(lst)+per_row-1) / per_row); rows = next_p2((isize(lst)+per_row-1) / per_row);
int q = length * rows; int q = length * rows;
connections.resize(q); connections.resize(q);
portal_connections.resize(q);
wallcolor.resize(q); wallcolor.resize(q);
texturemap.resize(q); texturemap.resize(q);
volumetric.resize(q); volumetric.resize(q);
@ -2022,6 +2039,7 @@ struct raycast_map {
auto code = enc(ids[c1], 0); auto code = enc(ids[c1], 0);
connections[u][0] = code[0]; connections[u][0] = code[0];
connections[u][1] = code[1]; connections[u][1] = code[1];
portal_connections[u][0] = 0;
if(isWall3(c1)) { if(isWall3(c1)) {
celldrawer dd; celldrawer dd;
dd.c = c1; dd.c = c1;
@ -2066,6 +2084,10 @@ struct raycast_map {
ms.push_back(p->id1.T); ms.push_back(p->id1.T);
ms.push_back(p->id2.iT); ms.push_back(p->id2.iT);
connections[u][2] = (k+.5) / 1024.; connections[u][2] = (k+.5) / 1024.;
portal_connections[u][0] = p->id1.kind / 16. + .5;
portal_connections[u][1] = p->id1.d / 16 + .5;
portal_connections[u][2] = p->id2.kind / 16. + .5;
portal_connections[u][3] = p->id2.d / 16 + .5;
} }
else { else {
transmatrix T = currentmap->iadj(c, i) * inverse(ms[wo + i]); transmatrix T = currentmap->iadj(c, i) * inverse(ms[wo + i]);
@ -2143,6 +2165,7 @@ struct raycast_map {
bind_array(connections, o->tConnections, txConnections, 3, length); bind_array(connections, o->tConnections, txConnections, 3, length);
bind_array(texturemap, o->tTextureMap, txTextureMap, 5, length); bind_array(texturemap, o->tTextureMap, txTextureMap, 5, length);
if(volumetric::on) bind_array(volumetric, o->tVolumetric, txVolumetric, 6, length); if(volumetric::on) bind_array(volumetric, o->tVolumetric, txVolumetric, 6, length);
bind_array(portal_connections, o->tPortalConnections, txPortalConnections, 1, length);
if(o->uMirrorShift != -1) { if(o->uMirrorShift != -1) {
glUniform1i(o->uMirrorShift, mirror_shift); glUniform1i(o->uMirrorShift, mirror_shift);