mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 01:00:25 +00:00
intra:: first version
This commit is contained in:
parent
30f964e6e3
commit
663e334e38
2
Makefile
2
Makefile
@ -156,7 +156,7 @@ makeh$(EXE_EXTENSION): makeh.cpp
|
||||
$(CXX) -O2 makeh.cpp -o $@
|
||||
|
||||
autohdr.h: makeh$(EXE_EXTENSION) language-data.cpp *.cpp
|
||||
./makeh classes.cpp locations.cpp colors.cpp hyperpoint.cpp geometry.cpp goldberg.cpp init.cpp floorshapes.cpp cell.cpp multi.cpp shmup.cpp pattern2.cpp mapeditor.cpp graph.cpp textures.cpp hprint.cpp language.cpp util.cpp complex.cpp *.cpp > autohdr.h
|
||||
./makeh classes.cpp locations.cpp colors.cpp hyperpoint.cpp geometry.cpp goldberg.cpp init.cpp floorshapes.cpp cell.cpp multi.cpp shmup.cpp pattern2.cpp mapeditor.cpp graph.cpp textures.cpp hprint.cpp language.cpp util.cpp complex.cpp multigame.cpp *.cpp > autohdr.h
|
||||
|
||||
language-data.cpp: langen$(EXE_EXTENSION)
|
||||
./langen > language-data.cpp
|
||||
|
2
cell.cpp
2
cell.cpp
@ -1450,7 +1450,7 @@ EX int valence() {
|
||||
/** portalspaces are not defined outside of a boundary */
|
||||
EX bool is_boundary(cell *c) {
|
||||
if(c == &out_of_bounds) return true;
|
||||
return (cgflags & qPORTALSPACE) && isWall(c->wall);
|
||||
return ((cgflags & qPORTALSPACE) || intra::in) && isWall(c->wall);
|
||||
}
|
||||
|
||||
/** compute the distlimit for a tessellation automatically */
|
||||
|
@ -1196,7 +1196,7 @@ EX void check_cgi() {
|
||||
if(fake::in()) fake::underlying_cgip->timestamp = ntimestamp;
|
||||
if(arcm::alt_cgip) arcm::alt_cgip->timestamp = ntimestamp;
|
||||
|
||||
if(isize(cgis) > 4) {
|
||||
if(isize(cgis) > 4 && !intra::in) {
|
||||
vector<pair<int, string>> timestamps;
|
||||
for(auto& t: cgis) timestamps.emplace_back(-t.second.timestamp, t.first);
|
||||
sort(timestamps.begin(), timestamps.end());
|
||||
|
@ -4014,6 +4014,11 @@ EX subcellshape& generate_subcellshape_if_needed(cell *c, int id) {
|
||||
ss.walltester.push_back(w);
|
||||
}
|
||||
|
||||
if(hybri || WDIM == 2) {
|
||||
ss.walltester.push_back(C0);
|
||||
ss.walltester.push_back(C0);
|
||||
}
|
||||
|
||||
for(int i=0; i<c1->type; i++)
|
||||
ss.faces.push_back({hybrid::get_corner(c1, i, 0, -1), hybrid::get_corner(c1, i, 0, +1), hybrid::get_corner(c1, i, 1, +1), hybrid::get_corner(c1, i, 1, -1)});
|
||||
|
||||
|
@ -123,6 +123,7 @@
|
||||
#include "inforder.cpp"
|
||||
#include "dpgen.cpp"
|
||||
#include "vr.cpp"
|
||||
#include "intra.cpp"
|
||||
|
||||
#if CAP_ROGUEVIZ
|
||||
#include "rogueviz/rogueviz-all.cpp"
|
||||
|
11
hypgraph.cpp
11
hypgraph.cpp
@ -2902,6 +2902,17 @@ EX transmatrix get_shift_view_of(const hyperpoint H, const transmatrix V) {
|
||||
/** shift the view according to the given tangent vector */
|
||||
EX void shift_view(hyperpoint H) {
|
||||
if(callhandlers(false, hooks_shift_view, H)) return;
|
||||
static bool recursive = false;
|
||||
if(!recursive && intra::in) {
|
||||
H /= 10;
|
||||
recursive = true;
|
||||
for(int i=0; i<10; i++) {
|
||||
shift_view(H);
|
||||
intra::check_portal_movement();
|
||||
}
|
||||
recursive = false;
|
||||
return;
|
||||
}
|
||||
auto oView = View;
|
||||
View = get_shift_view_of(H, View);
|
||||
auto& wc = current_display->which_copy;
|
||||
|
297
intra.cpp
Normal file
297
intra.cpp
Normal file
@ -0,0 +1,297 @@
|
||||
#include "hyper.h"
|
||||
|
||||
namespace hr {
|
||||
|
||||
EX namespace intra {
|
||||
|
||||
EX bool in;
|
||||
|
||||
#if HDR
|
||||
/** information per every space connected with intra-portals */
|
||||
struct intra_data {
|
||||
gamedata gd;
|
||||
geometryinfo gi;
|
||||
int wallindex;
|
||||
};
|
||||
#endif
|
||||
|
||||
EX vector<intra_data> data;
|
||||
|
||||
/** index of the space we are currently in */
|
||||
EX int intra_current;
|
||||
|
||||
/** map cells to their intra spaces */
|
||||
EX map<cell*, int> intra_id;
|
||||
|
||||
#if HDR
|
||||
/** information about portal (one side) */
|
||||
struct portal_data {
|
||||
int kind;
|
||||
hyperpoint v0;
|
||||
ld d;
|
||||
transmatrix T;
|
||||
transmatrix iT;
|
||||
hyperpoint co0;
|
||||
hyperpoint co1;
|
||||
ld scale;
|
||||
/* convert h to portal coordinates ('poco') to usual coordinates */
|
||||
hyperpoint to_poco(hyperpoint h) const;
|
||||
/* convert h from portal coordinates ('poco') to usual coordinates */
|
||||
hyperpoint from_poco(hyperpoint h) const;
|
||||
};
|
||||
#endif
|
||||
|
||||
hyperpoint portal_data::to_poco(hyperpoint h) const {
|
||||
if(prod && kind == 1) {
|
||||
auto dec = product_decompose(h);
|
||||
h = dec.second;
|
||||
h[0] /= h[2];
|
||||
h[1] /= h[2];
|
||||
h[2] = dec.first - d;
|
||||
h[3] = 1;
|
||||
return h;
|
||||
}
|
||||
else if(prod && kind == 0) {
|
||||
h = T * h;
|
||||
ld z = product_decompose(h).first;
|
||||
h /= exp(z);
|
||||
auto h1 = h;
|
||||
h[0] = asin_auto(h1[1]);
|
||||
h[1] = z;
|
||||
h[2] = asin_auto_clamp(h1[0] / cos_auto(h[0]));
|
||||
h[3] = 1;
|
||||
return h;
|
||||
}
|
||||
else {
|
||||
h = T * h;
|
||||
h /= h[3];
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
hyperpoint portal_data::from_poco(hyperpoint h) const {
|
||||
if(prod && kind == 1) {
|
||||
ld d = h[2];
|
||||
h[2] = 1;
|
||||
auto z = product_decompose(h).first;
|
||||
return h * exp(d+d-z);
|
||||
}
|
||||
else if(prod && kind == 0) {
|
||||
auto h0 = h;
|
||||
h[0] = sin_auto(h0[2]) * cos_auto(h0[0]);
|
||||
h[1] = sin_auto(h0[0]);
|
||||
h[2] = cos_auto(h0[0]) * cos_auto(h0[2]);
|
||||
h[3] = 1;
|
||||
return iT * h * exp(h0[1]);
|
||||
}
|
||||
else {
|
||||
h[3] = 1;
|
||||
return normalize(iT * h);
|
||||
}
|
||||
}
|
||||
|
||||
EX portal_data make_portal(cellwalker cw) {
|
||||
auto& ss = currentmap->get_cellshape(cw.at);
|
||||
auto& fac = ss.faces[cw.spin];
|
||||
portal_data id;
|
||||
id.scale = 1;
|
||||
if(prod && cw.spin == cw.at->type - 1) {
|
||||
id.kind = 1;
|
||||
id.d = product_decompose(fac[0]).first;
|
||||
id.v0 = C0 * exp(id.d);
|
||||
}
|
||||
else if(prod && cw.spin == cw.at->type - 2) {
|
||||
throw hr_exception("cannot construct a portal in this direction");
|
||||
}
|
||||
else if(prod) {
|
||||
id.kind = 0;
|
||||
id.v0 = Hypc;
|
||||
id.scale = cgi.plevel;
|
||||
for(auto p: fac) id.v0 += p;
|
||||
id.v0 /= sqrt(abs(intval(id.v0, Hypc)));
|
||||
id.T = cpush(0, -hdist0(id.v0)) * spintox(id.v0);
|
||||
for(int i=0; i<3; i++) id.T[3][i] = id.T[i][3] = i==3;
|
||||
if(debugflags & DF_GEOM)
|
||||
for(int a=0; a<4; a++) {
|
||||
hyperpoint h = fac[a];
|
||||
println(hlog, kz(h), " -> ", kz(spintox(id.v0)*h), " -> ", kz(cpush(0, -hdist0(id.v0))) * kz(spintox(id.v0) * h), " -> ", kz(id.to_poco(h)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
id.kind = 0;
|
||||
id.v0 = Hypc;
|
||||
for(auto p: fac) id.v0 += p;
|
||||
id.v0 = normalize(id.v0);
|
||||
id.T = cpush(2, -hdist0(id.v0)) * cspin(2, 0, 90*degree) * spintox(id.v0);
|
||||
}
|
||||
id.iT = inverse(id.T);
|
||||
if(MDIM == 3) for(int i=0; i<4; i++) id.iT[3][i] = id.iT[i][3] = i==3;
|
||||
id.co0 = id.to_poco(fac[(in_s2xe() || sphere) ? 2 : 0]);
|
||||
id.co1 = id.to_poco(fac[1]);
|
||||
return id;
|
||||
}
|
||||
|
||||
#if HDR
|
||||
/** information about connection (portal-to-portal) */
|
||||
struct connection_data {
|
||||
int source_world;
|
||||
int target_world;
|
||||
cellwalker scw, tcw;
|
||||
portal_data id1;
|
||||
portal_data id2;
|
||||
transmatrix T;
|
||||
};
|
||||
#endif
|
||||
|
||||
EX map<cellwalker, connection_data> connections;
|
||||
|
||||
EX connection_data* find_connection(int a, int b) {
|
||||
for(auto& p: connections)
|
||||
if(intra_id[p.first.at] == a && p.second.target_world == b)
|
||||
return &p.second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EX void switch_to(int id) {
|
||||
if(intra_current == id) return;
|
||||
data[intra_current].gd.storegame();
|
||||
intra_current = id;
|
||||
ginf[gProduct] = data[intra_current].gi;
|
||||
data[intra_current].gd.restoregame();
|
||||
}
|
||||
|
||||
void connect_portal_1(cellwalker cw1, cellwalker cw2) {
|
||||
auto& p = connections[cw1];
|
||||
p.source_world = intra_id[cw1.at];
|
||||
p.target_world = intra_id[cw2.at];
|
||||
p.scw = cw1;
|
||||
p.tcw = cw2;
|
||||
switch_to(intra_id[cw1.at]);
|
||||
p.id1 = make_portal(cw1);
|
||||
switch_to(intra_id[cw2.at]);
|
||||
p.id2 = make_portal(cw2);
|
||||
|
||||
if(1) {
|
||||
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
||||
transmatrix T1;
|
||||
set_column(T1, 0, p.id1.co0);
|
||||
set_column(T1, 1, p.id1.co1);
|
||||
set_column(T1, 2, hyperpoint(0,0,p.id1.scale,0));
|
||||
set_column(T1, 3, C03);
|
||||
transmatrix T2;
|
||||
set_column(T2, 0, p.id2.co0);
|
||||
set_column(T2, 1, p.id2.co1);
|
||||
set_column(T2, 2, hyperpoint(0,0,-p.id2.scale,0));
|
||||
set_column(T2, 3, C03);
|
||||
if(debugflags & DF_GEOM) for(int i=0; i<4; i++)
|
||||
println(hlog, "mapping ", get_column(T1, i), " to ", get_column(T2, i));
|
||||
p.T = T2 * inverse(T1);
|
||||
}
|
||||
}
|
||||
|
||||
EX vector<pair<int, cell*>> full_sample_list;
|
||||
|
||||
EX void connect_portal(cellwalker cw1, cellwalker cw2) {
|
||||
connect_portal_1(cw1, cw2);
|
||||
connect_portal_1(cw2, cw1);
|
||||
}
|
||||
|
||||
/** make currentmap into one of the spaces in intra */
|
||||
EX void become() {
|
||||
auto& ac = currentmap->allcells();
|
||||
for(cell *c: ac)
|
||||
intra_id[c] = intra_current;
|
||||
for(cell *c: ac)
|
||||
currentmap->wall_offset(c);
|
||||
for(cell *c: ac) c->item = itNone;
|
||||
data.emplace_back();
|
||||
data.back().gd.storegame();
|
||||
data.back().gi = ginf[gProduct];
|
||||
|
||||
auto v = hybrid::gen_sample_list();
|
||||
int gi = 0;
|
||||
if(full_sample_list.size()) {
|
||||
gi = full_sample_list.back().first;
|
||||
full_sample_list.pop_back();
|
||||
}
|
||||
data.back().wallindex = gi;
|
||||
for(auto x: v)
|
||||
full_sample_list.emplace_back(x.first + gi, x.second);
|
||||
sightranges[geometry] = 10;
|
||||
}
|
||||
|
||||
/** after called become() on some spaces, actually start intra */
|
||||
EX void start(int id IS(0)) {
|
||||
in = true;
|
||||
intra_current = id;
|
||||
data[intra_current].gd.restoregame();
|
||||
ginf[gProduct] = data[intra_current].gi;
|
||||
}
|
||||
|
||||
#if HDR
|
||||
/** a convenience struct to switch back after a temporary switch_to */
|
||||
struct resetter {
|
||||
int ic;
|
||||
resetter() { ic = intra::intra_current; }
|
||||
~resetter() { if(intra::in) switch_to(ic); }
|
||||
};
|
||||
#endif
|
||||
|
||||
EX void may_switch_to(cell *c) {
|
||||
if(in) switch_to(intra_id[c]);
|
||||
}
|
||||
|
||||
EX int full_wall_offset(cell *c) {
|
||||
int wo = currentmap->wall_offset(c);
|
||||
if(in) wo += data[intra_id[c]].wallindex;
|
||||
return wo;
|
||||
}
|
||||
|
||||
EX void check_portal_movement() {
|
||||
transmatrix iView = view_inverse(View);
|
||||
ld dist = hdist0(iView * C0);
|
||||
int nei = -1;
|
||||
for(int i=0; i<centerover->type; i++) {
|
||||
ld dist1 = hdist0(currentmap->ray_iadj(centerover, i) * iView * C0);
|
||||
if(dist1 < dist) nei = i, dist = dist1;
|
||||
}
|
||||
|
||||
auto cw1 = cellwalker(centerover, nei);
|
||||
ld c = camera_speed;
|
||||
auto p = at_or_null(connections, cw1);
|
||||
if(p) {
|
||||
ld eps = 1e-3;
|
||||
c /= p->id1.scale;
|
||||
anims::cycle_length /= p->id1.scale;
|
||||
|
||||
array<hyperpoint, 3> ds; /* camera, forward, upward */
|
||||
ds[0] = inverse(View) * C0;
|
||||
ds[1] = inverse(get_shift_view_of(ctangent(2, -eps), View)) * C0;
|
||||
ds[2] = inverse(get_shift_view_of(ctangent(1, +eps), View)) * C0;
|
||||
|
||||
for(auto& h: ds) h = p->id1.to_poco(h);
|
||||
|
||||
/* reset the original */
|
||||
View = Id; NLP = Id;
|
||||
|
||||
switch_to(p->target_world);
|
||||
centerover = p->tcw.at;
|
||||
|
||||
if(1) {
|
||||
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
||||
for(auto& h: ds) h = p->T * h;
|
||||
}
|
||||
|
||||
for(auto& h: ds) h = p->id2.from_poco(h);
|
||||
|
||||
set_view(ds[0], ds[1], ds[2]);
|
||||
|
||||
c *= p->id2.scale;
|
||||
anims::cycle_length *= p->id2.scale;
|
||||
camera_speed = c;
|
||||
}
|
||||
}
|
||||
|
||||
EX }
|
||||
|
||||
}
|
@ -61,6 +61,8 @@ void gamedata_all(gamedata& gd) {
|
||||
gd.store(land_structure);
|
||||
gd.store(*current_display);
|
||||
gd.store(cgip);
|
||||
gd.store(hybrid::underlying);
|
||||
gd.store(hybrid::underlying_cgip);
|
||||
gd.store_ptr(vid);
|
||||
gd.store(sightrange_bonus);
|
||||
gd.store(genrange_bonus);
|
||||
|
@ -1410,7 +1410,7 @@ EX namespace hybrid {
|
||||
vector<pair<int, cell*>> result;
|
||||
for(auto& v: cgi.walloffsets) if(v.first >= 0) result.push_back(v);
|
||||
sort(result.begin(), result.end());
|
||||
result.emplace_back(isize(cgi.wallstart), nullptr);
|
||||
result.emplace_back(isize(cgi.wallstart)-1, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
351
raycaster.cpp
351
raycaster.cpp
@ -57,11 +57,13 @@ EX int max_cells = 2048;
|
||||
EX bool rays_generate = true;
|
||||
|
||||
EX ld& exp_decay_current() {
|
||||
if(intra::in) return exp_decay_exp;
|
||||
if(fake::in()) return *FPIU(&exp_decay_current());
|
||||
return (sn::in() || hyperbolic || sl2) ? exp_decay_exp : exp_decay_poly;
|
||||
}
|
||||
|
||||
EX int& max_iter_current() {
|
||||
if(intra::in) return max_iter_iso;
|
||||
if(nonisotropic || stretch::in()) return max_iter_sol;
|
||||
else if(is_eyes()) return max_iter_eyes;
|
||||
else return max_iter_iso;
|
||||
@ -93,6 +95,7 @@ ld& maxstep_current() {
|
||||
eGeometry last_geometry;
|
||||
|
||||
vector<pair<int, cell*>> used_sample_list() {
|
||||
if(intra::in) return intra::full_sample_list;
|
||||
return hybrid::gen_sample_list();
|
||||
}
|
||||
|
||||
@ -322,7 +325,8 @@ struct raygen {
|
||||
void compute_which_and_dist();
|
||||
void apply_reflect();
|
||||
void move_forward();
|
||||
void emit_iterate();
|
||||
void emit_intra_portal(int gid1, int gid2);
|
||||
void emit_iterate(int gid1);
|
||||
void create();
|
||||
};
|
||||
|
||||
@ -336,7 +340,7 @@ void raygen::compute_which_and_dist() {
|
||||
fmain +=
|
||||
" if(which == -1) {\n";
|
||||
|
||||
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : (WDIM == 2 || is_subcube_based(variation)) ? "sides" : its(flat2))+"; i++) {\n";
|
||||
fmain += "for(int i="+its(flat1)+"; i<"+(prod ? "sides-2" : (WDIM == 2 || is_subcube_based(variation) || intra::in) ? "sides" : its(flat2))+"; i++) {\n";
|
||||
|
||||
// fmain += "int woi = walloffset+i;\n";
|
||||
|
||||
@ -961,15 +965,132 @@ void raygen::apply_reflect() {
|
||||
}
|
||||
}
|
||||
|
||||
void raygen::emit_iterate() {
|
||||
void raygen::emit_intra_portal(int gid1, int gid2) {
|
||||
|
||||
int they_curvature = false;
|
||||
if(1) {
|
||||
intra::resetter ir;
|
||||
intra::switch_to(gid2);
|
||||
they_curvature = hyperbolic ? -1 : sphere ? 1 : 0;
|
||||
/* product also has 0 */
|
||||
}
|
||||
|
||||
if(prod && they_curvature) {
|
||||
string fn = in_h2xe() ? "to_poco_h2xr_h" : "to_poco_s2xr_s";
|
||||
fmain +=
|
||||
" mediump vec4 nposition = position + tangent * xspeed * 1e-3;\n"
|
||||
" position = "+fn+"(position);\n"
|
||||
" position.z = 0.;\n" // zpos - uPLevel;\n"
|
||||
" nposition = "+fn+"(nposition);\n"
|
||||
" nposition.z = zspeed * 1e-3;\n";
|
||||
}
|
||||
else if(prod) {
|
||||
string fn = in_h2xe() ? "to_poco_h2xr_e" : "to_poco_s2xr_e";
|
||||
fmain +=
|
||||
" mediump vec4 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";
|
||||
}
|
||||
else {
|
||||
fmain +=
|
||||
" mediump vec4 nposition = position + tangent * 1e-3;\n"
|
||||
" mediump mat4 tkt = " + getM("mid+1") + ";\n";
|
||||
if(hyperbolic) fmain +=
|
||||
" position = to_poco_h3(tkt * position);\n"
|
||||
" nposition = to_poco_h3(tkt * nposition);\n";
|
||||
else if(sphere) fmain +=
|
||||
" position = to_poco_s3(tkt * position);\n"
|
||||
" nposition = to_poco_s3(tkt * nposition);\n";
|
||||
else fmain +=
|
||||
" position = tkt * position;\n"
|
||||
" nposition = tkt * nposition;\n";
|
||||
}
|
||||
|
||||
fmain +=
|
||||
" mediump mat4 m = " + getM("mid") + ";\n"
|
||||
" position = m * position;\n"
|
||||
" nposition = m * nposition;\n";
|
||||
|
||||
int we_curvature = hyperbolic ? -1 : sphere ? 1 : 0;
|
||||
|
||||
intra::resetter ir;
|
||||
intra::switch_to(gid2);
|
||||
|
||||
if(prod && we_curvature) {
|
||||
string sgn = in_h2xe() ? "-" : "+";
|
||||
string fn = in_h2xe() ? "from_poco_h2xr_h" : "from_poco_s2xr_s";
|
||||
ld their_plevel = cgi.plevel / 2;
|
||||
fmain +=
|
||||
" zspeed = (nposition.z - position.z) * 1e3;\n"
|
||||
" zpos = position.z + " + glhr::to_glsl(their_plevel) + ";\n"
|
||||
" position = "+fn+"(position);\n"
|
||||
" nposition = "+fn+"(nposition);\n"
|
||||
" tangent = (nposition - position) * 1e3;\n"
|
||||
" mediump float pnorm = tangent.z * position.z "+sgn+" tangent.x * position.x "+sgn+" tangent.y * position.y;\n"
|
||||
" tangent -= position * pnorm;\n"
|
||||
" xspeed = sqrt(tangent.x * tangent.x + tangent.y * tangent.y "+sgn+" tangent.z * tangent.z);\n"
|
||||
" tangent /= xspeed;\n";
|
||||
}
|
||||
else if(prod) {
|
||||
string sgn = in_h2xe() ? "-" : "+";
|
||||
string fn = in_h2xe() ? "from_poco_h2xr_e" : "from_poco_s2xr_e";
|
||||
fmain +=
|
||||
" mediump mat4 itkt = " + getM("mid+2") + ";\n";
|
||||
fmain +=
|
||||
" zpos = position.y;\n"
|
||||
" zspeed = (nposition.y - zpos) * 1e3;\n"
|
||||
" position = itkt * "+fn+"(position);\n"
|
||||
" nposition = itkt * "+fn+"(nposition);\n"
|
||||
" tangent = (nposition - position) * 1e3;\n"
|
||||
" mediump float pnorm = tangent.z * position.z "+sgn+" dot(position.xy, tangent.xy);\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";
|
||||
}
|
||||
else {
|
||||
string sgn = hyperbolic ? "-" : "+";
|
||||
string he = hyperbolic ? "from_poco_h3" : "from_poco_s3";
|
||||
fmain +=
|
||||
" mediump mat4 itkt = " + getM("mid+2") + ";\n";
|
||||
|
||||
if(hyperbolic || sphere) fmain +=
|
||||
" position = itkt * "+he+"(position);\n"
|
||||
" nposition = itkt * "+he+"(nposition);\n"
|
||||
" tangent = (nposition - position) * 1e3;\n"
|
||||
" mediump float pnorm = position.w * position.w "+sgn+" dot(position.xyz, position.xyz);\n"
|
||||
" position /= sqrt(pnorm);\n"
|
||||
" pnorm = tangent.w * position.w "+sgn+" dot(position.xyz, tangent.xyz);\n"
|
||||
" tangent -= position * pnorm;\n"
|
||||
" mediump float xspeed = sqrt(dot(tangent.xyz, tangent.xyz) "+sgn+" tangent.w * tangent.w);\n"
|
||||
" tangent /= xspeed;\n";
|
||||
|
||||
else fmain +=
|
||||
" position = itkt * position;\n"
|
||||
" nposition = itkt * nposition;\n"
|
||||
" tangent = (nposition - position) * 1e3;\n"
|
||||
" tangent /= dot(tangent.xyz, tangent.xyz);\n";
|
||||
}
|
||||
}
|
||||
|
||||
void raygen::emit_iterate(int gid1) {
|
||||
using glhr::to_glsl;
|
||||
|
||||
if(intra::in && prod)
|
||||
fmain += " const mediump float uPLevel = " + to_glsl(cgi.plevel/2) + ";\n";
|
||||
|
||||
fmain +=
|
||||
" mediump float dist = 100.;\n";
|
||||
|
||||
fmain +=
|
||||
" int which = -1;\n";
|
||||
|
||||
if(hyperbolic && intra::in) fmain += "iter +=8;\n";
|
||||
|
||||
if(in_e2xe() && !eyes) fmain += "tangent.w = position.w = 0.;\n";
|
||||
|
||||
if(IN_ODS) fmain +=
|
||||
@ -1183,7 +1304,111 @@ void raygen::emit_iterate() {
|
||||
" m[0][1] = -m[0][1]; m[1][0] = -m[1][0];\n" // inverse
|
||||
" toOrig = toOrig * m;\n";
|
||||
|
||||
fmain += no_intra_portal;
|
||||
if(!intra::in) fmain += no_intra_portal;
|
||||
else {
|
||||
|
||||
if(hyperbolic) {
|
||||
fsh +=
|
||||
"mediump vec4 to_poco_h3(mediump vec4 pos) {\n"
|
||||
" return pos / pos[3];\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 from_poco_h3(mediump vec4 pos) {\n"
|
||||
" float s = 1. - dot(pos.xyz, pos.xyz);\n"
|
||||
" return pos / sqrt(s);\n"
|
||||
" }\n\n";
|
||||
}
|
||||
|
||||
if(sphere) {
|
||||
fsh +=
|
||||
"mediump vec4 to_poco_s3(mediump vec4 pos) {\n"
|
||||
" return pos / pos[3];\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 from_poco_s3(mediump vec4 pos) {\n"
|
||||
" float s = 1. + dot(pos.xyz, pos.xyz);\n"
|
||||
" return pos / sqrt(s);\n"
|
||||
" }\n\n";
|
||||
}
|
||||
|
||||
if(prod) {
|
||||
if(in_h2xe()) {
|
||||
fsh +=
|
||||
"mediump vec4 from_poco_h2xr_h(mediump vec4 pos) {\n"
|
||||
" float s = 1. - pos.x*pos.x - pos.y * pos.y;\n"
|
||||
" pos.z = 1.;\n"
|
||||
" return pos / sqrt(s);\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 to_poco_h2xr_h(mediump vec4 pos) {\n"
|
||||
" pos /= pos[2];\n"
|
||||
" pos.w = 1.;\n"
|
||||
" return pos;\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 from_poco_h2xr_e(mediump vec4 pos) {\n"
|
||||
" return vec4(sinh(pos[2]) * cosh(pos[0]), sinh(pos[0]), cosh(pos[0]) * cosh(pos[2]), 0);\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 to_poco_h2xr_e(mediump vec4 pos) {\n"
|
||||
" mediump float x = asinh(pos[1]);\n"
|
||||
" return vec4(x, 0, asinh(pos[0] / cosh(x)), 1);\n"
|
||||
" }\n\n";
|
||||
}
|
||||
else {
|
||||
fsh +=
|
||||
"mediump vec4 from_poco_s2xr_s(mediump vec4 pos) {\n"
|
||||
" float s = 1. + pos.x*pos.x + pos.y * pos.y;\n"
|
||||
" pos.z = 1.;\n"
|
||||
" return pos / sqrt(s);\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 to_poco_s2xr_s(mediump vec4 pos) {\n"
|
||||
" pos /= pos[2];\n"
|
||||
" pos.w = 1.;\n"
|
||||
" return pos;\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 from_poco_s2xr_e(mediump vec4 pos) {\n"
|
||||
" return vec4(sin(pos[2]) * cos(pos[0]), sin(pos[0]), cos(pos[0]) * cos(pos[2]), 0);\n"
|
||||
" }\n\n";
|
||||
|
||||
fsh +=
|
||||
"mediump vec4 to_poco_s2xr_e(mediump vec4 pos) {\n"
|
||||
" mediump float x = asin_clamp(pos[1]);\n"
|
||||
" return vec4(x, 0, asin_clamp(pos[0] / cos(x)), 1);\n"
|
||||
" }\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(intra::in) {
|
||||
int q = isize(intra::data);
|
||||
for(int gid2=0; gid2<q; gid2++) {
|
||||
if(gid2 == q-1)
|
||||
fmain += " {\n";
|
||||
else {
|
||||
fmain += " if(nwalloffset < " + its(intra::data[gid2+1].wallindex) + ") {\n";
|
||||
}
|
||||
if(gid1 == gid2)
|
||||
fmain += no_intra_portal;
|
||||
else
|
||||
emit_intra_portal(gid1, gid2);
|
||||
if(gid2 == q-1)
|
||||
fmain += " }\n";
|
||||
else
|
||||
fmain += " } else\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
fmain += no_intra_portal;
|
||||
}
|
||||
|
||||
if(many_cell_types) {
|
||||
fmain +=
|
||||
@ -1239,7 +1464,15 @@ void raygen::create() {
|
||||
" gl_Position = aPosition; at = uProjection * aPosition; \n"
|
||||
" }\n";
|
||||
|
||||
irays = isize(cgi.raywall);
|
||||
if(intra::in) {
|
||||
irays = 0;
|
||||
intra::resetter ir;
|
||||
for(int i=0; i<isize(intra::data); i++) {
|
||||
intra::switch_to(i);
|
||||
irays += isize(cgi.raywall);
|
||||
}
|
||||
}
|
||||
else irays = isize(cgi.raywall);
|
||||
string rays = its(irays);
|
||||
|
||||
fsh =
|
||||
@ -1481,6 +1714,11 @@ void raygen::create() {
|
||||
" mediump vec4 position = vw * vec4(0., 0., 0., 1.);\n"
|
||||
" mediump vec4 tangent = vw * at0;\n";
|
||||
}
|
||||
if(intra::in && !prod) {
|
||||
fmain += " mediump float zspeed = 1.;\n";
|
||||
fmain += " mediump float xspeed = 1.;\n";
|
||||
fmain += " mediump float zpos = 0.;\n";
|
||||
}
|
||||
|
||||
if(eyes) {
|
||||
fsh += "mediump uniform mat4 uEyeShift;\n";
|
||||
@ -1522,7 +1760,25 @@ void raygen::create() {
|
||||
" mediump vec2 cid = uStartid;\n"
|
||||
" for(int iter=0; iter<" + its(max_iter_current()) + "; iter++) {\n";
|
||||
|
||||
emit_iterate();
|
||||
if(intra::in) {
|
||||
int gi = isize(intra::data);
|
||||
for(int i=0; i<gi; i++) {
|
||||
if(i == gi-1)
|
||||
fmain += " {\n";
|
||||
else {
|
||||
fmain += " if(walloffset < " + its(intra::data[i+1].wallindex) + ") {\n";
|
||||
}
|
||||
intra::resetter ir;
|
||||
intra::switch_to(i);
|
||||
emit_iterate(i);
|
||||
if(i == gi-1)
|
||||
fmain += " }\n";
|
||||
else
|
||||
fmain += " } else\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
emit_iterate(-1);
|
||||
|
||||
fmain +=
|
||||
" }\n"
|
||||
@ -1644,9 +1900,12 @@ struct raycast_map {
|
||||
ms.clear();
|
||||
ms.resize(sa.back().first, Id);
|
||||
|
||||
intra::resetter ir;
|
||||
|
||||
for(auto& p: sa) {
|
||||
int id = p.first;
|
||||
cell *c = p.second;
|
||||
intra::may_switch_to(c);
|
||||
if(!c) continue;
|
||||
for(int j=0; j<c->type; j++)
|
||||
ms[id+j] = protect_prod(currentmap->ray_iadj(c, j));
|
||||
@ -1667,6 +1926,7 @@ struct raycast_map {
|
||||
int id = p.first;
|
||||
cell *c = p.second;
|
||||
if(!c) continue;
|
||||
intra::may_switch_to(c);
|
||||
for(int j=0; j<c->type; j++)
|
||||
ms[mirror_shift+id+j] = protect_prod(mirrorize(ms[id+j]));
|
||||
if(WDIM == 2) for(int a: {0, 1}) {
|
||||
@ -1680,12 +1940,14 @@ struct raycast_map {
|
||||
}
|
||||
}
|
||||
|
||||
if(prod) {
|
||||
for(auto p: sa) {
|
||||
int id =p.first;
|
||||
if(id == 0) continue;
|
||||
ms[id-2] = Id;
|
||||
ms[id-1] = Id;
|
||||
for(auto p: sa) {
|
||||
cell *c = p.second;
|
||||
if(!c) continue;
|
||||
intra::may_switch_to(c);
|
||||
int id =p.first;
|
||||
if(prod) {
|
||||
ms[id+c->type-2] = Id;
|
||||
ms[id+c->type-1] = Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1694,13 +1956,22 @@ struct raycast_map {
|
||||
manual_celllister cl;
|
||||
cl.add(cs);
|
||||
bool optimize = !isWall3(cs);
|
||||
intra::resetter ir;
|
||||
// vector<int> legaldir = { -1 };
|
||||
for(int i=0; i<isize(cl.lst); i++) {
|
||||
cell *c = cl.lst[i];
|
||||
intra::may_switch_to(c);
|
||||
if(racing::on && i > 0 && c->wall == waBarrier) continue;
|
||||
if(optimize && isWall3(c)) continue;
|
||||
forCellIdCM(c2, d, c) {
|
||||
// if(reflect_val == 0 && !((1<<d) & legaldir[i])) continue;
|
||||
|
||||
if(intra::in) {
|
||||
cellwalker cw(c, d);
|
||||
auto p = at_or_null(intra::connections, cw);
|
||||
if(p) c2 = p->tcw.at;
|
||||
}
|
||||
|
||||
if(rays_generate) setdist(c2, 7, c);
|
||||
/* if(!cl.listed(c2))
|
||||
legaldir.push_back(legaldir[i] &~ (1<<((d+3)%6)) ); */
|
||||
@ -1722,6 +1993,7 @@ struct raycast_map {
|
||||
}
|
||||
|
||||
void generate_connections(cell *c, int id) {
|
||||
intra::may_switch_to(c);
|
||||
auto& vmap = volumetric::vmap;
|
||||
if(volumetric::on) {
|
||||
celldrawer dd;
|
||||
@ -1735,7 +2007,14 @@ struct raycast_map {
|
||||
vcolor = (backcolor << 8);
|
||||
volumetric[u] = glhr::acolor(vcolor);
|
||||
}
|
||||
forCellIdEx(c1, i, c) {
|
||||
forCellIdEx(c1_real, i, c) {
|
||||
cell *c1 = c1_real;
|
||||
const intra::connection_data *p = nullptr;
|
||||
if(intra::in) {
|
||||
cellwalker cw(c, i);
|
||||
p = at_or_null(intra::connections, cw);
|
||||
if(p) c1 = p->tcw.at;
|
||||
}
|
||||
int u = (id/per_row*length) + (id%per_row * deg) + i;
|
||||
if(!ids.count(c1)) {
|
||||
wallcolor[u] = glhr::acolor(color_out_of_range | 0xFF);
|
||||
@ -1775,23 +2054,36 @@ struct raycast_map {
|
||||
}
|
||||
}
|
||||
|
||||
int wo = currentmap->wall_offset(c);
|
||||
int wo = intra::full_wall_offset(c);
|
||||
if(wo >= our_raygen.irays) {
|
||||
println(hlog, "wo=", wo, " irays = ", our_raygen.irays);
|
||||
reset_raycaster();
|
||||
return;
|
||||
}
|
||||
transmatrix T = currentmap->iadj(c, i) * inverse(ms[wo + i]);
|
||||
if(in_e2xe() && i >= c->type-2)
|
||||
T = Id;
|
||||
T = protect_prod(T);
|
||||
for(int k=0; k<=isize(ms); k++) {
|
||||
if(k < isize(ms) && !eqmatrix(ms[k], T, 1e-5)) continue;
|
||||
if(k == isize(ms)) ms.push_back(T);
|
||||
if(p) {
|
||||
int k = isize(ms);
|
||||
auto bak = geometry;
|
||||
ms.push_back(p->T);
|
||||
geometry = bak;
|
||||
ms.push_back(p->id1.T);
|
||||
ms.push_back(p->id2.iT);
|
||||
connections[u][2] = (k+.5) / 1024.;
|
||||
break;
|
||||
}
|
||||
auto wo1 = currentmap->wall_offset(c1);
|
||||
else {
|
||||
transmatrix T = currentmap->iadj(c, i) * inverse(ms[wo + i]);
|
||||
if(in_e2xe() && i >= c->type-2)
|
||||
T = Id;
|
||||
T = protect_prod(T);
|
||||
for(int k=0; k<=isize(ms); k++) {
|
||||
if(k < isize(ms) && !eqmatrix(ms[k], T, 1e-5)) continue;
|
||||
if(k == isize(ms)) ms.push_back(T);
|
||||
connections[u][2] = (k+.5) / 1024.;
|
||||
break;
|
||||
}
|
||||
}
|
||||
intra::resetter ir;
|
||||
intra::may_switch_to(c1);
|
||||
int wo1 = intra::full_wall_offset(c1);
|
||||
if(wo1 >= max_wall_offset)
|
||||
println(hlog, "error: wall_offset ", wo1, " exceeds ", max_wall_offset);
|
||||
if(c1->type >= max_celltype)
|
||||
@ -1815,6 +2107,7 @@ struct raycast_map {
|
||||
|
||||
void generate_connections() {
|
||||
int id = 0;
|
||||
intra::resetter ir;
|
||||
for(cell* c: lst) if(!reset_rmap)
|
||||
generate_connections(c, id++);
|
||||
}
|
||||
@ -2012,14 +2305,22 @@ EX void cast() {
|
||||
}
|
||||
|
||||
if(o->uWallOffset != -1) {
|
||||
glUniform1i(o->uWallOffset, currentmap->wall_offset(cs));
|
||||
glUniform1i(o->uWallOffset, intra::full_wall_offset(cs));
|
||||
glUniform1i(o->uSides, cs->type + (WDIM == 2 ? 2 : 0));
|
||||
}
|
||||
|
||||
vector<glvertex> wallx, wally;
|
||||
vector<GLint> wallstart;
|
||||
|
||||
load_walls(wallx, wally, wallstart);
|
||||
if(intra::in) {
|
||||
intra::resetter ir;
|
||||
for(int i=0; i<isize(intra::data); i++) {
|
||||
intra::switch_to(i);
|
||||
load_walls(wallx, wally, wallstart);
|
||||
}
|
||||
}
|
||||
else
|
||||
load_walls(wallx, wally, wallstart);
|
||||
|
||||
if(wall_via_texture) {
|
||||
int wlength = next_p2(isize(wallx));
|
||||
|
@ -801,21 +801,23 @@ EX void take(string fname, const function<void()>& what IS(default_screenshot_co
|
||||
#if CAP_WRL
|
||||
wrl::take(fname);
|
||||
#endif
|
||||
return;
|
||||
break;
|
||||
|
||||
case screenshot_format::svg:
|
||||
#if CAP_SVG
|
||||
svg::render(fname, what);
|
||||
#endif
|
||||
return;
|
||||
break;
|
||||
|
||||
case screenshot_format::png:
|
||||
case screenshot_format::rawfile:
|
||||
#if CAP_PNG
|
||||
render_png(fname, what);
|
||||
#endif
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
v.backup.plevel_factor = vid.plevel_factor;
|
||||
}
|
||||
|
||||
#if CAP_COMMANDLINE
|
||||
|
@ -751,6 +751,7 @@ EX void add_fixed_functions(string& shader) {
|
||||
|
||||
add_if(shader, "tanh", "mediump float tanh(mediump float x) { return sinh(x) / cosh(x); }\n");
|
||||
add_if(shader, "sinh", "mediump float sinh(mediump float x) { return (exp(x) - exp(-x)) / 2.0; }\n");
|
||||
add_if(shader, "asin_clamp", "mediump float asin_clamp(mediump float x) { return x > 1. ? PI/2. : x < -1. ? -PI/2. : asin(x); }\n");
|
||||
add_if(shader, "cosh", "mediump float cosh(mediump float x) { return (exp(x) + exp(-x)) / 2.0; }\n");
|
||||
add_if(shader, "asinh", "mediump float asinh(mediump float x) { return log(sqrt(x*x + 1.0) + x); }\n");
|
||||
add_if(shader, "acosh", "mediump float acosh(mediump float x) { return log(sqrt(x*x - 1.0) + x); }\n");
|
||||
|
Loading…
Reference in New Issue
Block a user