general non-special-floor cleanup; standard and full floors are now perfect in gp

This commit is contained in:
Zeno Rogue 2018-05-04 02:46:44 +02:00
parent 4aa73c560c
commit c721851db1
6 changed files with 134 additions and 61 deletions

View File

@ -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<pair<int, int>, loc> center_locs;

View File

@ -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<int> 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<const hpcshape*> ds(qfi.shape, &shCircleFloor);
dynamicval<bool> db(qfi.special, true);
for(int z=1; z<layers; z++) {
double zg = zgrad0(-geom3::lake_top, geom3::actual_wall_height(), z, layers);
warpfloor(c, xyzscale(V, zg*(layers-z)/layers, zg),

View File

@ -3233,7 +3233,6 @@ void queuepolyat(const transmatrix& V, const hpcshape& h, int col, int prio);
void queuetable(const transmatrix& V, const vector<glvertex>& f, int cnt, int linecol, int fillcol, int prio);
struct qfloorinfo {
bool special;
transmatrix spin;
const hpcshape *shape;
textureinfo *tinf;

View File

@ -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; i<c->type; 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);
}
}

View File

@ -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<hyperpoint> 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<qhpc; i++)
ourshape.push_back(make_array<GLfloat>(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; i<last->e-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<int,3> 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; c<cor; c++) {
bshape(shFullFloorSideGP[k][x&31][y&31][d][c], PPR_FLOOR);
hpcpush(get_corner_position(li, c));
hpcpush(get_corner_position(li, c+1));
chasmifyPoly(dlow, dhi, k);
bshape(shFloorSideGP[k][x&31][y&31][d][c], PPR_FLOOR);
hpcpush(get_corner_position(li, c, 3.3));
hpcpush(get_corner_position(li, c+1, 3.3));
chasmifyPoly(dlow, dhi, k);
}
}
}
}
for(int d=0; d<2; d++) {
@ -1893,6 +1954,7 @@ void buildpolys() {
bshape(shBigTriangle, PPR_FLOOR);
for(int t=0; t<=S3; t++) hpcpush(ddi(t*S28, -triangleside) * C0);
last->flags |= 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<USERSHAPEGROUPS; i++) for(int j=0; j<USERSHAPEIDS; j++) {
usershape *us = usershapes[i][j];
@ -2413,6 +2475,7 @@ void buildpolys() {
}
static int qhpc0;
int qhpc = size(hpc);
if(qhpc != qhpc0 && debug_geometry)
printf("qhpc = %d (%d+%d)\n", qhpc0 = qhpc, prehpc, qhpc-prehpc);
@ -2505,23 +2568,15 @@ qfloorinfo qfi_dc;
int chasmg;
bool isSpecial(const hpcshape &h) {
return
&h != &shFloor[0] &&
&h != &shFloor[1] &&
&h != &shTriheptaFloor[0] &&
&h != &shTriheptaFloor[1] &&
&h != &shTriheptaFloor[13] &&
&h != &shBigTriangle;
}
const hpcshape& getSeabed(const hpcshape& c) {
if(&c == &shCloudFloor[2]) return shCloudSeabed[2];
if(&c == &shCaveFloor[2]) return shCaveSeabed[2];
if(&c == &shCaveFloor[3]) return shCaveSeabed[3];
if(nonbitrunc || euclid || sphere) return c;
if(&c == &shFloor[0]) return shFullFloor[0];
if(&c == &shFloor[1]) return shFullFloor[1];
if(&c >= &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]

View File

@ -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;