mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-10-26 11:27:39 +00:00
pipes for anisotropic geometries
This commit is contained in:
@@ -1278,31 +1278,25 @@ void geometry_information::make_3d_models() {
|
|||||||
finishshape();
|
finishshape();
|
||||||
}
|
}
|
||||||
|
|
||||||
hpcshape& geometry_information::generate_pipe(ld length, ld width, ePipeEnd endtype) {
|
hpcshape& geometry_information::gen_pipe(hpcshape& pipe, ePipeEnd endtype, ld ratio, const hr::function<hyperpoint(ld,ld,ld)>& f) {
|
||||||
int id = int(length * 172 + .5) + int(157003 * log(width+.001));
|
cgi.bshape(pipe, PPR::WALL);
|
||||||
bool pers = in_perspective();
|
|
||||||
if(!pers) id ^= 0x4126891;
|
|
||||||
if(shPipe.count(id)) return shPipe[id];
|
|
||||||
hpcshape& pipe = shPipe[id];
|
|
||||||
println(hlog, "generating pipe of length ", length, " and width ", width);
|
|
||||||
bshape(pipe, PPR::WALL);
|
|
||||||
|
|
||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
auto& utt = models_texture;
|
auto& utt = cgi.models_texture;
|
||||||
if(floor_textures) {
|
if(floor_textures) {
|
||||||
pipe.tinf = &utt;
|
pipe.tinf = &utt;
|
||||||
pipe.texture_offset = isize(utt.tvertices);
|
pipe.texture_offset = isize(utt.tvertices);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int MAX_X = 32;
|
const int MAX_X = 32;
|
||||||
const int MAX_R = 20;
|
const int MAX_R = 20;
|
||||||
auto at = [&] (ld i, ld a, ld z = 1, ld s = 1) {
|
auto at = [&] (ld i, ld a, ld z = 1, ld s = 1) {
|
||||||
a += 0.5;
|
a += 0.5;
|
||||||
ld alpha = TAU * a / MAX_R;
|
ld alpha = TAU * a / MAX_R;
|
||||||
hpcpush(xpush(i * length / MAX_X) * cspin(1, 2, alpha) * ypush0(width*z));
|
cgi.hpcpush(f(i / MAX_X, alpha, z));
|
||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
if(floor_textures) utt.tvertices.push_back(glhr::makevertex(0, pers ? 0.549 - s * 0.45 * sin(alpha) : 0.999, 0));
|
if(floor_textures) utt.tvertices.push_back(glhr::makevertex(0, true ? 0.549 - s * 0.45 * sin(alpha) : 0.999, 0));
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
for(int i=0; i<MAX_X; i++) {
|
for(int i=0; i<MAX_X; i++) {
|
||||||
@@ -1324,7 +1318,7 @@ hpcshape& geometry_information::generate_pipe(ld length, ld width, ePipeEnd endt
|
|||||||
|
|
||||||
if(endtype == ePipeEnd::ball) for(int a=0; a<MAX_R; a++) for(int x=-MAX_R; x<MAX_R; x++) {
|
if(endtype == ePipeEnd::ball) for(int a=0; a<MAX_R; a++) for(int x=-MAX_R; x<MAX_R; x++) {
|
||||||
ld xb = x < 0 ? 0 : MAX_X;
|
ld xb = x < 0 ? 0 : MAX_X;
|
||||||
ld mul = MAX_X * width/length * .9; // .9 to prevent Z-fighting
|
ld mul = MAX_X * ratio * .9; // .9 to prevent Z-fighting
|
||||||
ld x0 = xb + mul * sin(x * 90._deg / MAX_R);
|
ld x0 = xb + mul * sin(x * 90._deg / MAX_R);
|
||||||
ld x1 = xb + mul * sin((x+1) * 90._deg / MAX_R);
|
ld x1 = xb + mul * sin((x+1) * 90._deg / MAX_R);
|
||||||
ld z0 = cos(x * 90._deg / MAX_R);
|
ld z0 = cos(x * 90._deg / MAX_R);
|
||||||
@@ -1343,6 +1337,42 @@ hpcshape& geometry_information::generate_pipe(ld length, ld width, ePipeEnd endt
|
|||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hpcshape& geometry_information::get_pipe_noniso(hyperpoint target, ld width, ePipeEnd endtype) {
|
||||||
|
int id = bucketer(target) + int(157003 * log(width+.001));
|
||||||
|
if(cgi.shPipe.count(id)) return cgi.shPipe[id];
|
||||||
|
hpcshape& pipe = cgi.shPipe[id];
|
||||||
|
|
||||||
|
hyperpoint lmax = sol ? inverse_exp_newton(target, 10) : inverse_exp(shiftless(target));
|
||||||
|
transmatrix lT;
|
||||||
|
ld length;
|
||||||
|
if(1) {
|
||||||
|
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
||||||
|
length = hdist0(lmax);
|
||||||
|
lT = rspintox(lmax);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gen_pipe(pipe, endtype, width/length, [&] (ld i, ld alpha, ld z) {
|
||||||
|
hyperpoint p;
|
||||||
|
if(1) {
|
||||||
|
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
||||||
|
p = xpush(i * length) * cspin(1, 2, alpha) * ypush0(width*z);
|
||||||
|
p = lT * p;
|
||||||
|
}
|
||||||
|
return direct_exp(p);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hpcshape& geometry_information::get_pipe_iso(ld length, ld width, ePipeEnd endtype) {
|
||||||
|
int id = int(length * 172 + .5) + int(157003 * log(width+.001));
|
||||||
|
bool pers = in_perspective();
|
||||||
|
if(!pers) id ^= 0x4126891;
|
||||||
|
if(shPipe.count(id)) return shPipe[id];
|
||||||
|
hpcshape& pipe = shPipe[id];
|
||||||
|
println(hlog, "generating pipe of length ", length, " and width ", width);
|
||||||
|
|
||||||
|
return gen_pipe(pipe, endtype, width/length, [&] (ld i, ld alpha, ld z) { return xpush(i * length) * cspin(1, 2, alpha) * ypush0(width*z); });
|
||||||
|
}
|
||||||
|
|
||||||
#undef S
|
#undef S
|
||||||
#undef SH
|
#undef SH
|
||||||
#undef revZ
|
#undef revZ
|
||||||
|
|||||||
@@ -543,7 +543,9 @@ hpcshape
|
|||||||
void require_usershapes() { if(usershape_state == usershape_changes) return; usershape_state = usershape_changes; prepare_usershapes(); }
|
void require_usershapes() { if(usershape_state == usershape_changes) return; usershape_state = usershape_changes; prepare_usershapes(); }
|
||||||
int timestamp;
|
int timestamp;
|
||||||
|
|
||||||
hpcshape& generate_pipe(ld length, ld width, ePipeEnd endtype = ePipeEnd::sharp);
|
hpcshape& gen_pipe(hpcshape& pipe, ePipeEnd endtype, ld ratio, const hr::function<hyperpoint(ld,ld,ld)>& f);
|
||||||
|
hpcshape& get_pipe_iso(ld length, ld width, ePipeEnd endtype = ePipeEnd::sharp);
|
||||||
|
hpcshape& get_pipe_noniso(hyperpoint target, ld width, ePipeEnd endtype = ePipeEnd::sharp);
|
||||||
|
|
||||||
map<string, unique_ptr<gi_extension>> ext;
|
map<string, unique_ptr<gi_extension>> ext;
|
||||||
|
|
||||||
|
|||||||
12
graph.cpp
12
graph.cpp
@@ -4200,11 +4200,19 @@ EX void gridline(const shiftmatrix& V1, const hyperpoint h1, const shiftmatrix&
|
|||||||
ld d = (c1 <= 0 || c2 <= 0) ? 99 : hdist(V1.T*h1, U2*h2);
|
ld d = (c1 <= 0 || c2 <= 0) ? 99 : hdist(V1.T*h1, U2*h2);
|
||||||
|
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
if(WDIM == 3 && fat_edges) {
|
if(GDIM == 3 && fat_edges) {
|
||||||
|
if(nonisotropic) {
|
||||||
|
auto nV1 = V1 * rgpushxto0(h1);
|
||||||
|
hyperpoint U2 = inverse_shift(nV1, V2*rgpushxto0(h2)) * C0;
|
||||||
|
auto& p = cgi.get_pipe_noniso(U2, vid.linewidth, ePipeEnd::ball);
|
||||||
|
queuepoly(nV1, p, col);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
shiftmatrix T = V1 * rgpushxto0(h1);
|
shiftmatrix T = V1 * rgpushxto0(h1);
|
||||||
transmatrix S = rspintox(inverse_shift(T, V2) * h2);
|
transmatrix S = rspintox(inverse_shift(T, V2) * h2);
|
||||||
transmatrix U = rspintoc(inverse_shift(T*S, shiftless(C0)), 2, 1);
|
transmatrix U = rspintoc(inverse_shift(T*S, shiftless(C0)), 2, 1);
|
||||||
auto& p = queuepoly(T * S * U, cgi.generate_pipe(d, vid.linewidth, ePipeEnd::ball), col);
|
auto& p = queuepoly(T * S * U, cgi.get_pipe_iso(d, vid.linewidth, ePipeEnd::ball), col);
|
||||||
p.intester = xpush0(d/2);
|
p.intester = xpush0(d/2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -610,119 +610,10 @@ void draw_hedge(const shiftmatrix& V) {
|
|||||||
md->render(V);
|
md->render(V);
|
||||||
}
|
}
|
||||||
|
|
||||||
hyperpoint inverse_exp_newton(hyperpoint h, int iter) {
|
|
||||||
auto approx = inverse_exp(shiftless(h));
|
|
||||||
for(int i=0; i<iter; i++) {
|
|
||||||
transmatrix T;
|
|
||||||
ld eps = 1e-3;
|
|
||||||
hyperpoint cur = direct_exp(approx);
|
|
||||||
println(hlog, approx, " error = ", hdist(cur, h), " iteration ", i, "/", iter);
|
|
||||||
for(int i=0; i<3; i++)
|
|
||||||
set_column(T, i, direct_exp(approx + ctangent(i, eps)) - h);
|
|
||||||
set_column(T, 3, C03);
|
|
||||||
approx = approx - inverse(T) * (cur - h) * eps;
|
|
||||||
}
|
|
||||||
return approx;
|
|
||||||
}
|
|
||||||
|
|
||||||
hpcshape& get_noniso_pipe(hyperpoint target, ld width, ePipeEnd endtype) {
|
|
||||||
int id = bucketer(target) + int(157003 * log(width+.001));
|
|
||||||
if(cgi.shPipe.count(id)) return cgi.shPipe[id];
|
|
||||||
hpcshape& pipe = cgi.shPipe[id];
|
|
||||||
println(hlog, "generating pipe at target ", target, " and width ", width);
|
|
||||||
cgi.bshape(pipe, PPR::HEPTAMARK);
|
|
||||||
|
|
||||||
#if CAP_GL
|
|
||||||
auto& utt = cgi.models_texture;
|
|
||||||
if(floor_textures) {
|
|
||||||
pipe.tinf = &utt;
|
|
||||||
pipe.texture_offset = isize(utt.tvertices);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hyperpoint lmax = inverse_exp_newton(target, 10);
|
|
||||||
println(hlog, "error = ", hdist(direct_exp(lmax), target));
|
|
||||||
transmatrix lT;
|
|
||||||
ld length;
|
|
||||||
if(1) {
|
|
||||||
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
|
||||||
length = hdist0(lmax);
|
|
||||||
lT = rspintox(lmax);
|
|
||||||
println(hlog, "target = ", target, " lmax = ", lmax, " length = ", length, " lT = ", kz(lT));
|
|
||||||
println(hlog, "test: ", lT * xpush0(length), " vs ", lmax);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int MAX_X = 32;
|
|
||||||
const int MAX_R = 20;
|
|
||||||
auto at = [&] (ld i, ld a, ld z = 1, ld s = 1) {
|
|
||||||
a += 0.5;
|
|
||||||
ld alpha = TAU * a / MAX_R;
|
|
||||||
hyperpoint p;
|
|
||||||
if(1) {
|
|
||||||
dynamicval<eGeometry> g(geometry, gCubeTiling);
|
|
||||||
p = xpush(i * length / MAX_X) * cspin(1, 2, alpha) * ypush0(width*z);
|
|
||||||
p = lT * p;
|
|
||||||
}
|
|
||||||
p = direct_exp(p);
|
|
||||||
cgi.hpcpush(p);
|
|
||||||
#if CAP_GL
|
|
||||||
if(floor_textures) utt.tvertices.push_back(glhr::makevertex(0, true ? 0.549 - s * 0.45 * sin(alpha) : 0.999, 0));
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
for(int i=0; i<MAX_X; i++) {
|
|
||||||
for(int a=0; a<MAX_R; a++) {
|
|
||||||
at(i, a, 1);
|
|
||||||
at(i, a+1, 1);
|
|
||||||
at(i+1, a, 1);
|
|
||||||
at(i+1, a+1, 1);
|
|
||||||
at(i+1, a, 1);
|
|
||||||
at(i, a+1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(endtype == ePipeEnd::sharp) for(int a=0; a<MAX_R; a++) for(int x: {0, MAX_X}) {
|
|
||||||
at(x, a, 1, 0);
|
|
||||||
at(x, a+1, 1, 0);
|
|
||||||
at(x, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(endtype == ePipeEnd::ball) for(int a=0; a<MAX_R; a++) for(int x=-MAX_R; x<MAX_R; x++) {
|
|
||||||
ld xb = x < 0 ? 0 : MAX_X;
|
|
||||||
ld mul = MAX_X * width/length * .9; // .9 to prevent Z-fighting
|
|
||||||
ld x0 = xb + mul * sin(x * 90._deg / MAX_R);
|
|
||||||
ld x1 = xb + mul * sin((x+1) * 90._deg / MAX_R);
|
|
||||||
ld z0 = cos(x * 90._deg / MAX_R);
|
|
||||||
ld z1 = cos((x+1) * 90._deg / MAX_R);
|
|
||||||
at(x0, a, z0, z0);
|
|
||||||
at(x0, a+1, z0, z0);
|
|
||||||
at(x1, a, z1, z1);
|
|
||||||
at(x1, a+1, z1, z1);
|
|
||||||
at(x1, a, z1, z1);
|
|
||||||
at(x0, a+1, z0, z0);
|
|
||||||
}
|
|
||||||
|
|
||||||
cgi.last->flags |= POLY_TRIANGLES | POLY_PRINTABLE;
|
|
||||||
cgi.finishshape();
|
|
||||||
cgi.extra_vertices();
|
|
||||||
return pipe;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fat_line(const shiftmatrix& V1, const hyperpoint h1, const shiftmatrix& V2, const hyperpoint h2, color_t col, int prec, ld lw) {
|
void fat_line(const shiftmatrix& V1, const hyperpoint h1, const shiftmatrix& V2, const hyperpoint h2, color_t col, int prec, ld lw) {
|
||||||
if(nonisotropic) {
|
dynamicval<bool> df(fat_edges, true);
|
||||||
auto nV1 = V1 * rgpushxto0(h1);
|
dynamicval<ld> dlw(vid.linewidth, lw);
|
||||||
hyperpoint U2 = inverse_shift(nV1, V2*rgpushxto0(h2)) * C0;
|
gridline(V1, h1, V2, h2, col, prec);
|
||||||
auto& p = get_noniso_pipe(U2, lw, ePipeEnd::ball);
|
|
||||||
queuepoly(nV1, p, col);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ld d = hdist(V1.T*h1, V2.T*h2);
|
|
||||||
|
|
||||||
shiftmatrix T = V1 * rgpushxto0(h1);
|
|
||||||
transmatrix S = rspintox(inverse_shift(T, V2) * h2);
|
|
||||||
transmatrix U = rspintoc(inverse_shift(T*S, shiftless(C0)), 2, 1);
|
|
||||||
auto& p = queuepoly(T * S * U, cgi.generate_pipe(d, lw, ePipeEnd::ball), col);
|
|
||||||
p.intester = xpush0(d/2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int scaffoldx = 0, scaffoldy = 0, scaffoldb = 0, scaffoldx_move = 0, scaffoldy_move;
|
int scaffoldx = 0, scaffoldy = 0, scaffoldb = 0, scaffoldx_move = 0, scaffoldy_move;
|
||||||
|
|||||||
Reference in New Issue
Block a user