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:
parent
b3fc40a8fc
commit
8b6a745a8f
@ -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;
|
||||||
|
145
raycaster.cpp
145
raycaster.cpp
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user