diff --git a/goldberg.cpp b/goldberg.cpp index df3fdd8f..63e8b06d 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -445,9 +445,8 @@ namespace gp { } } } - - hyperpoint get_corner_position(cell *c, int cid, ld cf = 3) { - auto li = get_local_info(c); + + hyperpoint get_corner_position(const local_info& li, int cid, ld cf = 3) { int i = li.last_dir; if(i == -1) return atz(dir_matrix(cid), corners, li.relative, 0, cf); @@ -456,6 +455,10 @@ namespace gp { return inverse(cellmatrix) * atz(dir_matrix(i), corners, li.relative, fix6(cid + li.total_dir), cf); } } + + hyperpoint get_corner_position(cell *c, int cid, ld cf = 3) { + return get_corner_position(get_local_info(c), cid, cf); + } map, loc> center_locs; diff --git a/graph.cpp b/graph.cpp index 3bead6c5..e4e3e06a 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3075,7 +3075,7 @@ void floorShadow(cell *c, const transmatrix& V, int col, bool warp) { return; // shadows break the depth testing if(shmup::on || nbtnice) warp = false; dynamicval p(poly_outline, OUTLINE_TRANS); - if(wmescher && qfi.special) { + if(!(qfi.shape->flags & POLY_HASSHADOW)) { queuepolyat(V * qfi.spin * shadowmulmatrix, *qfi.shape, col, PPR_WALLSHADOW); } else if(warp) { @@ -3120,9 +3120,8 @@ void plainfloor(cell *c, bool warp, const transmatrix &V, int col, int prio) { else queuepolyat(V, shBigTriangle, col, prio); } - else { - queuepolyat(V, shFloor[ctof(c)], col, prio); - } + else + queuepolyat(V, *qfi.shape, col, prio); } void qfloor_eswap(cell *c, const transmatrix& V, const hpcshape& sh, int col); @@ -3134,9 +3133,8 @@ void qplainfloor(cell *c, bool warp, const transmatrix &V, int col) { } else if(is_nice_dual(c)) qfloor_eswap(c, V, shBigTriangle, col); - else { + else qfloor(c, V, shFloor[ctof(c)], col); - } } int wavephase; @@ -3150,17 +3148,15 @@ void warpfloor(cell *c, const transmatrix& V, int col, int prio, bool warp) { } else #endif - if(wmescher && qfi.special) - queuepolyat(V*qfi.spin, *qfi.shape, col, prio); - else plainfloor(c, warp, V, col, prio); + plainfloor(c, warp, V, col, prio); } #define placeSidewallX(a,b,c,d,e,f,g) \ - { if((wmescher && qfi.special) || !validsidepar[c]) { \ + { if(!(qfi.shape->flags & POLY_HASWALLS) || !validsidepar[c]) { \ escherSidewall(a,c,d,g); break; } \ else placeSidewall(a,b,c,d,e,f,g); } #define placeSidewallXB(a,b,c,d,e,f,g, Break) \ - { if((wmescher && qfi.shape) || !validsidepar[c]) { \ + { if(!(qfi.shape->flags & POLY_HASWALLS) || !validsidepar[c]) { \ escherSidewall(a,c,d,g); Break; break; } \ else placeSidewall(a,b,c,d,e,f,g); } @@ -3214,6 +3210,16 @@ void placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, bool warp, else if(sidepar == SIDE_BTOI) prio = PPR_BELOWBOTTOM; else prio = PPR_REDWALL-2+4*(sidepar-SIDE_SLEV); + flagtype f = qfi.shape->flags; + + if(gp::on && !mirr) { + if(f & POLY_FULL) + queuepolyat(V, shFullFloorSideGP[sidepar][DRAW_INDICES][i], col, prio); + if(f & POLY_PLAIN) + queuepolyat(V, shFloorSideGP[sidepar][DRAW_INDICES][i], col, prio); + return; + } + transmatrix V2 = V * ddspin(c, i); // if(sphere && vid.alpha <= 1 && tC0(V2 * xpush(cellgfxdist(c, i)/2))[2] < -.5) return; @@ -3226,7 +3232,7 @@ void placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, bool warp, // prio += c->cpdist - c->mov[i]->cpdist; queuepolyat(V2, - (qfi.tinf?shFullFloorSide:mirr?shMFloorSide:warp?(pseudohept(c)&&!ishept(c)?shTriheptaSideGP:shTriheptaSide):is_nice_dual(c)?shBigTriSide:shFloorSide)[sidepar][ctof(c)], col, prio); + ((f & POLY_FULL)?shFullFloorSide:mirr?shMFloorSide:warp?(pseudohept(c)&&!ishept(c)?shTriheptaSideGP:shTriheptaSide):is_nice_dual(c)?shBigTriSide:shFloorSide)[sidepar][ctof(c)], col, prio); } bool openorsafe(cell *c) { @@ -3516,7 +3522,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } #endif - qfi.shape = NULL; qfi.special = false; + qfi.shape = &shFloor[ctof(c)]; ivoryz = isGravityLand(c->land); bool orig = false; @@ -3931,13 +3937,13 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { transmatrix V2 = V * qfi.spin; if(wmspatial && wmescher) { - qfi.shape = &shSemiFeatherFloor[0]; qfi.special = true; + qfi.shape = &shSemiFeatherFloor[0]; int dk = 1; int vcol = winf[waVinePlant].color; warpfloor(c, mscale(V, geom3::WALL), darkena(vcol, dk, 0xFF), PPR_WALL3A, false); escherSidewall(c, SIDE_WALL, V, darkena(gradient(0, vcol, 0, .8, 1), dk, 0xFF)); qfloor(c, V2, shSemiFeatherFloor[1], darkena(fcol, dk, 0xFF)); - qfi.shape = &shFeatherFloor[0]; qfi.special = true; + qfi.shape = &shFeatherFloor[0]; } else if(wmspatial) { @@ -4013,8 +4019,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } else if(wmplain) { - if(wmspatial && highwall(c)) ; - else qfloor(c, Vf, PLAINFLOOR, darkena(fcol, fd, 0xFF)); + if(wmspatial && highwall(c)) + qfloor_virtual(c, Vf, PLAINFLOOR); + else + qfloor(c, Vf, PLAINFLOOR, darkena(fcol, fd, 0xFF)); } else if(randomPatternsMode && c->land != laBarrier && !isWarped(c->land)) { @@ -4522,7 +4530,6 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { if(c->land == laOceanWall && wmescher && wmspatial) { const int layers = 2 << detaillevel; dynamicval ds(qfi.shape, &shCircleFloor); - dynamicval db(qfi.special, true); for(int z=1; z& f, int cnt, int linecol, int fillcol, int prio); struct qfloorinfo { - bool special; transmatrix spin; const hpcshape *shape; textureinfo *tinf; diff --git a/hypgraph.cpp b/hypgraph.cpp index 09ded5dd..8a6e536c 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -519,7 +519,9 @@ void drawrec(cell *c, const transmatrix& V) { 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(maindir != li.last_dir) printf("ld %d/%d\n", maindir, li.last_dir); */ - transmatrix V1 = V * Tf[maindir][at.first&31][at.second&31][fix6(dir)]; + draw_li.relative = at; + draw_li.total_dir = fix6(dir); + transmatrix V1 = V * Tf[draw_li.last_dir][at.first&31][at.second&31][fix6(dir)]; if(in_qrange(V1)) drawcell(c, V1, 0, false); } @@ -533,6 +535,8 @@ void drawrec(cell *c, const transmatrix& V) { } void drawrec(cell *c, const transmatrix& V) { + draw_li.relative = loc(0,0); + draw_li.total_dir = 0; if(dodrawcell(c)) drawcell(c, V, 0, false); for(int i=0; itype; i++) { @@ -540,6 +544,7 @@ void drawrec(cell *c, const transmatrix& V) { if(!c2) continue; if(c2->mov[0] != c) continue; if(c2 == c2->master->c7) continue; + draw_li.last_dir = i; drawrec(c2, V, gp::loc(1,0), 3, i); } } diff --git a/polygons.cpp b/polygons.cpp index 233cd2c6..231f4fe4 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -20,11 +20,19 @@ static const int POLY_TOOLARGE = 32; // on the sphere (orthogonal projection), do not draw without any points in front static const int POLY_INFRONT = 64; -#define QHPC 512000 +// floor shapes which have their sidewalls +static const int POLY_HASWALLS = 128; +// plain floors +static const int POLY_PLAIN = 256; +// full floors +static const int POLY_FULL = 512; +// floor shapes which have their shadows, or can use shFloorShadow +static const int POLY_HASSHADOW = 1024; -int qhpc, prehpc; -hyperpoint hpc[QHPC]; +vector hpc; + +int prehpc; bool first; @@ -55,14 +63,14 @@ bool ptdsort(const polytodraw& p1, const polytodraw& p2) { void hpcpush(hyperpoint h) { if(sphere) h = mid(h,h); - if(/*vid.usingGL && */!first && intval(hpc[qhpc-1], h) > (sphere ? (ISMOBWEB ? .04 : .0001) : 0.25)) { - hyperpoint md = mid(hpc[qhpc-1], h); + if(/*vid.usingGL && */!first && intval(hpc.back(), h) > (sphere ? (ISMOBWEB ? .04 : .0001) : 0.25)) { + hyperpoint md = mid(hpc.back(), h); hpcpush(md); hpcpush(h); return; } first = false; - hpc[qhpc++] = h; + hpc.push_back(h); } #define SIDE_SLEV 0 @@ -76,15 +84,15 @@ void hpcpush(hyperpoint h) { bool validsidepar[SIDEPARS]; void chasmifyPoly(double fac, double fac2, int k) { - for(int i=qhpc-1; i >= last->s; i--) { + for(int i=size(hpc)-1; i >= last->s; i--) { hyperpoint H; for(int j=0; j<3; j++) { H[j] = hpc[i][j] * fac; hpc[i][j] *= fac2; } - hpc[qhpc++] = H; + hpc.push_back(H); } - hpc[qhpc++] = hpc[last->s]; + hpc.push_back(hpc[last->s]); last->flags |= POLY_ISSIDE; } @@ -109,8 +117,8 @@ void initPolyForGL() { ourshape.clear(); - for(int i=0; i(hpc[i][0], hpc[i][1], hpc[i][2])); + for(auto& h: hpc) + ourshape.push_back(glhr::pointtogl(h)); glhr::store_in_buffer(ourshape); } @@ -1150,7 +1158,12 @@ hpcshape shAsymmetric, - shDodeca; + shDodeca, + + shFullFloorGP[32][32][6], + shFullFloorSideGP[SIDEPARS][32][32][6][8], + shFloorGP[32][32][6], + shFloorSideGP[SIDEPARS][32][32][6][8]; #define USERLAYERS 32 #define USERSHAPEGROUPS 4 @@ -1200,7 +1213,7 @@ hyperpoint turtlevertex(int u, double x, double y, double z) { } void finishshape() { - last->e = qhpc; + last->e = size(hpc); double area = 0; for(int i=last->s; ie-1; i++) area += hpc[i][0] * hpc[i+1][1] - hpc[i+1][0] * hpc[i][1]; @@ -1214,7 +1227,7 @@ void finishshape() { void bshape(hpcshape& sh, int p) { if(last) finishshape(); last = &sh; - last->s = qhpc, last->prio = p; + last->s = size(hpc), last->prio = p; last->flags = 0; first = true; } @@ -1232,7 +1245,7 @@ void bshape(hpcshape& sh, int p, double shzoom, int shapeid, double bonus = 0, f while(polydata[whereis] != NEWSHAPE || polydata[whereis+1] != shapeid) whereis++; int rots = polydata[whereis+2]; int sym = polydata[whereis+3]; array arr; - arr[0] = qhpc; arr[1] = rots; arr[2] = sym; + arr[0] = size(hpc); arr[1] = rots; arr[2] = sym; symmetriesAt.emplace_back(arr); whereis += 4; int qty = 0; @@ -1298,7 +1311,7 @@ void bshape_goldberg(hpcshape sh[3], int p, double shzoom, int shapeid, double b } void copyshape(hpcshape& sh, hpcshape& orig, int p) { - if(last) last->e = qhpc; + if(last) last->e = size(hpc); sh = orig; sh.prio = p; } @@ -1360,7 +1373,7 @@ void buildpolys() { DEBB(DF_INIT, (debugfile,"buildpolys\n")); // printf("crossf = %f euclid = %d sphere = %d\n", float(crossf), euclid, sphere); - qhpc = 0; + hpc.clear(); bshape(shMovestar, PPR_MOVESTAR); for(int i=0; i<=8; i++) { @@ -1422,9 +1435,11 @@ void buildpolys() { bshape(shTriheptaFloor[0], PPR_FLOOR); for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28 + tshift0, trihepta0) * C0); + last->flags |= POLY_HASWALLS | POLY_HASSHADOW; bshape(shTriheptaFloor[1], PPR_FLOOR); for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12 + tshift1, trihepta1) * C0); + last->flags |= POLY_HASWALLS | POLY_HASSHADOW; bshape(shTriheptaFloorShadow[0], PPR_FLOOR); for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28 + tshift0, trihepta0*SHADMUL) * C0); @@ -1434,6 +1449,7 @@ void buildpolys() { bshape(shTriheptaFloor[13], PPR_FLOOR); for(int t=0; t<=S6; t++) hpcpush(ddi(t*S14 + S7, trihepta0*1.6) * C0); + last->flags |= POLY_HASWALLS | POLY_HASSHADOW; bshape(shTriheptaFloorShadow[2], PPR_FLOOR); for(int t=0; t<=S6; t++) hpcpush(ddi(t*S14 + S7, trihepta0*SHADMUL*1.6) * C0); @@ -1460,14 +1476,36 @@ void buildpolys() { x *= bscale6; x *= gp::scale; if(gp::scale != 1) x /= 2; - for(int t=0; t<=S6; t++) { hpcpush(C0); if(t) hpcpush(ddi(S7 + t*S14, x) * C0); } + for(int t=0; t<=S6; t++) { hpcpush(C0); if(t) hpcpush(ddi(S7 + t*S14, x) * C0); + last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW; + } x = rhexf; x *= bscale7; // x *= gp::scale; bshape(shFullCross[1], PPR_FLOOR); for(int t=0; t<=S7; t++) { hpcpush(C0); if(t) hpcpush(ddi(t*S12+td, x) * C0); } + 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; @@ -1491,12 +1529,14 @@ void buildpolys() { bshape(shFloor[0], PPR_FLOOR); for(int t=0; t<=S6; t++) hpcpush(ddi(S7 + t*S14, floorrad0) * C0); + last->flags |= POLY_HASWALLS | POLY_PLAIN | POLY_HASSHADOW; bshape(shCircleFloor, PPR_FLOOR); for(int t=0; t<=S84; t+=2) hpcpush(ddi(t, shexf*.7*spzoom) * C0); bshape(shFloor[1], PPR_FLOOR); for(int t=0; t<=S7; t++) hpcpush(ddi(t*S12 + td, floorrad1) * C0); + last->flags |= POLY_HASWALLS | POLY_PLAIN | POLY_HASSHADOW; for(int i=0; i<3; i++) for(int j=0; j<3; j++) shadowmulmatrix[i][j] = i==2&&j==2 ? 1: @@ -1568,6 +1608,27 @@ 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; cflags |= POLY_HASWALLS | POLY_HASSHADOW; bshape(shBigTriShadow, PPR_FLOOR); for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28 + S14 + (S3==4?S14:0), triangleside*SHADMUL) * C0); @@ -1920,7 +1982,7 @@ void buildpolys() { bshape(shParticle[i], PPR_PARTICLE); for(int t=0; t<6; t++) hpcpush(spin(M_PI * t * 2 / 6 + M_PI * 2/6 * hrand(100) / 150.) * xpush((0.03 + hrand(100) * 0.0003) * goldbf) * C0); - hpc[qhpc++] = hpc[last->s]; + hpc.push_back(hpc[last->s]); } // hand-drawn shapes @@ -2399,8 +2461,8 @@ void buildpolys() { bshapeend(); - prehpc = qhpc; - DEBB(DF_INIT, (debugfile,"hpc = %d\n", qhpc)); + prehpc = size(hpc); + DEBB(DF_INIT, (debugfile,"hpc = %d\n", prehpc)); for(int i=0; i= &shFloorGP[0][0][0] && &c <= &shFloorGP[32][0][0]) + return *(&c - &shFloorGP[0][0][0] + &shFullFloorGP[0][0][0]); + if(nonbitrunc || euclid || sphere) return c; if(&c == &shCaveFloor[0]) return shCaveSeabed[0]; if(&c == &shCaveFloor[1]) return shCaveSeabed[1]; if(&c == &shCloudFloor[0]) return shCloudSeabed[0]; @@ -2542,14 +2597,17 @@ void qfloor0(cell *c, const transmatrix& V, const hpcshape& h, int col) { void qfloor(cell *c, const transmatrix& V, const hpcshape& h, int col) { qfloor0(c, V, h, col); - qfi.special = isSpecial(h); + qfi.shape = &h, qfi.spin = Id; + qfi.tinf = NULL; + } + +void qfloor_virtual(cell *c, const transmatrix& V, const hpcshape& h) { qfi.shape = &h, qfi.spin = Id; qfi.tinf = NULL; } void qfloor(cell *c, const transmatrix& V, const transmatrix& Vspin, const hpcshape& h, int col) { qfloor0(c, V*Vspin, h, col); - qfi.special = isSpecial(h); qfi.shape = &h, qfi.spin = Vspin; qfi.tinf = NULL; } @@ -3628,8 +3686,9 @@ NEWSHAPE #define ECT3 ((euclid&&!a4)?3:xct6) // no eswap -#define PLAINFLOOR shFloor[ct6] -#define FULLFLOOR shFullFloor[ct6] +#define PLAINFLOOR (gp::on ? shFloorGP[DRAW_INDICES] : shFloor[ct6]) +#define DRAW_INDICES gp::draw_li.relative.first&31][gp::draw_li.relative.second&31][fix6(gp::draw_li.total_dir) +#define FULLFLOOR (gp::on ? shFullFloorGP[DRAW_INDICES] : shFullFloor[ct6]) #define CAVEFLOOR shCaveFloor[ECT3] #define OVERFLOOR shOverFloor[euclid&&a4&&nonbitrunc?2:ECT] #define CLOUDFLOOR shCloudFloor[ECT] diff --git a/textures.cpp b/textures.cpp index 7147332c..b88b8772 100644 --- a/textures.cpp +++ b/textures.cpp @@ -349,8 +349,8 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) { int n = mi.vertices.size(); - qfi.special = false; - qfi.shape = &shFullFloor[ctof(c)]; + int ct6 = ctof(c); + qfi.shape = &FULLFLOOR; qfi.tinf = &mi; if(chasmg == 2) return false;