refactored do_draw(cell*, const transmatrix&)

This commit is contained in:
Zeno Rogue 2018-11-10 14:26:49 +01:00
parent 3f8194746a
commit 44c1b43b1c
5 changed files with 100 additions and 100 deletions

View File

@ -604,15 +604,6 @@ void create_adjacent(heptagon *h, int d) {
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) {
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() {
visited.clear();
enqueue(viewctr.at, cview());
int idx = 0;
dq::visited.clear();
dq::enqueue(viewctr.at, cview());
while(!drawqueue.empty()) {
auto p = drawqueue.front();
drawqueue.pop();
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));
dq::drawqueue.pop();
int id = id_of(h);
int S = isize(current.triangles[id]);
if(id < 2*current.N ? !DUAL : !PURE) {
if(vid.use_smart_range == 0 && !dodrawcell(h->c7)) 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);
if(!do_draw(h->c7, V)) continue;
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;
transmatrix V1 = V * adjcell_matrix(h, i);
bandfixer bf(V1);
enqueue(h->move(i), V1);
dq::enqueue(h->move(i), V1);
}
idx++;
}
}

View File

@ -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}}};
}
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() {
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) {
if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7))

View File

@ -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)
int shallow(cell *c) {

View File

@ -4356,5 +4356,14 @@ inline void delayed_geo_reset() { need_reset_geometry = true; }
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);
}

View File

@ -690,8 +690,11 @@ transmatrix applyspin(const heptspin& hs, const transmatrix& V) {
}
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;
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 y = vid.ycenter + vid.radius * h1[1] * vid.stretch;
if(x > vid.xres * 2) return false;
@ -715,13 +718,6 @@ bool in_smart_range(const transmatrix& T) {
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 {
/*
@ -741,7 +737,7 @@ void drawrec(cell *c, const transmatrix& V) {
gp::local_info draw_li;
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);
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));
@ -749,8 +745,7 @@ void drawrec(cell *c, const transmatrix& V) {
draw_li.relative = at;
draw_li.total_dir = 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++) {
cell *c2 = c->move(i);
@ -765,7 +760,7 @@ void drawrec(cell *c, const transmatrix& V) {
draw_li.relative = loc(0,0);
draw_li.total_dir = 0;
draw_li.last_dir = -1;
if(dodrawcell(c))
if(do_draw(c, V))
drawcell(c, V, 0, false);
for(int i=0; i<c->type; 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) {
// calc_relative_matrix(cwt.c, hs.at);
// calc_relative_matrix(cwt.c, hs.at);
cell *c = hs.at->c7;
transmatrix V10;
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) {
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];
transmatrix V0 = actualV(hs, V1);
auto& vc = irr::cells_of_heptagon[hi.base.at];
for(int i=0; i<isize(vc); i++)
if(dodrawcell(hi.subcells[i]) && in_qrange(V0 * irr::cells[vc[i]].pusher))
for(int i=0; i<isize(vc); i++) {
cell *c = hi.subcells[i];
transmatrix V1 = V0 * irr::cells[vc[i]].pusher;
if(do_draw(c, V1))
draw = true,
drawcell(hi.subcells[i], V0 * irr::cells[vc[i]].pusher, 0, false);
}
}
else {
if(dodrawcell(c)) {
if(do_draw(c, V1)) {
transmatrix V2 = actualV(hs, V1);
if(in_qrange(V2))
drawcell(c, V2, 0, hs.mirrored);
else draw = false;
drawcell(c, V2, 0, hs.mirrored);
draw = true;
}
if(BITRUNCATED) for(int d=0; d<S7; d++) {
int ds = hs.at->c.fix(hs.spin + d);
// 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];
if(in_qrange(V2))
drawcell(c->move(ds), V2, 0, hs.mirrored ^ c->c.mirror(ds));
if(do_draw(c->move(ds), V2))
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(i < 30 || in_smart_range(Mat)) {
if(vid.use_smart_range == 2) setdist(cw.at, 7, cw.at);
if(dodrawcell(cw.at))
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
if(do_draw(cw.at, Mat)) {
drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored);
for(int x=-1; x<=+1; x++)
for(int y=-1; y<=+1; 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;
}
}