mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
refactored do_draw(cell*, const transmatrix&)
This commit is contained in:
parent
3f8194746a
commit
44c1b43b1c
@ -604,15 +604,6 @@ void create_adjacent(heptagon *h, int d) {
|
|||||||
connect_digons_too(hi, heptspin(hnew, 0));
|
connect_digons_too(hi, heptspin(hnew, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
set<heptagon*> visited;
|
|
||||||
queue<tuple<heptagon*, transmatrix, ld>> drawqueue;
|
|
||||||
|
|
||||||
void enqueue(heptagon *h, const transmatrix& T) {
|
|
||||||
if(visited.count(h)) { return; }
|
|
||||||
visited.insert(h);
|
|
||||||
drawqueue.emplace(h, T, band_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
pair<ld, ld>& archimedean_tiling::get_triangle(heptagon *h, int cid) {
|
pair<ld, ld>& archimedean_tiling::get_triangle(heptagon *h, int cid) {
|
||||||
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||||
}
|
}
|
||||||
@ -641,23 +632,21 @@ transmatrix adjcell_matrix(heptagon *h, int d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void draw() {
|
void draw() {
|
||||||
visited.clear();
|
dq::visited.clear();
|
||||||
enqueue(viewctr.at, cview());
|
dq::enqueue(viewctr.at, cview());
|
||||||
int idx = 0;
|
|
||||||
|
|
||||||
while(!drawqueue.empty()) {
|
while(!dq::drawqueue.empty()) {
|
||||||
auto p = drawqueue.front();
|
auto& p = dq::drawqueue.front();
|
||||||
drawqueue.pop();
|
|
||||||
heptagon *h = get<0>(p);
|
heptagon *h = get<0>(p);
|
||||||
transmatrix V = get<1>(p);
|
transmatrix V = get<1>(p);
|
||||||
dynamicval<ld> b(band_shift, get<2>(p));
|
dynamicval<ld> b(band_shift, get<2>(p));
|
||||||
|
dq::drawqueue.pop();
|
||||||
|
|
||||||
int id = id_of(h);
|
int id = id_of(h);
|
||||||
int S = isize(current.triangles[id]);
|
int S = isize(current.triangles[id]);
|
||||||
|
|
||||||
if(id < 2*current.N ? !DUAL : !PURE) {
|
if(id < 2*current.N ? !DUAL : !PURE) {
|
||||||
if(vid.use_smart_range == 0 && !dodrawcell(h->c7)) continue;
|
if(!do_draw(h->c7, V)) continue;
|
||||||
if(vid.use_smart_range && idx > 50 && !in_smart_range(V)) continue;
|
|
||||||
if(vid.use_smart_range == 2) setdist(h->c7, 7, h->c7);
|
|
||||||
drawcell(h->c7, V, 0, false);
|
drawcell(h->c7, V, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,9 +656,8 @@ void draw() {
|
|||||||
if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue;
|
if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue;
|
||||||
transmatrix V1 = V * adjcell_matrix(h, i);
|
transmatrix V1 = V * adjcell_matrix(h, i);
|
||||||
bandfixer bf(V1);
|
bandfixer bf(V1);
|
||||||
enqueue(h->move(i), V1);
|
dq::enqueue(h->move(i), V1);
|
||||||
}
|
}
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,39 +152,34 @@ namespace binary {
|
|||||||
return transmatrix {{{-u*u/8+1, u/2, u*u/8}, {-u/2, 1, u/2}, {-u*u/8, u/2, u*u/8+1}}};
|
return transmatrix {{{-u*u/8+1, u/2, u*u/8}, {-u/2, 1, u/2}, {-u*u/8, u/2, u*u/8+1}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_rec(cell *c, int dirs, const transmatrix& V, int reclev) {
|
|
||||||
|
|
||||||
transmatrix V1 = V;
|
|
||||||
bandfixer bf(V1);
|
|
||||||
|
|
||||||
if(vid.use_smart_range == 0 && !dodrawcell(c)) return;
|
|
||||||
if(vid.use_smart_range && reclev >= 2 && !in_smart_range(V1)) return;
|
|
||||||
if(vid.use_smart_range == 2) setdist(c, 7, c);
|
|
||||||
|
|
||||||
drawcell(c, V1, 0, false);
|
|
||||||
// 1: up
|
|
||||||
if(dirs & 1)
|
|
||||||
draw_rec(createMov(c, bd_up), 7, V1 * xpush(-log(2)), reclev+1);
|
|
||||||
// right
|
|
||||||
if(dirs & 2)
|
|
||||||
draw_rec(createMov(c, bd_right), 2, V1 * parabolic(1), reclev+1);
|
|
||||||
// left
|
|
||||||
if(dirs & 4)
|
|
||||||
draw_rec(createMov(c, bd_left), 4, V1 * parabolic(-1), reclev+1);
|
|
||||||
// down
|
|
||||||
if((dirs & 8) && c->type == 6)
|
|
||||||
draw_rec(createMov(c, bd_down), dirs & 62, V1 * xpush(log(2)), reclev+1);
|
|
||||||
// down_left
|
|
||||||
if((dirs & 16) && c->type == 7)
|
|
||||||
draw_rec(createMov(c, bd_down_left), dirs & 28, V1 * parabolic(-1) * xpush(log(2)), reclev+1);
|
|
||||||
// down_right
|
|
||||||
if((dirs & 32) && c->type == 7)
|
|
||||||
draw_rec(createMov(c, bd_down_right), dirs & 42, V1 * parabolic(1) * xpush(log(2)), reclev+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
void draw() {
|
||||||
draw_rec(viewctr.at->c7, 63, cview(), 0);
|
dq::visited.clear();
|
||||||
}
|
dq::enqueue(viewctr.at, cview());
|
||||||
|
|
||||||
|
while(!dq::drawqueue.empty()) {
|
||||||
|
auto& p = dq::drawqueue.front();
|
||||||
|
heptagon *h = get<0>(p);
|
||||||
|
transmatrix V = get<1>(p);
|
||||||
|
dynamicval<ld> b(band_shift, get<2>(p));
|
||||||
|
bandfixer bf(V);
|
||||||
|
dq::drawqueue.pop();
|
||||||
|
|
||||||
|
cell *c = h->c7;
|
||||||
|
if(!do_draw(c, V)) continue;
|
||||||
|
drawcell(c, V, 0, false);
|
||||||
|
|
||||||
|
dq::enqueue(h->move(bd_up), V * xpush(-log(2)));
|
||||||
|
dq::enqueue(h->move(bd_right), V * parabolic(1));
|
||||||
|
dq::enqueue(h->move(bd_left), V * parabolic(-1));
|
||||||
|
if(c->type == 6)
|
||||||
|
dq::enqueue(h->move(bd_down), V * xpush(log(2)));
|
||||||
|
// down_left
|
||||||
|
if(c->type == 7) {
|
||||||
|
dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2)));
|
||||||
|
dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||||
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))
|
||||||
|
12
graph.cpp
12
graph.cpp
@ -3388,18 +3388,6 @@ void pushdown(cell *c, int& q, const transmatrix &V, double down, bool rezoom, b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dodrawcell(cell *c) {
|
|
||||||
// do not display out of range cells, unless on torus
|
|
||||||
if(c->pathdist == PINFD && geometry != gTorus && vid.use_smart_range == 0)
|
|
||||||
return false;
|
|
||||||
// do not display not fully generated cells, unless a cheater
|
|
||||||
if(c->mpdist > 7 && !cheater && !autocheat) return false;
|
|
||||||
// in the Yendor Challenge, scrolling back is forbidden
|
|
||||||
if(c->cpdist > 7 && yendor::on && !cheater && !autocheat) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1 : (floor, water); 2 : (water, bottom); 4 : (bottom, inf)
|
// 1 : (floor, water); 2 : (water, bottom); 4 : (bottom, inf)
|
||||||
|
|
||||||
int shallow(cell *c) {
|
int shallow(cell *c) {
|
||||||
|
9
hyper.h
9
hyper.h
@ -4356,5 +4356,14 @@ inline void delayed_geo_reset() { need_reset_geometry = true; }
|
|||||||
|
|
||||||
extern unordered_map<string, ld&> params;
|
extern unordered_map<string, ld&> params;
|
||||||
|
|
||||||
|
namespace dq {
|
||||||
|
extern set<heptagon*> visited;
|
||||||
|
extern queue<tuple<heptagon*, transmatrix, ld>> drawqueue;
|
||||||
|
|
||||||
|
void enqueue(heptagon *h, const transmatrix& T);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool do_draw(cell *c, const transmatrix& T);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
92
hypgraph.cpp
92
hypgraph.cpp
@ -690,8 +690,11 @@ transmatrix applyspin(const heptspin& hs, const transmatrix& V) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool in_smart_range(const transmatrix& T) {
|
bool in_smart_range(const transmatrix& T) {
|
||||||
|
if(std::isnan(T[2][2]) || std::isinf(T[2][2]) || T[2][2] > 1e8) return false;
|
||||||
hyperpoint h1, h2, h3;
|
hyperpoint h1, h2, h3;
|
||||||
applymodel(tC0(T), h1);
|
applymodel(tC0(T), h1);
|
||||||
|
if(std::isnan(h1[0]) || std::isnan(h1[1])) return false;
|
||||||
|
if(std::isinf(h1[0]) || std::isinf(h1[1])) return false;
|
||||||
ld x = vid.xcenter + vid.radius * h1[0];
|
ld x = vid.xcenter + vid.radius * h1[0];
|
||||||
ld y = vid.ycenter + vid.radius * h1[1] * vid.stretch;
|
ld y = vid.ycenter + vid.radius * h1[1] * vid.stretch;
|
||||||
if(x > vid.xres * 2) return false;
|
if(x > vid.xres * 2) return false;
|
||||||
@ -715,13 +718,6 @@ bool in_smart_range(const transmatrix& T) {
|
|||||||
y + 2 * max(y1, y2) > 0;
|
y + 2 * max(y1, y2) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// in hyperbolic quotient geometries, relying on pathdist is not sufficient
|
|
||||||
bool in_qrange(const transmatrix& V) {
|
|
||||||
if(!quotient || !hyperbolic || vid.use_smart_range) return true;
|
|
||||||
return in_smart_range(V);
|
|
||||||
// return V[2][2] < cosh(crossf * get_sightrange_ambush());
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace gp {
|
namespace gp {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -741,7 +737,7 @@ void drawrec(cell *c, const transmatrix& V) {
|
|||||||
gp::local_info draw_li;
|
gp::local_info draw_li;
|
||||||
|
|
||||||
void drawrec(cell *c, const transmatrix& V, gp::loc at, int dir, int maindir) {
|
void drawrec(cell *c, const transmatrix& V, gp::loc at, int dir, int maindir) {
|
||||||
if(dodrawcell(c)) {
|
if(do_draw(c, V)) {
|
||||||
/* auto li = get_local_info(c);
|
/* auto li = get_local_info(c);
|
||||||
if(fix6(dir) != fix6(li.total_dir)) printf("totaldir %d/%d\n", dir, li.total_dir);
|
if(fix6(dir) != fix6(li.total_dir)) printf("totaldir %d/%d\n", dir, li.total_dir);
|
||||||
if(at != li.relative) printf("at %s/%s\n", disp(at), disp(li.relative));
|
if(at != li.relative) printf("at %s/%s\n", disp(at), disp(li.relative));
|
||||||
@ -749,8 +745,7 @@ void drawrec(cell *c, const transmatrix& V) {
|
|||||||
draw_li.relative = at;
|
draw_li.relative = at;
|
||||||
draw_li.total_dir = fixg6(dir);
|
draw_li.total_dir = fixg6(dir);
|
||||||
transmatrix V1 = V * Tf[draw_li.last_dir][at.first&31][at.second&31][fixg6(dir)];
|
transmatrix V1 = V * Tf[draw_li.last_dir][at.first&31][at.second&31][fixg6(dir)];
|
||||||
if(in_qrange(V1))
|
drawcell(c, V1, 0, false);
|
||||||
drawcell(c, V1, 0, false);
|
|
||||||
}
|
}
|
||||||
for(int i=0; i<c->type; i++) {
|
for(int i=0; i<c->type; i++) {
|
||||||
cell *c2 = c->move(i);
|
cell *c2 = c->move(i);
|
||||||
@ -765,7 +760,7 @@ void drawrec(cell *c, const transmatrix& V) {
|
|||||||
draw_li.relative = loc(0,0);
|
draw_li.relative = loc(0,0);
|
||||||
draw_li.total_dir = 0;
|
draw_li.total_dir = 0;
|
||||||
draw_li.last_dir = -1;
|
draw_li.last_dir = -1;
|
||||||
if(dodrawcell(c))
|
if(do_draw(c, V))
|
||||||
drawcell(c, V, 0, false);
|
drawcell(c, V, 0, false);
|
||||||
for(int i=0; i<c->type; i++) {
|
for(int i=0; i<c->type; i++) {
|
||||||
cell *c2 = c->move(i);
|
cell *c2 = c->move(i);
|
||||||
@ -780,23 +775,14 @@ void drawrec(cell *c, const transmatrix& V) {
|
|||||||
|
|
||||||
void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev) {
|
void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev) {
|
||||||
|
|
||||||
// calc_relative_matrix(cwt.c, hs.at);
|
// calc_relative_matrix(cwt.c, hs.at);
|
||||||
|
|
||||||
cell *c = hs.at->c7;
|
cell *c = hs.at->c7;
|
||||||
|
|
||||||
transmatrix V10;
|
transmatrix V10;
|
||||||
const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V;
|
const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V;
|
||||||
|
|
||||||
bool draw = c->pathdist < PINFD;
|
bool draw = false;
|
||||||
|
|
||||||
if(cells_drawn > vid.cells_drawn_limit || reclev >= 10000 || std::isinf(V[2][2]) || std::isnan(V[2][2]) || V[2][2] > 1e8)
|
|
||||||
draw = false;
|
|
||||||
else if(vid.use_smart_range) {
|
|
||||||
draw = reclev < 2 ? true : in_smart_range(V);
|
|
||||||
if(draw && vid.use_smart_range == 2)
|
|
||||||
setdist(c, 7, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GOLDBERG) {
|
if(GOLDBERG) {
|
||||||
gp::drawrec(c, actualV(hs, V1));
|
gp::drawrec(c, actualV(hs, V1));
|
||||||
}
|
}
|
||||||
@ -805,27 +791,30 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev) {
|
|||||||
auto& hi = irr::periodmap[hs.at];
|
auto& hi = irr::periodmap[hs.at];
|
||||||
transmatrix V0 = actualV(hs, V1);
|
transmatrix V0 = actualV(hs, V1);
|
||||||
auto& vc = irr::cells_of_heptagon[hi.base.at];
|
auto& vc = irr::cells_of_heptagon[hi.base.at];
|
||||||
for(int i=0; i<isize(vc); i++)
|
for(int i=0; i<isize(vc); i++) {
|
||||||
if(dodrawcell(hi.subcells[i]) && in_qrange(V0 * irr::cells[vc[i]].pusher))
|
cell *c = hi.subcells[i];
|
||||||
|
transmatrix V1 = V0 * irr::cells[vc[i]].pusher;
|
||||||
|
if(do_draw(c, V1))
|
||||||
draw = true,
|
draw = true,
|
||||||
drawcell(hi.subcells[i], V0 * irr::cells[vc[i]].pusher, 0, false);
|
drawcell(hi.subcells[i], V0 * irr::cells[vc[i]].pusher, 0, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if(dodrawcell(c)) {
|
if(do_draw(c, V1)) {
|
||||||
transmatrix V2 = actualV(hs, V1);
|
transmatrix V2 = actualV(hs, V1);
|
||||||
if(in_qrange(V2))
|
drawcell(c, V2, 0, hs.mirrored);
|
||||||
drawcell(c, V2, 0, hs.mirrored);
|
draw = true;
|
||||||
else draw = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(BITRUNCATED) for(int d=0; d<S7; d++) {
|
if(BITRUNCATED) for(int d=0; d<S7; d++) {
|
||||||
int ds = hs.at->c.fix(hs.spin + d);
|
int ds = hs.at->c.fix(hs.spin + d);
|
||||||
// createMov(c, ds);
|
// createMov(c, ds);
|
||||||
if(c->move(ds) && c->c.spin(ds) == 0 && dodrawcell(c->move(ds))) {
|
if(c->move(ds) && c->c.spin(ds) == 0) {
|
||||||
transmatrix V2 = V1 * hexmove[d];
|
transmatrix V2 = V1 * hexmove[d];
|
||||||
if(in_qrange(V2))
|
if(do_draw(c->move(ds), V2))
|
||||||
drawcell(c->move(ds), V2, 0, hs.mirrored ^ c->c.mirror(ds));
|
draw = true,
|
||||||
|
drawcell(c->move(ds), V2, 0, hs.mirrored ^ c->c.mirror(ds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -928,10 +917,8 @@ void drawEuclidean() {
|
|||||||
if(locald < centerd) centerd = locald, centerover = cw, View = Mat;
|
if(locald < centerd) centerd = locald, centerover = cw, View = Mat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i < 30 || in_smart_range(Mat)) {
|
if(do_draw(cw.at, Mat)) {
|
||||||
if(vid.use_smart_range == 2) setdist(cw.at, 7, cw.at);
|
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
|
||||||
if(dodrawcell(cw.at))
|
|
||||||
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
|
|
||||||
for(int x=-1; x<=+1; x++)
|
for(int x=-1; x<=+1; x++)
|
||||||
for(int y=-1; y<=+1; y++) {
|
for(int y=-1; y<=+1; y++) {
|
||||||
auto p = at + pair_to_vec(x, y);
|
auto p = at + pair_to_vec(x, y);
|
||||||
@ -1353,4 +1340,37 @@ void fix_the_band(transmatrix& T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace dq {
|
||||||
|
set<heptagon*> visited;
|
||||||
|
queue<tuple<heptagon*, transmatrix, ld>> drawqueue;
|
||||||
|
|
||||||
|
void enqueue(heptagon *h, const transmatrix& T) {
|
||||||
|
if(!h || visited.count(h)) { return; }
|
||||||
|
visited.insert(h);
|
||||||
|
drawqueue.emplace(h, T, band_shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool do_draw(cell *c) {
|
||||||
|
// do not display out of range cells, unless on torus
|
||||||
|
if(c->pathdist == PINFD && geometry != gTorus && vid.use_smart_range == 0)
|
||||||
|
return false;
|
||||||
|
// do not display not fully generated cells, unless a cheater
|
||||||
|
if(c->mpdist > 7 && !cheater && !autocheat) return false;
|
||||||
|
// in the Yendor Challenge, scrolling back is forbidden
|
||||||
|
if(c->cpdist > 7 && yendor::on && !cheater && !autocheat) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool do_draw(cell *c, const transmatrix& T) {
|
||||||
|
if(!do_draw(c)) return false;
|
||||||
|
if(cells_drawn > vid.cells_drawn_limit) return false;
|
||||||
|
bool usr = vid.use_smart_range || quotient || torus;
|
||||||
|
if(usr && cells_drawn >= 50 && !in_smart_range(T)) return false;
|
||||||
|
if(vid.use_smart_range == 2) setdist(c, 7, c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user