mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
raycasting in 2D
This commit is contained in:
parent
fad1c650c7
commit
2a0b0101fd
@ -662,6 +662,8 @@ int celldrawer::getSnakelevColor(int i, int last) {
|
||||
|
||||
void celldrawer::draw_wall() {
|
||||
|
||||
if(no_wall_rendering) return;
|
||||
|
||||
if(GDIM == 3 && WDIM == 2) {
|
||||
if(!qfi.fshape) qfi.fshape = &cgi.shFullFloor;
|
||||
if(conegraph(c)) {
|
||||
|
6
fake.cpp
6
fake.cpp
@ -26,9 +26,9 @@ EX namespace fake {
|
||||
|
||||
EX bool available() {
|
||||
if(in()) return true;
|
||||
if(GDIM == 2 && standard_tiling() && (PURE || BITRUNCATED)) return true;
|
||||
if(WDIM == 2 && standard_tiling() && (PURE || BITRUNCATED)) return true;
|
||||
if(arcm::in() && PURE) return true;
|
||||
if(GDIM == 2) return false;
|
||||
if(WDIM == 2) return false;
|
||||
if(among(geometry, gRhombic3, gBitrunc3)) return false;
|
||||
return euc::in() || reg3::in();
|
||||
}
|
||||
@ -366,6 +366,7 @@ EX void compute_scale() {
|
||||
ginf[gFake].g = WDIM == 3 ? giSphere3 : giSphere2;
|
||||
}
|
||||
|
||||
geom3::apply_always3();
|
||||
ld around_ideal = 1/(1/2. - 1./get_middle());
|
||||
|
||||
if(arcm::in()) {
|
||||
@ -461,6 +462,7 @@ EX void change_around() {
|
||||
fixmatrix(View);
|
||||
sightranges[gFake] = range * t;
|
||||
texture::config.remap();
|
||||
geom3::apply_always3();
|
||||
}
|
||||
|
||||
EX void configure() {
|
||||
|
@ -914,6 +914,7 @@ EX int shvid(cell *c) {
|
||||
}
|
||||
|
||||
EX struct dqi_poly *draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio IS(PPR::DEFAULT)) {
|
||||
if(no_wall_rendering) return NULL;
|
||||
if(!c) return &queuepolyat(V, shv[0], col, prio);
|
||||
else if(WDIM == 3) return NULL;
|
||||
#if CAP_GP
|
||||
@ -950,10 +951,12 @@ EX struct dqi_poly *draw_shapevec(cell *c, const transmatrix& V, const vector<hp
|
||||
}
|
||||
|
||||
EX void draw_floorshape(cell *c, const transmatrix& V, const floorshape &fsh, color_t col, PPR prio IS(PPR::DEFAULT)) {
|
||||
if(no_wall_rendering) return;
|
||||
draw_shapevec(c, V, fsh.b, col, prio);
|
||||
}
|
||||
|
||||
EX void draw_qfi(cell *c, const transmatrix& V, color_t col, PPR prio IS(PPR::DEFAULT), vector<hpcshape> floorshape::* tab IS(&floorshape::b)) {
|
||||
if(no_wall_rendering) return;
|
||||
if(qfi.shape)
|
||||
queuepolyat(V * qfi.spin, *qfi.shape, col, prio);
|
||||
else if(qfi.usershape >= 0) {
|
||||
|
@ -616,12 +616,11 @@ void geometry_information::prepare_basics() {
|
||||
if(fake::in() && WDIM == 2) {
|
||||
auto& u = *fake::underlying_cgip;
|
||||
geometry = fake::underlying;
|
||||
ld orig = xpush0(u.hcrossf)[0] / xpush0(u.hcrossf)[WDIM];
|
||||
ld orig = xpush0(u.hcrossf)[0] / xpush0(u.hcrossf)[GDIM];
|
||||
geometry = gFake;
|
||||
ld our = xpush0(hcrossf)[0] / xpush0(hcrossf)[WDIM];
|
||||
ld our = xpush0(hcrossf)[0] / xpush0(hcrossf)[GDIM];
|
||||
fake::scale = our / orig;
|
||||
// if(debugflags & DF_GEOM)
|
||||
println(hlog, "scale set to ", fake::scale);
|
||||
}
|
||||
|
||||
if(fake::in() && WDIM == 3) {
|
||||
|
@ -3769,7 +3769,7 @@ EX void gridline(const transmatrix& V, const hyperpoint h1, const hyperpoint h2,
|
||||
}
|
||||
|
||||
EX int wall_offset(cell *c) {
|
||||
if(hybri) return hybrid::wall_offset(c);
|
||||
if(hybri || WDIM == 2) return hybrid::wall_offset(c);
|
||||
if(kite::in() && kite::getshape(c->master) == kite::pKite) return 10;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1068,6 +1068,9 @@ EX namespace hybrid {
|
||||
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(WDIM == 2) {
|
||||
return to_other_side(get_corner_position(c, i), get_corner_position(c, (i+1)));
|
||||
}
|
||||
if(prod) {
|
||||
transmatrix T;
|
||||
cell *cw = hybrid::get_where(c).first;
|
||||
@ -1253,6 +1256,11 @@ EX namespace hybrid {
|
||||
|
||||
EX hyperpoint get_corner(cell *c, int i, int next, ld z) {
|
||||
ld lev = cgi.plevel * z / 2;
|
||||
if(WDIM == 2) {
|
||||
ld zz = lerp(cgi.FLOOR, cgi.WALL, (1+z) / 2);
|
||||
hyperpoint h = zshift(get_corner_position(c, i+next), zz);
|
||||
return h;
|
||||
}
|
||||
if(prod) {
|
||||
dynamicval<eGeometry> g(geometry, hybrid::underlying);
|
||||
dynamicval<geometry_information*> gc(cgip, hybrid::underlying_cgip);
|
||||
@ -1276,24 +1284,25 @@ EX namespace hybrid {
|
||||
EX int wall_offset(cell *c) {
|
||||
if(GOLDBERG) {
|
||||
/* a bit slow... */
|
||||
cell *c1 = get_where(c).first;
|
||||
gp::draw_li = PIU(gp::get_local_info(c1));
|
||||
cell *c1 = WDIM == 2 ? c : get_where(c).first;
|
||||
gp::draw_li = WDIM == 2 ? gp::get_local_info(c1) : PIU(gp::get_local_info(c1));
|
||||
}
|
||||
int id = hybrid::underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c);
|
||||
auto ugeometry = hybri ? hybrid::underlying : geometry;
|
||||
int id = ugeometry == 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, nullptr});
|
||||
auto &wop = cgi.walloffsets[id];
|
||||
int &wo = wop.first;
|
||||
if(!wop.second) wop.second = c;
|
||||
if(wo == -1) {
|
||||
cell *c1 = hybrid::get_where(c).first;
|
||||
cell *c1 = hybri ? hybrid::get_where(c).first : c;
|
||||
wo = isize(cgi.shWall3D);
|
||||
int won = wo + c->type;
|
||||
int won = wo + c->type + (WDIM == 2 ? 2 : 0);
|
||||
if(!cgi.wallstart.empty()) cgi.wallstart.pop_back();
|
||||
cgi.reserve_wall3d(won);
|
||||
|
||||
if(prod) for(int i=0; i<c1->type; i++) {
|
||||
if(prod || WDIM == 2) for(int i=0; i<c1->type; i++) {
|
||||
hyperpoint w;
|
||||
((hrmap_hybrid*)currentmap)->in_underlying([&] {
|
||||
auto f = [&] {
|
||||
/* mirror image of C0 in the axis h1-h2 */
|
||||
hyperpoint h1 = get_corner_position(c1, i);
|
||||
hyperpoint h2 = get_corner_position(c1, i+1);
|
||||
@ -1302,7 +1311,11 @@ EX namespace hybrid {
|
||||
w = T * C0;
|
||||
w[1] = -w[1];
|
||||
w = inverse(T) * w;
|
||||
});
|
||||
};
|
||||
if(prod)
|
||||
((hrmap_hybrid*)currentmap)->in_underlying(f);
|
||||
else
|
||||
f();
|
||||
cgi.walltester[wo + i] = w;
|
||||
}
|
||||
|
||||
@ -1314,7 +1327,7 @@ EX namespace hybrid {
|
||||
int z = a ? 1 : -1;
|
||||
hyperpoint ctr = zpush0(z * cgi.plevel/2);
|
||||
for(int i=0; i<c1->type; i++)
|
||||
if(prod)
|
||||
if(prod || WDIM == 2)
|
||||
l.push_back(hybrid::get_corner(c1, i, 0, z));
|
||||
else {
|
||||
l.push_back(ctr);
|
||||
@ -1341,7 +1354,7 @@ EX namespace hybrid {
|
||||
});
|
||||
|
||||
EX vector<pair<int, cell*>> gen_sample_list() {
|
||||
if(!hybri) return {make_pair(0, centerover), make_pair(centerover->type, nullptr)};
|
||||
if(!hybri && WDIM != 2) return {make_pair(0, centerover), make_pair(centerover->type, nullptr)};
|
||||
vector<pair<int, cell*>> result;
|
||||
for(auto& v: cgi.walloffsets) if(v.first >= 0) result.push_back(v);
|
||||
sort(result.begin(), result.end());
|
||||
|
@ -65,7 +65,8 @@ eGeometry last_geometry;
|
||||
EX bool available() {
|
||||
if(noGUI) return false;
|
||||
if(!vid.usingGL) return false;
|
||||
if(WDIM == 2) return false;
|
||||
if(GDIM == 2) return false;
|
||||
if(WDIM == 2 && (kite::in() || bt::in())) return false;
|
||||
if(hyperbolic && pmodel == mdPerspective && !kite::in())
|
||||
return true;
|
||||
if(sphere && pmodel == mdPerspective && !rotspace)
|
||||
@ -154,7 +155,7 @@ shared_ptr<raycaster> our_raycaster;
|
||||
|
||||
EX void reset_raycaster() { our_raycaster = nullptr; }
|
||||
|
||||
int deg;
|
||||
int deg, irays;
|
||||
|
||||
#ifdef GLES_ONLY
|
||||
void add(string& tgt, string type, string name, int min_index, int max_index) {
|
||||
@ -190,6 +191,8 @@ void enable_raycaster() {
|
||||
reset_raycaster();
|
||||
}
|
||||
|
||||
wall_offset(centerover); /* so raywall is not empty and deg is not zero */
|
||||
|
||||
deg = 0;
|
||||
|
||||
auto samples = hybrid::gen_sample_list();
|
||||
@ -217,7 +220,7 @@ void enable_raycaster() {
|
||||
#endif
|
||||
" }\n";
|
||||
|
||||
int irays = isize(cgi.raywall);
|
||||
irays = isize(cgi.raywall);
|
||||
string rays = its(irays);
|
||||
|
||||
string fsh =
|
||||
@ -299,7 +302,7 @@ void enable_raycaster() {
|
||||
}
|
||||
else {
|
||||
fsh += "const int walloffset = 0;\n"
|
||||
"const int sides = " + its(centerover->type) + ";\n";
|
||||
"const int sides = " + its(centerover->type+(WDIM == 2 ? 2 : 0)) + ";\n";
|
||||
}
|
||||
|
||||
|
||||
@ -417,47 +420,49 @@ void enable_raycaster() {
|
||||
fmain +=
|
||||
" if(which == -1) {\n";
|
||||
|
||||
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : its(flat2))+"; i++) {\n";
|
||||
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : WDIM == 2 ? "sides" : its(flat2))+"; i++) {\n";
|
||||
|
||||
fmain += "int woi = walloffset+i;\n";
|
||||
|
||||
if(in_h2xe()) fmain +=
|
||||
" mediump float v = ((position - uM[walloffset+i] * position)[2] / (uM[walloffset+i] * tangent - tangent)[2]);\n"
|
||||
" mediump float v = ((position - uM[woi] * position)[2] / (uM[woi] * tangent - tangent)[2]);\n"
|
||||
" if(v > 1. || v < -1.) continue;\n"
|
||||
" mediump float d = atanh(v);\n"
|
||||
" mediump vec4 next_tangent = position * sinh(d) + tangent * cosh(d);\n"
|
||||
" if(next_tangent[2] < (uM[walloffset+i] * next_tangent)[2]) continue;\n"
|
||||
" if(next_tangent[2] < (uM[woi] * next_tangent)[2]) continue;\n"
|
||||
" d /= xspeed;\n";
|
||||
else if(in_s2xe()) fmain +=
|
||||
" mediump float v = ((position - uM[walloffset+i] * position)[2] / (uM[walloffset+i] * tangent - tangent)[2]);\n"
|
||||
" mediump float v = ((position - uM[woi] * position)[2] / (uM[woi] * tangent - tangent)[2]);\n"
|
||||
" mediump float d = atan(v);\n"
|
||||
" mediump vec4 next_tangent = tangent * cos(d) - position * sin(d);\n"
|
||||
" if(next_tangent[2] > (uM[walloffset+i] * next_tangent)[2]) continue;\n"
|
||||
" if(next_tangent[2] > (uM[woi] * next_tangent)[2]) continue;\n"
|
||||
" d /= xspeed;\n";
|
||||
else if(in_e2xe()) fmain +=
|
||||
" mediump float deno = dot(position, tangent) - dot(uM[walloffset+i]*position, uM[walloffset+i]*tangent);\n"
|
||||
" mediump float deno = dot(position, tangent) - dot(uM[woi]*position, uM[woi]*tangent);\n"
|
||||
" if(deno < 1e-6 && deno > -1e-6) continue;\n"
|
||||
" mediump float d = (dot(uM[walloffset+i]*position, uM[walloffset+i]*position) - dot(position, position)) / 2. / deno;\n"
|
||||
" mediump float d = (dot(uM[woi]*position, uM[woi]*position) - dot(position, position)) / 2. / deno;\n"
|
||||
" if(d < 0.) continue;\n"
|
||||
" mediump vec4 next_position = position + d * tangent;\n"
|
||||
" if(dot(next_position, tangent) < dot(uM[walloffset+i]*next_position, uM[walloffset+i]*tangent)) continue;\n"
|
||||
" if(dot(next_position, tangent) < dot(uM[woi]*next_position, uM[woi]*tangent)) continue;\n"
|
||||
" d /= xspeed;\n";
|
||||
else if(hyperbolic) fmain +=
|
||||
" mediump float v = ((position - uM[i] * position)[3] / (uM[i] * tangent - tangent)[3]);\n"
|
||||
" mediump float v = ((position - uM[woi] * position)[3] / (uM[woi] * tangent - tangent)[3]);\n"
|
||||
" if(v > 1. || v < -1.) continue;\n"
|
||||
" mediump float d = atanh(v);\n"
|
||||
" mediump vec4 next_tangent = position * sinh(d) + tangent * cosh(d);\n"
|
||||
" if(next_tangent[3] < (uM[i] * next_tangent)[3]) continue;\n";
|
||||
" if(next_tangent[3] < (uM[woi] * next_tangent)[3]) continue;\n";
|
||||
else if(sphere) fmain +=
|
||||
" mediump float v = ((position - uM[i] * position)[3] / (uM[i] * tangent - tangent)[3]);\n"
|
||||
" mediump float v = ((position - uM[woi] * position)[3] / (uM[woi] * tangent - tangent)[3]);\n"
|
||||
" mediump float d = atan(v);\n"
|
||||
" mediump vec4 next_tangent = -position * sin(d) + tangent * cos(d);\n"
|
||||
" if(next_tangent[3] > (uM[i] * next_tangent)[3]) continue;\n";
|
||||
" if(next_tangent[3] > (uM[woi] * next_tangent)[3]) continue;\n";
|
||||
else fmain +=
|
||||
" mediump float deno = dot(position, tangent) - dot(uM[i]*position, uM[i]*tangent);\n"
|
||||
" mediump float deno = dot(position, tangent) - dot(uM[woi]*position, uM[woi]*tangent);\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[woi]*position, uM[woi]*position) - dot(position, position)) / 2. / deno;\n"
|
||||
" if(d < 0.) continue;\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[woi]*next_position, uM[woi]*tangent)) continue;\n";
|
||||
|
||||
fmain +=
|
||||
" if(d < dist) { dist = d; which = i; }\n"
|
||||
@ -1140,7 +1145,7 @@ EX void cast() {
|
||||
|
||||
if(o->uWallOffset != -1) {
|
||||
glUniform1i(o->uWallOffset, wall_offset(centerover));
|
||||
glUniform1i(o->uSides, centerover->type);
|
||||
glUniform1i(o->uSides, centerover->type + (WDIM == 2 ? 2 : 0));
|
||||
}
|
||||
|
||||
auto sa = hybrid::gen_sample_list();
|
||||
@ -1153,6 +1158,18 @@ EX void cast() {
|
||||
if(!c) continue;
|
||||
for(int j=0; j<c->type; j++)
|
||||
ms[id+j] = hybrid::ray_iadj(c, j);
|
||||
if(WDIM == 2) for(int a: {0, 1}) {
|
||||
int z = a ? 1 : -1;
|
||||
hyperpoint h = Hypc;
|
||||
for(int a=0; a<c->type; a++) {
|
||||
hyperpoint corner = hybrid::get_corner(c, a, 0, z);
|
||||
h += corner;
|
||||
}
|
||||
h = normalize(h);
|
||||
ld d = hdist0(h);
|
||||
if(h[2] > 0) d = -d;
|
||||
ms[id+c->type+a] = zpush(2*d);
|
||||
}
|
||||
}
|
||||
|
||||
// println(hlog, ms);
|
||||
@ -1219,17 +1236,35 @@ EX void cast() {
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix T = currentmap->iadj(c, i) * inverse(ms[wall_offset(c) + i]);
|
||||
int wo = wall_offset(c);
|
||||
if(wo >= irays) {
|
||||
println(hlog, "wo=", wo, " irays = ", irays);
|
||||
return;
|
||||
}
|
||||
transmatrix T = currentmap->iadj(c, i) * inverse(ms[wo + i]);
|
||||
for(int k=0; k<=isize(ms); k++) {
|
||||
if(k < isize(ms) && !eqmatrix(ms[k], T)) continue;
|
||||
if(k == isize(ms)) ms.push_back(T);
|
||||
connections[u][2] = (k+.5) / 1024.;
|
||||
break;
|
||||
}
|
||||
connections[u][3] = (wall_offset(c1) / 256.) + (c1->type + .5) / 4096.;
|
||||
connections[u][3] = (wall_offset(c1) / 256.) + (c1->type + (WDIM == 2 ? 2 : 0) + .5) / 4096.;
|
||||
}
|
||||
if(WDIM == 2) for(int a: {0, 1}) {
|
||||
celldrawer dd;
|
||||
dd.c = c;
|
||||
dd.setcolors();
|
||||
transmatrix Vf;
|
||||
dd.set_land_floor(Vf);
|
||||
int u = (id/per_row*length) + (id%per_row * deg) + c->type + a;
|
||||
wallcolor[u] = glhr::acolor(darkena(dd.fcol, 0, 0xFF));
|
||||
if(qfi.fshape)
|
||||
texturemap[u] = floor_texture_map[qfi.fshape->id];
|
||||
else
|
||||
texturemap[u] = glhr::makevertex(0.1,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(prod) {
|
||||
for(auto p: sa) {
|
||||
int id =p.first;
|
||||
|
Loading…
Reference in New Issue
Block a user