From 1c07230f8824bd4a2bf49cfeb03a7bc19aa732d7 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 4 May 2018 12:20:50 +0200 Subject: [PATCH] on-demand building of plainshapes --- goldberg.cpp | 2 + graph.cpp | 6 +-- hyper.h | 10 ++++ polygons.cpp | 136 +++++++++++++++++++++++++++++++-------------------- 4 files changed, 98 insertions(+), 56 deletions(-) diff --git a/goldberg.cpp b/goldberg.cpp index 63e8b06d..b092e13a 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -481,6 +481,8 @@ namespace gp { if(base_distlimit > 30) base_distlimit = 30; prepare_matrices(); + if(debug_geometry) + printf("scale = " LDF "\n", scale); } else { scale = 1; diff --git a/graph.cpp b/graph.cpp index 86be1687..48266c77 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3218,11 +3218,11 @@ void placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, bool warp, flagtype f = qfi.shape->flags; - if(gp::on && !mirr) { + if((f & POLY_GP) && !mirr) { if(f & POLY_FULL) - queuepolyat(V, shFullFloorSideGP[sidepar][DRAW_INDICES][i], col, prio); + queuepolyat(V, gp::get_plainshape().shFullFloorSide[sidepar][i], col, prio); if(f & POLY_PLAIN) - queuepolyat(V, shFloorSideGP[sidepar][DRAW_INDICES][i], col, prio); + queuepolyat(V, gp::get_plainshape().shFloorSide[sidepar][i], col, prio); return; } diff --git a/hyper.h b/hyper.h index 67a0254b..9cd693e2 100644 --- a/hyper.h +++ b/hyper.h @@ -3349,3 +3349,13 @@ namespace fieldpattern { bool incompatible(eLand l1, eLand l2); eOrbLandRelation getOLR(eItem it, eLand l); +struct plainshape; +void clear_plainshape(plainshape& gsh); +void build_plainshape(plainshape& gsh, gp::local_info& li); + +namespace gp { + void clear_plainshapes(); + plainshape& get_plainshape(); + } + +extern bool debug_geometry; diff --git a/polygons.cpp b/polygons.cpp index 549d0e5d..382f345f 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -28,7 +28,8 @@ static const int POLY_PLAIN = 256; static const int POLY_FULL = 512; // floor shapes which have their shadows, or can use shFloorShadow static const int POLY_HASSHADOW = 1024; - +// Goldberg shapes +static const int POLY_GP = 2048; vector hpc; @@ -122,6 +123,15 @@ void initPolyForGL() { glhr::store_in_buffer(ourshape); } + +void extra_vertices() { + while(size(ourshape) < size(hpc)) + ourshape.push_back(glhr::pointtogl(hpc[size(ourshape)])); + glhr::store_in_buffer(ourshape); + glhr::current_vertices = NULL; + prehpc = size(hpc); + } + #endif #if CAP_POLY @@ -1053,6 +1063,11 @@ void drawqueue() { } } +struct plainshape { + bool active; + hpcshape shFloor, shFullFloor, shFloorSide[SIDEPARS][8], shFullFloorSide[SIDEPARS][8]; + }; + hpcshape shFloorSide[SIDEPARS][2], shSemiFloorSide[SIDEPARS], shTriheptaSide[SIDEPARS][2], shTriheptaSideGP[SIDEPARS][2], @@ -1158,13 +1173,8 @@ hpcshape shAsymmetric, - shDodeca, + shDodeca; - shFullFloorGP[32][32][6], - shFullFloorSideGP[SIDEPARS][32][32][6][8], - shFloorGP[32][32][6], - shFloorSideGP[SIDEPARS][32][32][6][8]; - ld tentacle_length; #define USERLAYERS 32 @@ -1368,10 +1378,13 @@ template ld grot(bool geometry, ld factor, T... t) { else return grot(t...); } +ld dlow_table[SIDEPARS], dhi_table[SIDEPARS]; + void buildpolys() { symmetriesAt.clear(); geom3::compute(); + gp::clear_plainshapes(); DEBB(DF_INIT, (debugfile,"buildpolys\n")); // printf("crossf = %f euclid = %d sphere = %d\n", float(crossf), euclid, sphere); @@ -1490,25 +1503,6 @@ void buildpolys() { last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW; } - if(gp::on) { - for(int x=-16; x<16; x++) - for(int y=-16; y<16; y++) - for(int d=0; d<6; d++) { - bshape(shFullFloorGP[x&31][y&31][d], PPR_FLOOR); - int cor = (x||y) ? 6 : S7; - - gp::local_info li; li.last_dir = (x||y) ? 0 : -1; li.relative = gp::loc(x, y); li.total_dir = d; - for(int j=0; j<=cor; j++) - hpcpush(get_corner_position(li, j)); - last->flags |= POLY_HASWALLS | POLY_FULL; - - bshape(shFloorGP[x&31][y&31][d], PPR_FLOOR); - for(int j=0; j<=cor; j++) - hpcpush(get_corner_position(li, j, 3.3)); - last->flags |= POLY_HASWALLS | POLY_PLAIN; - } - } - bool strict = false; if(a4 && nonbitrunc) fac94 *= 1.1; @@ -1560,6 +1554,8 @@ void buildpolys() { else if(k==SIDE_BTOI) dlow = geom3::INFDEEP, dhi = geom3::BOTTOM; else if(k==SIDE_WTS3) dlow = geom3::SLEV[3], dhi = geom3::WALL; else dlow = geom3::SLEV[k-SIDE_SLEV], dhi = geom3::SLEV[k-SIDE_SLEV+1]; + dlow_table[k] = dlow; + dhi_table[k] = dhi; validsidepar[k] = (dlow > 0 && dhi > 0) || (dlow < 0 && dhi < 0); @@ -1609,28 +1605,7 @@ void buildpolys() { bshape(shBigTriSide[k][0], PPR_LAKEWALL); for(int t=0; t<=1; t++) hpcpush(ddi(t*S28-S14, triangleside) * C0); - chasmifyPoly(dlow, dhi, k); - - if(gp::on) { - for(int x=-16; x<16; x++) - for(int y=-16; y<16; y++) - for(int d=0; d<6; d++) { - int cor = (x||y) ? 6 : S7; - gp::local_info li; li.last_dir = (x||y) ? 0 : -1; li.relative = gp::loc(x, y); li.total_dir = d; - for(int c=0; c= &shFloorGP[0][0][0] && &c <= &shFloorGP[32][0][0]) - return *(&c - &shFloorGP[0][0][0] + &shFullFloorGP[0][0][0]); + if(c.flags & POLY_GP) if(c.flags & POLY_PLAIN) + return gp::get_plainshape().shFullFloor; if(nonbitrunc || euclid || sphere) return c; if(&c == &shCaveFloor[0]) return shCaveSeabed[0]; if(&c == &shCaveFloor[1]) return shCaveSeabed[1]; @@ -3676,6 +3651,62 @@ NEWSHAPE, 384, 1, 2, 0.146470,0.021791, 0.134179,0.071381, 0.089857,0.116839, 0. NEWSHAPE }; +namespace gp { + plainshape psh[32][32][8]; + extern gp::local_info draw_li; + + void clear_plainshapes() { + for(int i=0; i<32; i++) + for(int j=0; j<32; j++) + for(int k=0; k<8; k++) + clear_plainshape(psh[i][j][k]); + } + + plainshape& get_plainshape() { + auto& pshape = psh[draw_li.relative.first&31][draw_li.relative.second&31][fix6(draw_li.total_dir)]; + if(!pshape.active) build_plainshape(pshape, draw_li); + return pshape; + } + } + +void clear_plainshape(plainshape& gsh) { + gsh.active = false; + } + +void build_plainshape(plainshape& gsh, gp::local_info& li) { + + gsh.active = true; + bshape(gsh.shFullFloor, PPR_FLOOR); + bool master = !(li.relative.first||li.relative.second); + int cor = master ? S7 : 6; + printf("generating plainshape %d,%d,%d (%d)\n", li.relative.first, li.relative.second, li.total_dir, cor); + if(master) li.last_dir = -1; + + for(int j=0; j<=cor; j++) + hpcpush(get_corner_position(li, j)); + last->flags |= POLY_HASWALLS | POLY_FULL | POLY_GP; + + bshape(gsh.shFloor, PPR_FLOOR); + for(int j=0; j<=cor; j++) + hpcpush(get_corner_position(li, j, 3.3)); + last->flags |= POLY_HASWALLS | POLY_PLAIN | POLY_GP; + + for(int k=0; k