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,33 +968,37 @@ 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) {
fmain += "mediump vec4 nposition;\n";
fmain += "if(pconnection.x != .5) {\n"; // kind != 0
if(1) {
string fn = in_h2xe() ? "to_poco_h2xr_h" : "to_poco_s2xr_s"; string fn = in_h2xe() ? "to_poco_h2xr_h" : "to_poco_s2xr_s";
fmain += fmain +=
" mediump vec4 nposition = position + tangent * xspeed * 1e-3;\n" " nposition = position + tangent * xspeed * 1e-3;\n"
" position = "+fn+"(position);\n" " position = "+fn+"(position);\n"
" position.z = 0.;\n" // zpos - uPLevel;\n" " position.z = 0.;\n" // zpos - uPLevel;\n"
" nposition = "+fn+"(nposition);\n" " nposition = "+fn+"(nposition);\n"
" nposition.z = zspeed * 1e-3;\n"; " nposition.z = zspeed * 1e-3;\n"
" if(pconnection.y < .5) { nposition.z = -nposition.z; }\n";
} }
else if(prod) { fmain += " } else {\n";
if(1) {
string fn = in_h2xe() ? "to_poco_h2xr_e" : "to_poco_s2xr_e"; string fn = in_h2xe() ? "to_poco_h2xr_e" : "to_poco_s2xr_e";
fmain += fmain +=
" mediump vec4 nposition = position + tangent * xspeed * 1e-3;\n" " nposition = position + tangent * xspeed * 1e-3;\n"
" mediump mat4 tkt = " + getM("mid+1") + ";\n" " mediump mat4 tkt = " + getM("mid+1") + ";\n"
" position = "+fn+"(tkt * position);\n" " position = "+fn+"(tkt * position);\n"
" position.y = zpos;\n" " position.y = zpos;\n"
" nposition = "+fn+"(tkt * nposition);\n" " nposition = "+fn+"(tkt * nposition);\n"
" nposition.y = zpos + zspeed * 1e-3;\n"; " nposition.y = zpos + zspeed * 1e-3;\n";
} }
fmain += " }\n";
}
else { else {
fmain += fmain +=
" mediump vec4 nposition = position + tangent * 1e-3;\n" " mediump vec4 nposition = position + tangent * 1e-3;\n"
@ -1012,18 +1019,19 @@ 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) {
fmain += "if(pconnection.z != .5) {\n"; // kind != 0
if(1) {
string sgn = in_h2xe() ? "-" : "+"; string sgn = in_h2xe() ? "-" : "+";
string fn = in_h2xe() ? "from_poco_h2xr_h" : "from_poco_s2xr_s"; string fn = in_h2xe() ? "from_poco_h2xr_h" : "from_poco_s2xr_s";
ld their_plevel = cgi.plevel / 2;
fmain += fmain +=
" if(pconnection.w < .5) { position.z = -position.z; nposition.z = -nposition.z; }\n"
" zspeed = (nposition.z - position.z) * 1e3;\n" " zspeed = (nposition.z - position.z) * 1e3;\n"
" zpos = position.z + " + glhr::to_glsl(their_plevel) + ";\n" " zpos = position.z + (pconnection.w - .5) * 16.;\n"
" position = "+fn+"(position);\n" " position = "+fn+"(position);\n"
" nposition = "+fn+"(nposition);\n" " nposition = "+fn+"(nposition);\n"
" tangent = (nposition - position) * 1e3;\n" " tangent = (nposition - position) * 1e3;\n"
@ -1032,7 +1040,8 @@ void raygen::emit_intra_portal(int gid1, int gid2) {
" xspeed = sqrt(tangent.x * tangent.x + tangent.y * tangent.y "+sgn+" tangent.z * tangent.z);\n" " xspeed = sqrt(tangent.x * tangent.x + tangent.y * tangent.y "+sgn+" tangent.z * tangent.z);\n"
" tangent /= xspeed;\n"; " tangent /= xspeed;\n";
} }
else if(prod) { fmain += " } else {\n";
if(1) {
string sgn = in_h2xe() ? "-" : "+"; string sgn = in_h2xe() ? "-" : "+";
string fn = in_h2xe() ? "from_poco_h2xr_e" : "from_poco_s2xr_e"; string fn = in_h2xe() ? "from_poco_h2xr_e" : "from_poco_s2xr_e";
fmain += fmain +=
@ -1050,6 +1059,8 @@ void raygen::emit_intra_portal(int gid1, int gid2) {
" mediump float l = xspeed*xspeed+zspeed*zspeed;\n" " mediump float l = xspeed*xspeed+zspeed*zspeed;\n"
" xspeed /= sqrt(l); zspeed /= sqrt(l);\n"; " xspeed /= sqrt(l); zspeed /= sqrt(l);\n";
} }
fmain += "}\n";
}
else { else {
string sgn = hyperbolic ? "-" : "+"; string sgn = hyperbolic ? "-" : "+";
string he = hyperbolic ? "from_poco_h3" : "from_poco_s3"; string he = hyperbolic ? "from_poco_h3" : "from_poco_s3";
@ -1388,15 +1399,17 @@ 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)
fmain += no_intra_portal;
else
emit_intra_portal(gid1, gid2); emit_intra_portal(gid1, gid2);
if(gid2 == q-1) if(gid2 == q-1)
fmain += " }\n"; fmain += " }\n";
@ -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);