2019-08-10 11:43:24 +00:00
|
|
|
// Hyperbolic Rogue - Floor Shapes
|
|
|
|
|
|
|
|
// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details
|
|
|
|
|
|
|
|
/** \file floorshapes.cpp
|
|
|
|
* \brief Adjusting the floor shapes to various geometries.
|
|
|
|
*/
|
|
|
|
|
2019-09-05 07:15:40 +00:00
|
|
|
#include "hyper.h"
|
2018-06-10 23:58:31 +00:00
|
|
|
namespace hr {
|
2019-02-17 18:39:44 +00:00
|
|
|
#if CAP_SHAPES
|
2019-05-26 16:04:02 +00:00
|
|
|
|
2019-08-09 23:56:00 +00:00
|
|
|
#if HDR
|
|
|
|
struct qfloorinfo {
|
|
|
|
transmatrix spin;
|
|
|
|
const struct hpcshape *shape;
|
|
|
|
floorshape *fshape;
|
|
|
|
struct textureinfo *tinf;
|
|
|
|
int usershape;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern qfloorinfo qfi;
|
|
|
|
#endif
|
|
|
|
|
2019-08-09 20:07:03 +00:00
|
|
|
EX vector<basic_textureinfo> floor_texture_vertices;
|
2019-10-26 08:32:44 +00:00
|
|
|
EX vector<glvertex> floor_texture_map;
|
2019-08-09 23:07:39 +00:00
|
|
|
EX struct renderbuffer *floor_textures;
|
2019-05-26 16:04:02 +00:00
|
|
|
|
|
|
|
void geometry_information::init_floorshapes() {
|
|
|
|
all_escher_floorshapes.clear();
|
|
|
|
all_plain_floorshapes = {
|
|
|
|
&shFloor, &shMFloor, &shMFloor2, &shMFloor3, &shMFloor4,
|
|
|
|
&shFullFloor, &shBigTriangle, &shTriheptaFloor, &shBigHepta
|
|
|
|
};
|
|
|
|
|
|
|
|
for(auto s: all_plain_floorshapes) s->is_plain = true;
|
|
|
|
|
2020-02-23 03:42:52 +00:00
|
|
|
auto init_escher = [this] (escher_floorshape& sh, int s0, int s1, int noft, int s2) {
|
2019-05-26 16:04:02 +00:00
|
|
|
sh.shapeid0 = s0;
|
|
|
|
sh.shapeid1 = s1;
|
|
|
|
sh.noftype = noft;
|
|
|
|
sh.shapeid2 = s2;
|
|
|
|
sh.scale = 1;
|
|
|
|
sh.is_plain = false;
|
|
|
|
all_escher_floorshapes.push_back(&sh);
|
|
|
|
};
|
|
|
|
|
2020-02-23 03:42:52 +00:00
|
|
|
init_escher(shStarFloor, 1, 2, 0, 0);
|
|
|
|
init_escher(shCloudFloor, 3, 4, 0, 0);
|
2019-05-26 16:04:02 +00:00
|
|
|
init_escher(shCrossFloor, 5, 6, 2, 54);
|
|
|
|
init_escher(shChargedFloor, 7, 385, 1, 10);
|
2020-02-23 03:42:52 +00:00
|
|
|
init_escher(shSStarFloor, 11, 12, 0, 0);
|
2019-05-26 16:04:02 +00:00
|
|
|
init_escher(shOverFloor, 13, 15, 1, 14);
|
|
|
|
init_escher(shTriFloor, 17, 18, 0, 385);
|
|
|
|
init_escher(shFeatherFloor, 19, 21, 1, 20);
|
|
|
|
init_escher(shBarrowFloor, 23, 24, 1, 25);
|
|
|
|
init_escher(shNewFloor, 26, 27, 2, 54);
|
2020-02-23 03:42:52 +00:00
|
|
|
init_escher(shTrollFloor, 28, 29, 0, 0);
|
2019-05-26 16:04:02 +00:00
|
|
|
init_escher(shButterflyFloor, 325, 326, 1, 178);
|
|
|
|
init_escher(shLavaFloor, 359, 360, 1, 178);
|
|
|
|
init_escher(shLavaSeabed, 386, 387, 1, 178);
|
2020-02-23 03:42:52 +00:00
|
|
|
init_escher(shSeabed, 334, 335, 0, 0);
|
|
|
|
init_escher(shCloudSeabed, 336, 337, 0, 0);
|
2019-05-26 16:04:02 +00:00
|
|
|
init_escher(shCaveSeabed, 338, 339, 2, 54);
|
|
|
|
init_escher(shPalaceFloor, 45, 46, 0, 385);
|
|
|
|
init_escher(shDemonFloor, 51, 50, 1, 178);
|
|
|
|
init_escher(shCaveFloor, 52, 53, 2, 54);
|
|
|
|
init_escher(shDesertFloor, 55, 56, 0, 4);
|
|
|
|
init_escher(shPowerFloor, 57, 58, 0, 12); /* dragon */
|
|
|
|
init_escher(shRoseFloor, 174, 175, 1, 173);
|
|
|
|
init_escher(shSwitchFloor, 377, 378, 1, 379);
|
|
|
|
init_escher(shTurtleFloor, 176, 177, 1, 178);
|
|
|
|
for(int i: {0,1,2})
|
2020-02-23 03:42:52 +00:00
|
|
|
init_escher(shRedRockFloor[i], 55, 56, 0, 0);
|
2019-05-26 16:04:02 +00:00
|
|
|
init_escher(shDragonFloor, 181, 182, 2, 183); /* dragon */
|
|
|
|
|
|
|
|
int ids = 0;
|
|
|
|
for(auto sh: all_plain_floorshapes) sh->id = ids++;
|
|
|
|
for(auto sh: all_escher_floorshapes) sh->id = ids++;
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2020-01-18 15:03:32 +00:00
|
|
|
typedef pair<transmatrix, vector<transmatrix>> matrixitem;
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
struct mesher {
|
|
|
|
eGeometry g;
|
|
|
|
int sym;
|
|
|
|
ld bspi;
|
|
|
|
hyperpoint lcorner, rcorner, mfar[2], vfar[4];
|
|
|
|
};
|
|
|
|
|
|
|
|
mesher msh(eGeometry g, int sym, ld main, ld v0, ld v1, ld bspi, ld scale) {
|
|
|
|
main *= scale; v0 *= scale; v1 *= scale;
|
|
|
|
mesher m;
|
|
|
|
m.sym = sym;
|
|
|
|
m.bspi = bspi;
|
|
|
|
dynamicval<eGeometry> dg(geometry, g);
|
|
|
|
|
2018-08-19 14:28:36 +00:00
|
|
|
hyperpoint rot = xpush(v0) * xspinpush0(M_PI - M_PI/sym, main);
|
|
|
|
hyperpoint bnlfar = xpush(v0) * spin(M_PI) * rspintox(rot) * rspintox(rot) * rspintox(rot) * xpush0(hdist0(rot));
|
|
|
|
hyperpoint bnrfar = xpush(v0) * spin(M_PI) * spintox(rot) * spintox(rot) * spintox(rot) * xpush0(hdist0(rot));
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-19 13:52:39 +00:00
|
|
|
m.lcorner = xspinpush0 (bspi-M_PI/sym, main);
|
|
|
|
m.rcorner = xspinpush0 (bspi+M_PI/sym, main);
|
|
|
|
m.mfar[0] = xspinpush0 (bspi, v0);
|
|
|
|
m.mfar[1] = xspinpush0 (bspi, v1);
|
2018-05-07 18:13:56 +00:00
|
|
|
m.vfar[0] = spin(bspi) * bnlfar;
|
|
|
|
m.vfar[2] = spin(bspi) * bnrfar;
|
|
|
|
m.vfar[1] = spin(-2*M_PI/sym) * m.vfar[2];
|
|
|
|
m.vfar[3] = spin(+2*M_PI/sym) * m.vfar[0];
|
|
|
|
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct matrixlist {
|
|
|
|
mesher o, n;
|
|
|
|
vector<matrixitem> v;
|
|
|
|
};
|
|
|
|
|
|
|
|
matrixitem genitem(const transmatrix& m1, const transmatrix& m2, int nsym) {
|
|
|
|
matrixitem mi;
|
|
|
|
mi.first = m1;
|
2020-01-18 15:03:32 +00:00
|
|
|
mi.second.resize(nsym);
|
2018-05-07 18:13:56 +00:00
|
|
|
for(int i=0; i<nsym; i++)
|
|
|
|
mi.second[i] = spin(2*M_PI*i/nsym) * m2;
|
|
|
|
return mi;
|
|
|
|
}
|
|
|
|
|
2019-10-10 11:11:14 +00:00
|
|
|
bool do_kleinize() { return S3 >= OINF; }
|
|
|
|
|
2019-10-22 10:05:47 +00:00
|
|
|
EX hyperpoint kleinize(hyperpoint h) {
|
|
|
|
if(GDIM == 2) return point3(h[0]/h[2], h[1]/h[2], 1);
|
|
|
|
else return point31(h[0]/h[3], h[1]/h[3], h[2]/h[3]);
|
|
|
|
}
|
2019-10-10 11:11:14 +00:00
|
|
|
|
2018-05-07 18:13:56 +00:00
|
|
|
void addmatrix(matrixlist& matrices, hyperpoint o0, hyperpoint o1, hyperpoint o2, hyperpoint n0, hyperpoint n1, hyperpoint n2, int d, int osym, int nsym) {
|
2019-10-10 11:11:14 +00:00
|
|
|
if(do_kleinize()) o0 = kleinize(o0), o1 = kleinize(o1), o2 = kleinize(o2), n0 = kleinize(n0), n1 = kleinize(n1), n2 = kleinize(n2);
|
2019-05-15 07:36:25 +00:00
|
|
|
matrices.v.push_back(genitem(inverse(spin(2*M_PI*d/osym)*build_matrix(o0, o1, o2,C02)), spin(2*M_PI*d/nsym)*build_matrix(n0, n1, n2,C02), nsym));
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
matrixlist hex_matrices, hept_matrices;
|
|
|
|
|
|
|
|
void generate_matrices(matrixlist& matrices, const mesher& o, const mesher& n) {
|
|
|
|
matrices.v.clear();
|
|
|
|
matrices.o = o;
|
|
|
|
matrices.n = n;
|
|
|
|
|
|
|
|
for(int d=0; d<o.sym; d++) {
|
|
|
|
hyperpoint center = hpxy(0,0);
|
|
|
|
int d1 = d&1;
|
|
|
|
addmatrix(matrices, center, o.lcorner, o.rcorner, center, n.lcorner, n.rcorner, d, o.sym, n.sym);
|
|
|
|
addmatrix(matrices, o.mfar[d1], o.lcorner, o.rcorner, n.mfar[d1], n.lcorner, n.rcorner, d, o.sym, n.sym);
|
|
|
|
addmatrix(matrices, o.mfar[d1], o.lcorner, o.vfar[d1], n.mfar[d1], n.lcorner, n.vfar[d1], d, o.sym, n.sym);
|
|
|
|
addmatrix(matrices, o.mfar[d1], o.rcorner, o.vfar[d1+2], n.mfar[d1], n.rcorner, n.vfar[d1+2], d, o.sym, n.sym);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int nsym0;
|
|
|
|
|
|
|
|
void generate_matrices_scale(ld scale, int noft) {
|
|
|
|
mesher ohex = msh(gNormal, 6, 0.329036, 0.566256, 0.620672, 0, 1);
|
|
|
|
mesher ohept = msh(gNormal, 7, hexf7, hcrossf7, hcrossf7, M_PI/7, 1);
|
2018-08-28 15:17:34 +00:00
|
|
|
if(!BITRUNCATED) {
|
2019-05-26 16:04:02 +00:00
|
|
|
mesher nall = msh(geometry, S7, cgi.rhexf, cgi.tessf, cgi.tessf, -M_PI, scale);
|
2018-08-20 13:24:44 +00:00
|
|
|
bool use = geosupport_football() < 2;
|
2018-05-07 18:13:56 +00:00
|
|
|
if(use && noft == 1) {
|
|
|
|
mesher opure = msh(gNormal, 7, 0.620672, 1.090550, 1.090550, M_PI/7, 1);
|
|
|
|
generate_matrices(hept_matrices, opure, nall);
|
|
|
|
}
|
|
|
|
else if(use && noft == 2) {
|
|
|
|
mesher oeuc = msh(gNormal, 6, sqrt(3)/6, .5, .5, 0, 1);
|
|
|
|
generate_matrices(hept_matrices, oeuc, nall);
|
|
|
|
}
|
|
|
|
else if(use && noft == 3) {
|
|
|
|
generate_matrices(hept_matrices, ohex, nall);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
generate_matrices(hex_matrices, ohex, nall);
|
|
|
|
generate_matrices(hept_matrices, ohept, nall);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2019-05-26 16:04:02 +00:00
|
|
|
generate_matrices(hex_matrices, ohex, msh(geometry, S6, cgi.hexvdist, cgi.hexhexdist, cgi.hcrossf, (S3-3)*M_PI/S3, scale));
|
2019-11-27 00:01:20 +00:00
|
|
|
generate_matrices(hept_matrices, ohept, msh(geometry, S7, cgi.rhexf, cgi.hcrossf, cgi.hcrossf, M_PI/S7, scale));
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void geometry_information::bshape2(hpcshape& sh, PPR prio, int shapeid, matrixlist& m) {
|
2018-05-07 18:13:56 +00:00
|
|
|
auto& matrices = m.v;
|
|
|
|
int osym = m.o.sym;
|
|
|
|
int nsym = m.n.sym;
|
|
|
|
|
|
|
|
int whereis = 0;
|
|
|
|
while(polydata[whereis] != NEWSHAPE || polydata[whereis+1] != shapeid) whereis++;
|
|
|
|
int rots = polydata[whereis+2]; int sym = polydata[whereis+3];
|
|
|
|
whereis += 4;
|
|
|
|
int qty = 0;
|
|
|
|
while(polydata[whereis + 2*qty] != NEWSHAPE) qty++;
|
|
|
|
|
|
|
|
vector<hyperpoint> lst;
|
|
|
|
for(int i=0; i<qty; i++) {
|
|
|
|
dynamicval<eGeometry> dg(geometry, gNormal);
|
|
|
|
lst.push_back(hpxy(polydata[whereis+2*i], polydata[whereis+2*i+1]));
|
|
|
|
}
|
|
|
|
if(sym == 2)
|
|
|
|
for(int i=qty-1; i>=0; i--) {
|
|
|
|
dynamicval<eGeometry> dg(geometry, gNormal);
|
|
|
|
lst.push_back(hpxy(polydata[whereis+2*i], -polydata[whereis+2*i+1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
hyperpoint lstmid = hpxyz(0,0,0);
|
2018-05-09 19:33:10 +00:00
|
|
|
for(auto pp: lst) lstmid += pp;
|
2018-05-07 18:13:56 +00:00
|
|
|
transmatrix T = spin(-m.o.bspi);
|
|
|
|
while((spin(2*M_PI / rots) * T* lstmid)[0] < (T*lstmid)[0])
|
|
|
|
T = spin(2*M_PI / rots) * T;
|
|
|
|
while((spin(-2*M_PI / rots) * T* lstmid)[0] < (T*lstmid)[0])
|
|
|
|
T = spin(-2*M_PI / rots) * T;
|
|
|
|
T = spin(m.o.bspi) * T;
|
2018-05-09 19:33:10 +00:00
|
|
|
for(auto &pp: lst) pp = T * pp;
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-05-07 19:47:10 +00:00
|
|
|
if(osym % rots && rots % osym) printf("warning: rotation oddity (shapeid %d, osym=%d rots=%d)\n", shapeid, osym, rots);
|
|
|
|
|
2018-05-07 18:13:56 +00:00
|
|
|
if(rots > osym && rots % osym == 0) {
|
|
|
|
int rep = rots / osym;
|
|
|
|
int s = lst.size();
|
|
|
|
for(int i=0; i<s*(rep-1); i++)
|
|
|
|
lst.push_back(spin(2*M_PI/rots) * lst[i]);
|
|
|
|
rots /= rep;
|
|
|
|
}
|
|
|
|
|
2018-08-28 11:45:11 +00:00
|
|
|
bshape(sh, prio);
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
for(int r=0; r<nsym; r+=osym/rots) {
|
|
|
|
for(hyperpoint h: lst) {
|
|
|
|
hyperpoint nh = h;
|
2019-10-10 11:11:14 +00:00
|
|
|
if(do_kleinize()) nh = kleinize(nh);
|
2018-05-07 18:13:56 +00:00
|
|
|
int mapped = 0;
|
|
|
|
for(auto& m: matrices) {
|
|
|
|
hyperpoint z = m.first * h;
|
2019-10-10 11:11:14 +00:00
|
|
|
if(z[0] > -1e-5 && z[1] > -1e-5 && z[2] > -1e-5) {
|
2018-05-07 18:13:56 +00:00
|
|
|
nh = m.second[r] * z, mapped++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(mapped == 0) printf("warning: not mapped (shapeid %d)\n", shapeid);
|
|
|
|
hpcpush(mid(nh, nh));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hpcpush(hpc[last->s]);
|
|
|
|
}
|
|
|
|
|
2019-11-14 21:24:36 +00:00
|
|
|
template<class T> void sizeto(T& t, int n) {
|
|
|
|
if(isize(t) <= n) t.resize(n+1);
|
|
|
|
}
|
|
|
|
|
2019-12-27 22:01:55 +00:00
|
|
|
void geometry_information::bshape_regular(floorshape &fsh, int id, int sides, ld shift, ld size, cell *c) {
|
2018-08-09 17:28:53 +00:00
|
|
|
|
2019-11-14 21:24:36 +00:00
|
|
|
sizeto(fsh.b, id);
|
|
|
|
sizeto(fsh.shadow, id);
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_BT
|
2019-12-14 11:05:01 +00:00
|
|
|
if(bt::in()) {
|
2018-08-09 17:28:53 +00:00
|
|
|
|
2019-05-09 15:20:31 +00:00
|
|
|
const int STEP = vid.texture_step;
|
2019-05-09 15:00:05 +00:00
|
|
|
|
|
|
|
for(int t=0; t<2; t++) {
|
|
|
|
|
|
|
|
if(t == 0)
|
|
|
|
bshape(fsh.b[id], fsh.prio);
|
|
|
|
if(t == 1)
|
|
|
|
bshape(fsh.shadow[id], fsh.prio);
|
|
|
|
|
|
|
|
for(int i=0; i<sides; i++) {
|
2019-12-14 11:05:01 +00:00
|
|
|
hyperpoint h0 = bt::get_corner_horo_coordinates(c, i) * size;
|
|
|
|
hyperpoint h1 = bt::get_corner_horo_coordinates(c, i+1) * size;
|
2019-05-09 15:00:05 +00:00
|
|
|
if(t) h0 *= SHADMUL, h1 *= SHADMUL;
|
|
|
|
hyperpoint hd = (h1 - h0) / STEP;
|
2020-02-07 17:33:03 +00:00
|
|
|
for(int j=0; j<STEP; j++) {
|
2019-12-14 11:05:01 +00:00
|
|
|
hpcpush(bt::get_horopoint(h0 + hd * j));
|
2020-02-07 17:33:03 +00:00
|
|
|
if(geometry == gBinary4 && among(i, 2, 4)) break;
|
|
|
|
if(geometry == gBinaryTiling && among(i, 0, 4)) break;
|
|
|
|
if(geometry == gTernary && among(i, 3, 5)) break;
|
|
|
|
}
|
2018-08-09 17:28:53 +00:00
|
|
|
}
|
2019-05-09 15:00:05 +00:00
|
|
|
|
|
|
|
hpcpush(hpc[last->s]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int k=0; k<SIDEPARS; k++) {
|
2020-03-11 08:53:53 +00:00
|
|
|
if(isize(fsh.gpside[k]) < c->type)
|
|
|
|
fsh.gpside[k].resize(c->type);
|
2019-07-22 09:21:27 +00:00
|
|
|
for(int i=0; i<c->type; i++) {
|
2019-11-14 21:24:36 +00:00
|
|
|
sizeto(fsh.gpside[k][i], id);
|
2019-05-09 15:00:05 +00:00
|
|
|
bshape(fsh.gpside[k][i][id], PPR::LAKEWALL);
|
2019-12-14 11:05:01 +00:00
|
|
|
hyperpoint h0 = bt::get_corner_horo_coordinates(c, i) * size;
|
|
|
|
hyperpoint h1 = bt::get_corner_horo_coordinates(c, i+1) * size;
|
2019-05-09 15:00:05 +00:00
|
|
|
hyperpoint hd = (h1 - h0) / STEP;
|
|
|
|
for(int j=0; j<=STEP; j++)
|
2019-12-14 11:05:01 +00:00
|
|
|
hpcpush(iddspin(c, i) * bt::get_horopoint(h0 + hd * j));
|
2019-05-09 15:00:05 +00:00
|
|
|
chasmifyPoly(dlow_table[k], dhi_table[k], k);
|
2018-08-09 17:28:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2018-08-09 17:28:53 +00:00
|
|
|
|
2018-05-07 18:13:56 +00:00
|
|
|
bshape(fsh.b[id], fsh.prio);
|
|
|
|
for(int t=0; t<=sides; t++)
|
2018-08-20 00:03:43 +00:00
|
|
|
hpcpush(xspinpush0(t*2 * M_PI / sides + shift * M_PI / S42, size));
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
bshape(fsh.shadow[id], fsh.prio);
|
|
|
|
for(int t=0; t<=sides; t++)
|
2018-08-20 00:03:43 +00:00
|
|
|
hpcpush(xspinpush0(t*2 * M_PI / sides + shift * M_PI / S42, size * SHADMUL));
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
for(int k=0; k<SIDEPARS; k++) {
|
|
|
|
fsh.side[k].resize(2);
|
2018-08-28 12:27:23 +00:00
|
|
|
bshape(fsh.side[k][id], PPR::LAKEWALL);
|
2019-05-08 16:33:08 +00:00
|
|
|
hpcpush(xspinpush0(+M_PI/sides, size));
|
2018-08-19 13:55:49 +00:00
|
|
|
hpcpush(xspinpush0(-M_PI/sides, size));
|
2018-05-07 18:13:56 +00:00
|
|
|
chasmifyPoly(dlow_table[k], dhi_table[k], k);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_IRR
|
2018-07-16 18:05:23 +00:00
|
|
|
namespace irr { void generate_floorshapes(); }
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
// !siid equals pseudohept(c)
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void geometry_information::generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBBI(DF_POLY, ("generate_floorshapes_for ", id));
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
for(auto pfsh: all_plain_floorshapes) {
|
|
|
|
auto& fsh = *pfsh;
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2019-12-14 11:05:01 +00:00
|
|
|
if(STDVAR && (standard_tiling() || bt::in())) {
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
ld hexside = fsh.rad0, heptside = fsh.rad1;
|
|
|
|
|
|
|
|
for(int k=0; k<SIDEPARS; k++) sizeto(fsh.side[k], id);
|
|
|
|
|
2019-12-27 22:01:55 +00:00
|
|
|
ld td = (PURE && !(S7&1)) ? S42+S6 : 0;
|
2018-08-17 14:47:06 +00:00
|
|
|
if(&fsh == &shBigHepta) td += S6;
|
2019-12-27 22:01:55 +00:00
|
|
|
|
|
|
|
if(S3 >= OINF && !(S7 & 1)) td = S42 * 1. / S7;
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
int b = 0;
|
2018-08-28 15:17:34 +00:00
|
|
|
if(S3 == 4 && BITRUNCATED) b += S14;
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2019-11-14 21:24:36 +00:00
|
|
|
if(id)
|
|
|
|
bshape_regular(fsh, id, S7, td, heptside, c);
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2018-08-28 15:17:34 +00:00
|
|
|
else if(PURE) {
|
2018-08-17 14:47:06 +00:00
|
|
|
if(&fsh == &shTriheptaFloor)
|
2019-07-22 09:21:27 +00:00
|
|
|
bshape_regular(fsh, 0, S7/2, 0, hexside, c);
|
2018-08-17 14:47:06 +00:00
|
|
|
else if(&fsh == &shBigTriangle)
|
2019-07-22 09:21:27 +00:00
|
|
|
bshape_regular(fsh, 0, S7/2, S12, hexside, c);
|
2018-08-17 14:47:06 +00:00
|
|
|
else
|
2019-07-22 09:21:27 +00:00
|
|
|
bshape_regular(fsh, 0, S7, td, heptside, c);
|
2018-08-17 14:47:06 +00:00
|
|
|
}
|
|
|
|
else if(&fsh == &shBigTriangle)
|
2019-07-22 09:21:27 +00:00
|
|
|
bshape_regular(fsh, 0, S3, b+S14, hexside, c);
|
2018-08-17 14:47:06 +00:00
|
|
|
else if(&fsh == &shTriheptaFloor)
|
2019-07-22 09:21:27 +00:00
|
|
|
bshape_regular(fsh, 0, S3, b, hexside, c);
|
2018-08-17 14:47:06 +00:00
|
|
|
else
|
2019-07-22 09:21:27 +00:00
|
|
|
bshape_regular(fsh, 0, S6, S7, hexside, c);
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// special
|
|
|
|
ld sca = 3 * shFullFloor.rad0 / fsh.rad0;
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
vector<hyperpoint> cornerlist;
|
|
|
|
|
|
|
|
int cor = c->type;
|
|
|
|
|
|
|
|
if(&fsh == &shTriheptaFloor) {
|
|
|
|
if(!siid) {
|
|
|
|
for(int i=0; i<cor; i++)
|
|
|
|
cornerlist.push_back(midcorner(c, i, .49));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for(int i=0; i<cor; i++) {
|
|
|
|
int ri = i;
|
|
|
|
if((i&1) == ((sidir+siid)&1)) ri--;
|
2019-08-09 12:39:21 +00:00
|
|
|
ri = c->c.fix(ri);
|
|
|
|
cornerlist.push_back(mid(get_corner_position(c, ri, 3.1), get_corner_position(c, c->c.fix(ri+1), 3.1)));
|
2018-08-17 14:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
else if(&fsh == &shBigTriangle) {
|
|
|
|
if(!siid) {
|
|
|
|
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
|
|
|
|
}
|
2020-07-12 18:53:45 +00:00
|
|
|
else if(geosupport_chessboard()) {
|
|
|
|
for(int i=0; i<cor; i++) {
|
|
|
|
hyperpoint nc = nearcorner(c, i);
|
|
|
|
cornerlist.push_back(mid_at(hpxy(0,0), nc, .94));
|
|
|
|
}
|
|
|
|
}
|
2018-08-17 14:47:06 +00:00
|
|
|
else {
|
|
|
|
for(int i=0; i<cor; i++) {
|
|
|
|
int ri = i;
|
|
|
|
if((i&1) != ((sidir+siid)&1)) ri--;
|
2019-08-09 12:39:21 +00:00
|
|
|
ri = c->c.fix(ri);
|
2018-08-17 14:47:06 +00:00
|
|
|
hyperpoint nc = nearcorner(c, ri);
|
|
|
|
cornerlist.push_back(mid_at(hpxy(0,0), nc, .94));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
else if(&fsh == &shBigHepta) {
|
|
|
|
if(!siid) {
|
|
|
|
for(int i=0; i<cor; i++) {
|
|
|
|
hyperpoint nc = nearcorner(c, i);
|
|
|
|
cornerlist.push_back(mid_at(hpxy(0,0), nc, .94));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
2020-11-01 10:30:55 +00:00
|
|
|
|
|
|
|
else if(arb::in()) {
|
|
|
|
vector<hyperpoint> actual;
|
|
|
|
for(int j=0; j<cor; j++)
|
|
|
|
actual.push_back(get_corner_position(c, j));
|
|
|
|
|
|
|
|
ld min_dist = 1e3;
|
|
|
|
for(int j=0; j<cor; j++)
|
|
|
|
for(int k=0; k<j; k++) {
|
|
|
|
ld dist = hdist(actual[j], actual[k]);
|
|
|
|
if(dist > 1e-6 && dist < min_dist)
|
|
|
|
min_dist = dist;
|
|
|
|
}
|
|
|
|
|
|
|
|
ld dist = min_dist * (1 - 3 / sca);
|
|
|
|
|
|
|
|
ld area = 0;
|
|
|
|
for(int j=0; j<cor; j++) {
|
|
|
|
hyperpoint current = kleinize(actual[j]);
|
|
|
|
hyperpoint last = kleinize(actual[j?j-1:cor-1]);
|
|
|
|
area += current[0] * last[1] - last[0] * current[1];
|
|
|
|
}
|
|
|
|
if(area < 0) dist = -dist;
|
|
|
|
|
|
|
|
for(int j=0; j<cor; j++) {
|
|
|
|
hyperpoint last = actual[j?j-1:cor-1];
|
2020-11-27 01:05:11 +00:00
|
|
|
hyperpoint current = ypush(1e-6 * randd()) * xpush(1e-6) * actual[j];
|
2020-11-01 10:30:55 +00:00
|
|
|
hyperpoint next = actual[j<cor-1?j+1:0];
|
|
|
|
auto T = gpushxto0(current);
|
|
|
|
last = T * last;
|
|
|
|
next = T * next;
|
|
|
|
hyperpoint a = rspintox(last) * ypush0(dist);
|
|
|
|
hyperpoint b = rspintox(last) * xpush(hdist0(last)) * ypush0(dist);
|
|
|
|
|
|
|
|
hyperpoint c = rspintox(next) * ypush0(-dist);
|
|
|
|
hyperpoint d = rspintox(next) * xpush(hdist0(next)) * ypush0(-dist);
|
|
|
|
|
|
|
|
hyperpoint h = linecross(a, b, c, d);
|
|
|
|
|
|
|
|
cornerlist.push_back(rgpushxto0(current) * h);
|
|
|
|
}
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
else {
|
|
|
|
for(int j=0; j<cor; j++)
|
|
|
|
cornerlist.push_back(get_corner_position(c, j, sca));
|
|
|
|
}
|
|
|
|
|
|
|
|
sizeto(fsh.b, id);
|
2018-08-21 00:47:53 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
bshape(fsh.b[id], fsh.prio);
|
2018-08-21 02:24:14 +00:00
|
|
|
if(cor == 2) {
|
|
|
|
/* give digons some width */
|
|
|
|
for(int i=0; i<cor; i++) hpcpush(spin(-.1) * cornerlist[i]), hpcpush(spin(+.1) * cornerlist[i]);
|
|
|
|
hpcpush(spin(-.1) * cornerlist[0]);
|
|
|
|
}
|
|
|
|
else if(&fsh == &shTriheptaFloor && cor == 4 && siid)
|
|
|
|
/* trihepta floors generate digons too */
|
2018-08-21 00:47:53 +00:00
|
|
|
for(int i=0; i<=cor; i++) hpcpush(spin((i&1) ? .1 : -.1) * cornerlist[i%cor]);
|
|
|
|
else
|
|
|
|
for(int i=0; i<=cor; i++) hpcpush(cornerlist[i%cor]);
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
sizeto(fsh.shadow, id);
|
|
|
|
bshape(fsh.shadow[id], fsh.prio);
|
|
|
|
for(int i=0; i<=cor; i++)
|
|
|
|
hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL));
|
|
|
|
|
2020-01-18 15:03:32 +00:00
|
|
|
for(int k=0; k<SIDEPARS; k++) {
|
2020-03-11 08:53:53 +00:00
|
|
|
if(isize(fsh.gpside[k]) < cor)
|
|
|
|
fsh.gpside[k].resize(cor);
|
2018-08-17 14:47:06 +00:00
|
|
|
for(int cid=0; cid<cor; cid++) {
|
|
|
|
sizeto(fsh.gpside[k][cid], id);
|
|
|
|
bshape(fsh.gpside[k][cid][id], fsh.prio);
|
2020-03-21 08:28:16 +00:00
|
|
|
hpcpush(iddspin_side(c, cid) * cornerlist[cid]);
|
|
|
|
hpcpush(iddspin_side(c, cid) * cornerlist[(cid+1)%cor]);
|
2018-08-17 14:47:06 +00:00
|
|
|
chasmifyPoly(dlow_table[k], dhi_table[k], k);
|
|
|
|
}
|
2020-01-18 15:03:32 +00:00
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
2019-05-08 16:33:08 +00:00
|
|
|
|
2018-05-07 18:13:56 +00:00
|
|
|
for(auto pfsh: all_escher_floorshapes) {
|
2019-05-08 16:33:08 +00:00
|
|
|
|
2018-05-07 18:13:56 +00:00
|
|
|
auto& fsh = *pfsh;
|
2018-08-09 17:28:53 +00:00
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
sizeto(fsh.b, id);
|
2018-08-18 15:52:43 +00:00
|
|
|
sizeto(fsh.shadow, id);
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2019-12-14 10:26:03 +00:00
|
|
|
if(STDVAR && standard_tiling()) {
|
2018-08-17 14:47:06 +00:00
|
|
|
generate_matrices_scale(fsh.scale, fsh.noftype);
|
2019-07-22 09:21:27 +00:00
|
|
|
if(PURE && geosupport_football() < 2) {
|
|
|
|
bshape2(fsh.b[id], fsh.prio, fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1, hept_matrices);
|
2018-08-17 14:47:06 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(id == 0) bshape2(fsh.b[0], fsh.prio, fsh.shapeid0, hex_matrices);
|
|
|
|
if(id == 1) bshape2(fsh.b[1], fsh.prio, fsh.shapeid1, hept_matrices);
|
|
|
|
}
|
2018-08-18 15:52:43 +00:00
|
|
|
generate_matrices_scale(fsh.scale * SHADMUL, fsh.noftype);
|
2019-07-22 09:21:27 +00:00
|
|
|
if(PURE && geosupport_football() < 2) {
|
|
|
|
bshape2(fsh.shadow[id], fsh.prio, fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1, hept_matrices);
|
2018-08-18 15:52:43 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(id == 0) bshape2(fsh.shadow[0], fsh.prio, fsh.shapeid0, hex_matrices);
|
|
|
|
if(id == 1) bshape2(fsh.shadow[1], fsh.prio, fsh.shapeid1, hept_matrices);
|
|
|
|
}
|
2018-08-17 14:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
generate_matrices_scale(fsh.scale, fsh.noftype);
|
|
|
|
|
2018-08-20 13:24:44 +00:00
|
|
|
auto& m = (siid && geosupport_football() == 2) ? hex_matrices : hept_matrices;
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
int cor = c->type;
|
|
|
|
|
|
|
|
m.n.sym = cor;
|
|
|
|
|
|
|
|
int v = sidir+siid;
|
2020-01-18 15:03:32 +00:00
|
|
|
for(auto& mvi: m.v) mvi.second.resize(cor);
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2018-08-18 15:52:43 +00:00
|
|
|
for(int ii=0; ii<2; ii++) {
|
|
|
|
int i = 0;
|
|
|
|
for(int d=0; d<m.o.sym; d++) {
|
|
|
|
hyperpoint center = hpxy(0,0);
|
|
|
|
|
|
|
|
for(int cid=0; cid<cor; cid++) {
|
|
|
|
hyperpoint nlcorner = get_corner_position(c, (d+cid+v+1) % cor, 3 / fsh.scale * (ii ? 1/SHADMUL : 1));
|
|
|
|
hyperpoint nrcorner = get_corner_position(c, (d+cid+v+2) % cor, 3 / fsh.scale * (ii ? 1/SHADMUL : 1));
|
|
|
|
|
|
|
|
hyperpoint nfar = nearcorner(c, (d+cid+v+1) % cor);
|
|
|
|
|
|
|
|
hyperpoint nlfar = farcorner(c, (d+cid+v+1) % cor, 0);
|
|
|
|
hyperpoint nrfar = farcorner(c, (d+cid+v+1) % cor, 1);
|
2019-05-15 07:36:25 +00:00
|
|
|
m.v[i].second[cid] = build_matrix(center, nlcorner, nrcorner,C02);
|
|
|
|
m.v[i+1].second[cid] = build_matrix(nfar, nlcorner, nrcorner,C02);
|
|
|
|
m.v[i+2].second[cid] = build_matrix(nfar, nlcorner, nlfar,C02);
|
|
|
|
m.v[i+3].second[cid] = build_matrix(nfar, nrcorner, nrfar,C02);
|
2018-08-18 15:52:43 +00:00
|
|
|
}
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2018-08-18 15:52:43 +00:00
|
|
|
i += 4;
|
2018-08-09 17:28:53 +00:00
|
|
|
}
|
2018-08-18 15:52:43 +00:00
|
|
|
|
|
|
|
if(i != isize(m.v)) printf("warning: i=%d sm=%d\n", i, isize(m.v));
|
2018-08-20 13:24:44 +00:00
|
|
|
bshape2((ii?fsh.shadow:fsh.b)[id], fsh.prio, (fsh.shapeid2 && geosupport_football() < 2) ? fsh.shapeid2 : siid?fsh.shapeid0:fsh.shapeid1, m);
|
2018-08-09 17:28:53 +00:00
|
|
|
}
|
|
|
|
}
|
2019-05-08 18:15:50 +00:00
|
|
|
}
|
|
|
|
|
2019-05-09 15:54:30 +00:00
|
|
|
#if MAXMDIM >= 4
|
2019-05-08 18:15:50 +00:00
|
|
|
if(WDIM == 2 && GDIM == 3) {
|
|
|
|
finishshape();
|
|
|
|
for(auto pfsh: all_plain_floorshapes) {
|
|
|
|
auto& fsh = *pfsh;
|
2019-05-13 11:39:43 +00:00
|
|
|
|
|
|
|
for(int i=fsh.shadow[id].s; i<fsh.shadow[id].e; i++)
|
2019-05-26 16:04:02 +00:00
|
|
|
hpc[i] = orthogonal_move(hpc[i], FLOOR - human_height / 100);
|
2019-05-08 18:15:50 +00:00
|
|
|
|
|
|
|
for(int k=0; k<SIDEPARS; k++) {
|
|
|
|
sizeto(fsh.levels[k], id);
|
2019-05-09 15:20:31 +00:00
|
|
|
bshape(fsh.levels[k][id], fsh.prio);
|
|
|
|
last->flags |= POLY_TRIANGLES;
|
2019-05-26 16:04:02 +00:00
|
|
|
last->tinf = &floor_texture_vertices[fsh.id];
|
2019-05-09 15:20:31 +00:00
|
|
|
last->texture_offset = 0;
|
|
|
|
|
2019-05-09 15:00:05 +00:00
|
|
|
#if CAP_BT
|
2019-12-14 11:05:01 +00:00
|
|
|
if(bt::in())
|
2019-05-08 18:15:50 +00:00
|
|
|
for(int t=0; t<c->type; t++)
|
2019-05-09 15:20:31 +00:00
|
|
|
texture_order([&] (ld x, ld y) {
|
2019-12-14 11:05:01 +00:00
|
|
|
hyperpoint left = bt::get_corner_horo_coordinates(c, t);
|
|
|
|
hyperpoint right = bt::get_corner_horo_coordinates(c, t+1);
|
|
|
|
hpcpush(orthogonal_move(bt::get_horopoint(left * x + right * y), dfloor_table[k]));
|
2019-05-09 15:20:31 +00:00
|
|
|
});
|
2019-05-09 15:00:05 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
if(1) {
|
2019-05-09 15:20:31 +00:00
|
|
|
int s = fsh.b[id].s;
|
|
|
|
int e = fsh.b[id].e-1;
|
|
|
|
for(int t=0; t<e-s; t++) {
|
2019-05-13 11:40:03 +00:00
|
|
|
hyperpoint v1 = hpc[s+t] - C0;
|
|
|
|
hyperpoint v2 = hpc[s+t+1] - C0;
|
|
|
|
texture_order([&] (ld x, ld y) { hpcpush(orthogonal_move(normalize(C0 + v1 * x + v2 * y), dfloor_table[k])); });
|
2019-05-08 18:15:50 +00:00
|
|
|
}
|
|
|
|
}
|
2020-01-18 15:03:32 +00:00
|
|
|
|
|
|
|
finishshape();
|
2020-01-18 15:59:16 +00:00
|
|
|
ensure_vertex_number(fsh.levels[k][id]);
|
2019-05-08 18:15:50 +00:00
|
|
|
}
|
2019-05-09 23:24:16 +00:00
|
|
|
|
2019-05-12 18:10:01 +00:00
|
|
|
for(int co=0; co<2; co++) {
|
|
|
|
sizeto(fsh.cone[co], id);
|
|
|
|
bshape(fsh.cone[co][id], fsh.prio);
|
|
|
|
last->flags |= POLY_TRIANGLES;
|
2019-05-26 16:04:02 +00:00
|
|
|
last->tinf = &floor_texture_vertices[fsh.id];
|
2019-05-12 18:10:01 +00:00
|
|
|
last->texture_offset = 0;
|
2019-05-26 16:04:02 +00:00
|
|
|
ld h = (FLOOR - WALL) / (co+1);
|
|
|
|
ld top = co ? (FLOOR + WALL) / 2 : WALL;
|
2019-05-12 18:10:01 +00:00
|
|
|
#if CAP_BT
|
2019-12-14 11:05:01 +00:00
|
|
|
if(bt::in())
|
2019-05-12 18:10:01 +00:00
|
|
|
for(int t=0; t<c->type; t++)
|
|
|
|
texture_order([&] (ld x, ld y) {
|
2019-12-14 11:05:01 +00:00
|
|
|
hyperpoint left = bt::get_corner_horo_coordinates(c, t);
|
|
|
|
hyperpoint right = bt::get_corner_horo_coordinates(c, t+1);
|
|
|
|
hpcpush(orthogonal_move(bt::get_horopoint(left * x + right * y), top + h * (x+y)));
|
2019-05-12 18:10:01 +00:00
|
|
|
});
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
if(1) {
|
|
|
|
int s = fsh.b[id].s;
|
|
|
|
int e = fsh.b[id].e-1;
|
|
|
|
for(int t=0; t<e-s; t++) {
|
|
|
|
hyperpoint v1 = hpc[s+t] - C0;
|
|
|
|
hyperpoint v2 = hpc[s+t+1] - C0;
|
2019-05-13 11:40:03 +00:00
|
|
|
texture_order([&] (ld x, ld y) { hpcpush(orthogonal_move(normalize(C0 + v1 * x + v2 * y), top + h * (x+y))); });
|
2019-05-12 18:10:01 +00:00
|
|
|
}
|
2019-05-09 23:24:16 +00:00
|
|
|
}
|
2020-01-18 15:03:32 +00:00
|
|
|
|
|
|
|
finishshape();
|
2020-01-18 15:59:16 +00:00
|
|
|
ensure_vertex_number(fsh.cone[co][id]);
|
2019-05-09 23:24:16 +00:00
|
|
|
}
|
2019-05-09 15:54:30 +00:00
|
|
|
|
|
|
|
for(int l=0; l<SIDEPARS; l++) {
|
2020-01-18 15:59:16 +00:00
|
|
|
for(auto& li: fsh.side[l])
|
|
|
|
bind_floor_texture(li, fsh.id);
|
2020-03-11 08:53:53 +00:00
|
|
|
if(isize(fsh.gpside[l]) < c->type)
|
|
|
|
fsh.gpside[l].resize(c->type);
|
2020-01-18 15:59:16 +00:00
|
|
|
for(auto& gs: fsh.gpside[l]) {
|
|
|
|
for(auto& li: gs)
|
|
|
|
bind_floor_texture(li, fsh.id);
|
2020-01-18 15:03:32 +00:00
|
|
|
}
|
2019-05-09 15:54:30 +00:00
|
|
|
}
|
2019-05-08 18:15:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for(auto pfsh: all_escher_floorshapes) {
|
|
|
|
auto& fsh = *pfsh;
|
|
|
|
|
|
|
|
for(int l=0; l<SIDEPARS; l++) {
|
|
|
|
fsh.levels[l] = shFullFloor.levels[l];
|
2019-05-13 11:39:43 +00:00
|
|
|
fsh.shadow = shFullFloor.shadow;
|
2020-01-18 15:59:16 +00:00
|
|
|
for(auto& li: fsh.levels[l]) bind_floor_texture(li, fsh.id);
|
2019-05-08 18:15:50 +00:00
|
|
|
fsh.side[l] = shFullFloor.side[l];
|
2020-01-18 15:59:16 +00:00
|
|
|
for(auto& li: fsh.side[l]) bind_floor_texture(li, fsh.id);
|
2020-03-11 08:53:53 +00:00
|
|
|
if(isize(fsh.gpside[l]) < c->type)
|
|
|
|
fsh.gpside[l].resize(c->type);
|
2020-01-18 15:03:32 +00:00
|
|
|
for(int e=0; e<c->type; e++) {
|
2019-05-08 18:15:50 +00:00
|
|
|
fsh.gpside[l][e] = shFullFloor.gpside[l][e];
|
2020-01-18 15:59:16 +00:00
|
|
|
for(auto& li: fsh.gpside[l][e])
|
|
|
|
bind_floor_texture(li, fsh.id);
|
2019-05-09 15:54:30 +00:00
|
|
|
}
|
2019-05-12 18:10:01 +00:00
|
|
|
fsh.cone[0] = shFullFloor.cone[0];
|
|
|
|
fsh.cone[1] = shFullFloor.cone[1];
|
|
|
|
for(int c=0; c<2; c++)
|
|
|
|
for(auto& li: fsh.cone[c])
|
2020-01-18 15:59:16 +00:00
|
|
|
bind_floor_texture(li, fsh.id);
|
2019-05-08 18:15:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
finishshape();
|
2018-08-17 14:47:06 +00:00
|
|
|
}
|
2019-05-09 15:54:30 +00:00
|
|
|
#endif
|
2018-08-17 14:47:06 +00:00
|
|
|
}
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void geometry_information::generate_floorshapes() {
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBBI(DF_POLY, ("generate_floorshapes"));
|
2019-05-26 16:04:02 +00:00
|
|
|
|
2019-11-14 15:51:50 +00:00
|
|
|
heptagon modelh;
|
|
|
|
cell model;
|
|
|
|
model.master = &modelh;
|
2020-03-11 10:33:47 +00:00
|
|
|
modelh.c7 = &model;
|
2019-11-14 15:51:50 +00:00
|
|
|
model.type = modelh.type = S7;
|
2019-11-14 21:24:36 +00:00
|
|
|
|
|
|
|
auto mmerge1 = [&] (int i, int j) { model.c.setspin(i, j, false); modelh.c.setspin(i, j, false); };
|
|
|
|
auto mmerge = [&] (int i, int j) { mmerge1(i, j); mmerge1(j, i); };
|
|
|
|
|
2019-11-14 15:51:50 +00:00
|
|
|
for(int i=0; i<S7; i++) {
|
|
|
|
model.move(i) = &model;
|
|
|
|
modelh.move(i) = &modelh;
|
|
|
|
model.c.setspin(i, i, false);
|
|
|
|
modelh.c.setspin(i, i, false);
|
|
|
|
}
|
|
|
|
|
2019-05-08 16:33:08 +00:00
|
|
|
if(WDIM == 3) ;
|
2019-02-22 20:12:44 +00:00
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_IRR
|
|
|
|
else if(IRREGULAR) {
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBBI(DF_POLY, ("generate_floorshapes: irregular"));
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
int cc = isize(irr::cells);
|
|
|
|
|
|
|
|
for(int id=0; id<cc; id++) {
|
|
|
|
irr::cellindex[&model] = id;
|
|
|
|
auto& vs = irr::cells[id];
|
|
|
|
model.type = isize(vs.vertices);
|
|
|
|
int siid = !vs.is_pseudohept;
|
|
|
|
int sidir = 0;
|
|
|
|
if(siid) sidir = irr::cells[vs.neid[0]].is_pseudohept;
|
|
|
|
generate_floorshapes_for(id, &model, !vs.is_pseudohept, sidir);
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
2018-08-17 14:47:06 +00:00
|
|
|
|
|
|
|
printf("done\n");
|
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2020-07-12 18:52:32 +00:00
|
|
|
else if(GOLDBERG_INV) { /* will be generated on the fly */ }
|
2020-01-18 23:13:54 +00:00
|
|
|
|
|
|
|
else if(inforder::mixed()) { /* will be generated on the fly */ }
|
2018-08-17 14:47:06 +00:00
|
|
|
|
2019-07-25 10:24:02 +00:00
|
|
|
#if CAP_BT
|
2019-12-14 11:12:24 +00:00
|
|
|
else if(kite::in()) {
|
2019-07-25 10:24:02 +00:00
|
|
|
dynamicval<bool> ncor(approx_nearcorner, true);
|
|
|
|
for(int i=0; i<2; i++) {
|
2019-11-14 15:51:50 +00:00
|
|
|
modelh.s = hstate(i); /* kite/dart shape */
|
2019-11-28 22:59:16 +00:00
|
|
|
kite::no_adj = true;
|
2019-07-25 10:24:02 +00:00
|
|
|
generate_floorshapes_for(i, &model, 0, 0);
|
2019-11-28 22:59:16 +00:00
|
|
|
kite::no_adj = false;
|
2019-07-25 10:24:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_ARCM
|
2019-12-14 10:42:16 +00:00
|
|
|
else if(arcm::in()) {
|
2019-11-14 15:51:50 +00:00
|
|
|
arcm::parent_index_of(&modelh) = 0;
|
2018-08-20 00:02:45 +00:00
|
|
|
auto &ac = arcm::current;
|
2018-08-29 02:28:34 +00:00
|
|
|
for(int i=0; i<2*ac.N + 2; i++) {
|
2020-07-03 13:40:26 +00:00
|
|
|
if(ac.regular && i>=2 && i < 2*ac.N) continue;
|
2019-11-14 15:51:50 +00:00
|
|
|
arcm::id_of(&modelh) = i;
|
2018-08-20 00:02:45 +00:00
|
|
|
model.type = isize(ac.triangles[i]);
|
2019-11-14 15:51:50 +00:00
|
|
|
if(DUAL) model.type /= 2, arcm::parent_index_of(&modelh) = !(i&1);
|
2018-08-30 00:11:43 +00:00
|
|
|
|
2018-08-29 02:28:34 +00:00
|
|
|
if(BITRUNCATED)
|
2018-08-30 14:02:35 +00:00
|
|
|
generate_floorshapes_for(i, &model, !arcm::pseudohept(&model), arcm::pseudohept(&model) ? 0 : 1^(i&1));
|
2018-08-29 02:28:34 +00:00
|
|
|
else if(geosupport_football() == 2)
|
2018-08-30 14:02:35 +00:00
|
|
|
generate_floorshapes_for(i, &model, !arcm::pseudohept(&model), i >= 4 ? 1 : 0);
|
2018-08-19 16:06:08 +00:00
|
|
|
else
|
|
|
|
generate_floorshapes_for(i, &model, 0, 0);
|
2018-08-17 19:42:42 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2018-08-17 19:42:42 +00:00
|
|
|
|
2019-12-14 10:29:53 +00:00
|
|
|
else if(arb::in()) {
|
|
|
|
auto& c = arb::current;
|
|
|
|
int n = isize(c.shapes);
|
|
|
|
vector<cell> models(n);
|
|
|
|
vector<heptagon> modelh(n);
|
|
|
|
for(int i=0; i<n; i++) {
|
2019-12-23 19:51:15 +00:00
|
|
|
auto &ms = models[i];
|
|
|
|
auto &mh = modelh[i];
|
|
|
|
for(auto& t: ms.c.move_table) t = nullptr;
|
|
|
|
for(auto& t: mh.c.move_table) t = nullptr;
|
|
|
|
}
|
|
|
|
for(int i=0; i<n; i++) {
|
2019-12-14 10:29:53 +00:00
|
|
|
auto &ms = models[i];
|
|
|
|
auto &mh = modelh[i];
|
|
|
|
ms.master = &mh;
|
|
|
|
mh.c7 = &ms;
|
|
|
|
mh.zebraval = i;
|
|
|
|
auto& sh = c.shapes[i];
|
|
|
|
ms.type = mh.type = sh.size();
|
2019-12-27 22:38:28 +00:00
|
|
|
}
|
|
|
|
for(int i=0; i<n; i++) {
|
|
|
|
auto &ms = models[i];
|
|
|
|
auto &mh = modelh[i];
|
|
|
|
auto& sh = c.shapes[i];
|
2019-12-14 10:29:53 +00:00
|
|
|
for(int j=0; j<sh.size(); j++) {
|
|
|
|
auto& co = sh.connections[j];
|
|
|
|
mh.c.connect(j, &modelh[get<0>(co)], get<1>(co), get<2>(co));
|
|
|
|
ms.c.connect(j, &models[get<0>(co)], get<1>(co), get<2>(co));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(int i=0; i<n; i++) generate_floorshapes_for(i, &models[i], 0, 0);
|
|
|
|
}
|
|
|
|
|
2019-07-22 09:21:27 +00:00
|
|
|
else if(geometry == gBinary4) {
|
|
|
|
for(int i: {0,1}) {
|
|
|
|
modelh.zebraval = i;
|
2019-11-14 21:24:36 +00:00
|
|
|
mmerge(2, 4); mmerge(0, 3); mmerge(1, 3); mmerge(i, 3);
|
2019-07-22 09:21:27 +00:00
|
|
|
generate_floorshapes_for(i, &model, 1, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-30 21:36:15 +00:00
|
|
|
else if(geometry == gTernary) {
|
|
|
|
for(int i: {0,1,2}) {
|
|
|
|
modelh.zebraval = i;
|
2019-11-14 21:24:36 +00:00
|
|
|
mmerge(3, 5); for(int a=0; a<3; a++) mmerge1(a, 4); mmerge(4, i);
|
2019-09-30 21:36:15 +00:00
|
|
|
generate_floorshapes_for(i, &model, 1, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-22 09:21:27 +00:00
|
|
|
else if(PURE && geometry != gBinaryTiling && geosupport_football() < 2) {
|
|
|
|
generate_floorshapes_for(0, &model, 1, 0);
|
|
|
|
}
|
|
|
|
|
2018-08-17 14:47:06 +00:00
|
|
|
else {
|
2020-10-26 11:00:28 +00:00
|
|
|
static hrmap_standard stdmap;
|
|
|
|
dynamicval<hrmap*> c(currentmap, &stdmap);
|
|
|
|
// cell model;
|
2018-08-17 14:47:06 +00:00
|
|
|
model.type = S6; generate_floorshapes_for(0, &model, 0, 0);
|
2019-12-14 11:05:01 +00:00
|
|
|
model.type = S7; generate_floorshapes_for(1, &model, bt::in() ? 0 : 1, 0);
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_GP
|
2019-08-10 08:57:14 +00:00
|
|
|
EX namespace gp {
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2019-08-10 08:57:14 +00:00
|
|
|
EX void clear_plainshapes() {
|
2018-05-07 18:13:56 +00:00
|
|
|
for(int m=0; m<3; m++)
|
|
|
|
for(int sd=0; sd<8; sd++)
|
|
|
|
for(int i=0; i<32; i++)
|
|
|
|
for(int j=0; j<32; j++)
|
|
|
|
for(int k=0; k<8; k++)
|
2020-07-12 18:43:58 +00:00
|
|
|
cgi.gpdata->pshid[m][sd][i][j][k] = -1;
|
|
|
|
cgi.gpdata->nextid = 0;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void build_plainshape(int& id, gp::local_info& li, cell *c0, int siid, int sidir) {
|
2020-07-12 18:43:58 +00:00
|
|
|
id = cgi.gpdata->nextid++;
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
bool master = !(li.relative.first||li.relative.second);
|
2018-07-10 02:13:35 +00:00
|
|
|
int cor = master ? S7 : SG6;
|
2018-05-07 18:13:56 +00:00
|
|
|
if(master) li.last_dir = -1;
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GP, (format("last=%d at=%d,%d tot=%d siid=%d sidir=%d cor=%d id=%d\n", li.last_dir, li.relative.first, li.relative.second, li.total_dir, siid, sidir, cor, id)));
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
cgi.generate_floorshapes_for(id, c0, siid, sidir);
|
2018-05-07 18:13:56 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
cgi.finishshape();
|
|
|
|
cgi.extra_vertices();
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int get_plainshape_id(cell *c) {
|
|
|
|
int siid, sidir;
|
2020-07-12 18:52:32 +00:00
|
|
|
cell *c1 = c;
|
|
|
|
auto f = [&] {
|
|
|
|
if(geosupport_threecolor() == 2) {
|
|
|
|
auto si = patterns::getpatterninfo(c1, patterns::PAT_COLORING, patterns::SPF_NO_SUBCODES);
|
|
|
|
siid = si.id>>2;
|
|
|
|
// if(siid == 2) si.dir++;
|
|
|
|
// if(siid != pattern_threecolor(c)) printf("threecolor mismatch\n");
|
|
|
|
// if(pattern_threecolor(createMov(c, c->fixd(si.dir))) != (siid+1)%3) printf("threecolor mismatch direction\n");
|
|
|
|
sidir = c1->c.fix(si.dir);
|
|
|
|
}
|
|
|
|
else if(geosupport_football() == 2) {
|
|
|
|
siid = !pseudohept(c1);
|
|
|
|
sidir = !ishex1(c1);
|
|
|
|
}
|
|
|
|
else if(geosupport_chessboard()) {
|
|
|
|
siid = !chessvalue(c1);
|
|
|
|
sidir = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
siid = 0;
|
|
|
|
sidir = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if(INVERSE && gp::variation_for(gp::param) == eVariation::goldberg) {
|
|
|
|
c1 = gp::get_mapped(c);
|
|
|
|
UIU(f());
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
2020-07-12 18:52:32 +00:00
|
|
|
else if(INVERSE) {
|
2018-05-07 18:13:56 +00:00
|
|
|
siid = 0;
|
|
|
|
sidir = 0;
|
|
|
|
}
|
2020-07-12 18:52:32 +00:00
|
|
|
else f();
|
2020-07-12 18:43:58 +00:00
|
|
|
auto& id = cgi.gpdata->pshid[siid][sidir][draw_li.relative.first&31][draw_li.relative.second&31][gmod(draw_li.total_dir, S6)];
|
2019-05-26 16:04:02 +00:00
|
|
|
if(id == -1 && sphere && isize(cgi.shFloor.b) > 0) {
|
2018-08-20 14:41:21 +00:00
|
|
|
forCellEx(c1, c) if(!gmatrix0.count(c1)) return 0;
|
2018-08-20 14:28:25 +00:00
|
|
|
}
|
2018-08-18 15:38:07 +00:00
|
|
|
if(id == -1) build_plainshape(id, draw_li, c, siid, sidir);
|
2018-05-07 18:13:56 +00:00
|
|
|
return id;
|
|
|
|
}
|
2019-08-10 08:57:14 +00:00
|
|
|
EX }
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2018-05-07 18:13:56 +00:00
|
|
|
|
|
|
|
qfloorinfo qfi;
|
|
|
|
|
2019-09-06 06:17:02 +00:00
|
|
|
EX void set_no_floor() {
|
2018-05-07 18:13:56 +00:00
|
|
|
qfi.fshape = NULL;
|
|
|
|
qfi.shape = NULL;
|
2018-08-27 17:27:35 +00:00
|
|
|
qfi.tinf = NULL;
|
|
|
|
qfi.usershape = -1;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
2019-09-06 06:17:02 +00:00
|
|
|
EX void set_floor(floorshape& sh) {
|
2018-05-07 18:13:56 +00:00
|
|
|
qfi.fshape = &sh;
|
|
|
|
qfi.shape = NULL;
|
2018-08-04 09:15:05 +00:00
|
|
|
qfi.tinf = NULL;
|
2018-08-27 17:27:35 +00:00
|
|
|
qfi.usershape = -1;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
2019-09-06 06:17:02 +00:00
|
|
|
EX void set_floor(hpcshape& sh) {
|
2018-05-07 18:13:56 +00:00
|
|
|
qfi.shape = &sh;
|
|
|
|
qfi.fshape = NULL;
|
|
|
|
qfi.spin = Id;
|
2018-08-04 09:15:05 +00:00
|
|
|
qfi.tinf = NULL;
|
2018-08-27 17:27:35 +00:00
|
|
|
qfi.usershape = -1;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
2019-09-06 06:17:02 +00:00
|
|
|
EX void set_floor(const transmatrix& spin, hpcshape& sh) {
|
2018-05-07 18:13:56 +00:00
|
|
|
qfi.shape = &sh;
|
|
|
|
qfi.fshape = NULL;
|
|
|
|
qfi.spin = spin;
|
2018-08-27 17:27:35 +00:00
|
|
|
qfi.usershape = -1;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
2019-08-18 18:13:46 +00:00
|
|
|
EX int shvid(cell *c) {
|
2019-08-24 12:07:46 +00:00
|
|
|
if(hybri) {
|
|
|
|
cell *c1 = hybrid::get_where(c).first;
|
2019-11-28 22:09:04 +00:00
|
|
|
return PIU( shvid(c1) );
|
2019-08-18 18:13:46 +00:00
|
|
|
}
|
2020-07-12 18:52:32 +00:00
|
|
|
else if(GOLDBERG_INV)
|
2019-08-18 19:30:39 +00:00
|
|
|
return gp::get_plainshape_id(c);
|
2020-10-15 14:33:52 +00:00
|
|
|
#if CAP_IRR
|
2019-08-18 19:30:39 +00:00
|
|
|
else if(IRREGULAR)
|
|
|
|
return irr::cellindex[c];
|
2020-10-15 14:33:52 +00:00
|
|
|
#endif
|
|
|
|
#if CAP_ARCM
|
2020-07-03 13:40:26 +00:00
|
|
|
else if(arcm::in()) {
|
|
|
|
auto& ac = arcm::current;
|
|
|
|
int id = arcm::id_of(c->master);
|
|
|
|
if(ac.regular && id>=2 && id < 2*ac.N) id &= 1;
|
|
|
|
return id;
|
|
|
|
}
|
2020-10-15 14:33:52 +00:00
|
|
|
#endif
|
2019-12-14 10:29:53 +00:00
|
|
|
else if(arb::in())
|
|
|
|
return arb::id_of(c->master);
|
2019-08-18 18:13:46 +00:00
|
|
|
else if(geosupport_football() == 2)
|
2019-07-22 09:21:27 +00:00
|
|
|
return pseudohept(c);
|
2020-10-15 14:33:52 +00:00
|
|
|
#if CAP_BT
|
2019-07-22 09:21:27 +00:00
|
|
|
else if(geometry == gBinaryTiling)
|
|
|
|
return c->type-6;
|
2019-12-14 11:12:24 +00:00
|
|
|
else if(kite::in())
|
2019-07-25 10:24:02 +00:00
|
|
|
return kite::getshape(c->master);
|
2019-09-30 21:36:15 +00:00
|
|
|
else if(geometry == gBinary4 || geometry == gTernary)
|
2019-07-22 09:21:27 +00:00
|
|
|
return c->master->zebraval;
|
2020-10-15 14:33:52 +00:00
|
|
|
#endif
|
2020-01-18 23:13:54 +00:00
|
|
|
else if(inforder::mixed()) {
|
|
|
|
int t = c->type;
|
|
|
|
static vector<bool> computed;
|
|
|
|
if(isize(computed) <= t) computed.resize(t+1);
|
|
|
|
if(!computed[t]) {
|
|
|
|
computed[t] = true;
|
|
|
|
cell model;
|
|
|
|
heptagon modelh;
|
|
|
|
model.type = t;
|
|
|
|
modelh.type = t;
|
|
|
|
S7 = t;
|
|
|
|
for(int i=0; i<S7; i++) {
|
|
|
|
model.move(i) = &model;
|
|
|
|
modelh.move(i) = &modelh;
|
|
|
|
model.c.setspin(i, i, false);
|
|
|
|
modelh.c.setspin(i, i, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
cgi.tessf = edge_of_triangle_with_angles(0, M_PI/t, M_PI/t);
|
|
|
|
cgi.crossf = cgi.tessf;
|
|
|
|
|
|
|
|
println(hlog, "generating floorshapes for ", t);
|
|
|
|
cgi.generate_floorshapes_for(t, &model, 0, 0);
|
|
|
|
cgi.finishshape();
|
|
|
|
cgi.extra_vertices();
|
|
|
|
}
|
|
|
|
return t;
|
|
|
|
}
|
2019-07-22 09:21:27 +00:00
|
|
|
else if(PURE)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return ctof(c);
|
|
|
|
}
|
|
|
|
|
2020-07-27 16:49:04 +00:00
|
|
|
EX struct dqi_poly *draw_shapevec(cell *c, const shiftmatrix& V, const vector<hpcshape> &shv, color_t col, PPR prio IS(PPR::DEFAULT)) {
|
2020-06-03 13:11:20 +00:00
|
|
|
if(no_wall_rendering) return NULL;
|
2019-05-20 11:40:56 +00:00
|
|
|
if(!c) return &queuepolyat(V, shv[0], col, prio);
|
|
|
|
else if(WDIM == 3) return NULL;
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_GP
|
2018-08-28 15:17:34 +00:00
|
|
|
else if(GOLDBERG) {
|
2018-05-07 18:13:56 +00:00
|
|
|
int id = gp::get_plainshape_id(c);
|
2019-05-20 11:40:56 +00:00
|
|
|
if(isize(shv) > id) return &queuepolyat(V, shv[id], col, prio);
|
|
|
|
return NULL;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
|
|
|
#if CAP_IRR
|
2018-08-28 15:17:34 +00:00
|
|
|
else if(IRREGULAR) {
|
2018-07-16 18:05:23 +00:00
|
|
|
int id = irr::cellindex[c];
|
|
|
|
if(id < 0 || id >= isize(shv)) {
|
2019-05-20 11:40:56 +00:00
|
|
|
return NULL;
|
2018-07-16 18:05:23 +00:00
|
|
|
}
|
2019-05-20 11:40:56 +00:00
|
|
|
return &queuepolyat(V, shv[id], col, prio);
|
2018-07-16 18:05:23 +00:00
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
|
|
|
#if CAP_ARCM
|
2019-12-14 10:42:16 +00:00
|
|
|
else if(arcm::in()) {
|
2020-07-03 13:40:26 +00:00
|
|
|
return &queuepolyat(V, shv[shvid(c)], col, prio);
|
2018-08-18 15:39:12 +00:00
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2019-11-27 00:01:20 +00:00
|
|
|
else if(GOLDBERG && ishex1(c))
|
2019-05-20 11:40:56 +00:00
|
|
|
return &queuepolyat(V * pispin, shv[0], col, prio);
|
2019-12-14 11:12:24 +00:00
|
|
|
else if(!(S7&1) && PURE && !kite::in() && !a4) {
|
2018-05-07 18:13:56 +00:00
|
|
|
auto si = patterns::getpatterninfo(c, patterns::PAT_COLORING, 0);
|
|
|
|
if(si.id == 8) si.dir++;
|
2019-11-14 21:24:36 +00:00
|
|
|
transmatrix D = applyPatterndir(c, si);
|
|
|
|
return &queuepolyat(V*D, shv[shvid(c)], col, prio);
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
2019-07-22 09:21:27 +00:00
|
|
|
else
|
|
|
|
return &queuepolyat(V, shv[shvid(c)], col, prio);
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 16:49:04 +00:00
|
|
|
EX void draw_floorshape(cell *c, const shiftmatrix& V, const floorshape &fsh, color_t col, PPR prio IS(PPR::DEFAULT)) {
|
2020-06-03 13:11:20 +00:00
|
|
|
if(no_wall_rendering) return;
|
2018-05-07 18:13:56 +00:00
|
|
|
draw_shapevec(c, V, fsh.b, col, prio);
|
|
|
|
}
|
|
|
|
|
2020-07-27 16:49:04 +00:00
|
|
|
EX void draw_qfi(cell *c, const shiftmatrix& V, color_t col, PPR prio IS(PPR::DEFAULT), vector<hpcshape> floorshape::* tab IS(&floorshape::b)) {
|
2020-06-03 13:11:20 +00:00
|
|
|
if(no_wall_rendering) return;
|
2018-05-07 18:13:56 +00:00
|
|
|
if(qfi.shape)
|
|
|
|
queuepolyat(V * qfi.spin, *qfi.shape, col, prio);
|
2018-08-27 17:27:35 +00:00
|
|
|
else if(qfi.usershape >= 0) {
|
|
|
|
mapeditor::drawUserShape(V * qfi.spin, mapeditor::sgFloor, qfi.usershape, col, c);
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
else if(!qfi.fshape) ;
|
|
|
|
#if CAP_TEXTURE
|
|
|
|
else if(qfi.tinf) {
|
2018-09-04 17:53:42 +00:00
|
|
|
auto& poly = queuetable(V * qfi.spin, qfi.tinf->vertices, isize(qfi.tinf->vertices), texture::config.mesh_color, texture::config.recolor(col), prio == PPR::DEFAULT ? PPR::FLOOR : prio);
|
|
|
|
poly.tinf = qfi.tinf;
|
2019-03-20 01:16:00 +00:00
|
|
|
poly.offset_texture = 0;
|
2018-09-04 17:53:42 +00:00
|
|
|
poly.flags = POLY_INVERSE;
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
else draw_shapevec(c, V, (qfi.fshape->*tab), col, prio);
|
|
|
|
}
|
|
|
|
|
2019-09-06 06:17:02 +00:00
|
|
|
EX bool floorshape_debug;
|
|
|
|
EX void viewmat() {
|
2018-08-18 15:38:07 +00:00
|
|
|
if(floorshape_debug) {
|
2020-07-27 16:49:04 +00:00
|
|
|
shiftmatrix V = ggmatrix(cwt.at);
|
2018-07-16 18:05:23 +00:00
|
|
|
|
2018-08-18 15:38:07 +00:00
|
|
|
for(int i=0; i<cwt.at->type; i++) {
|
2020-07-27 16:49:04 +00:00
|
|
|
shiftpoint ci = V * get_corner_position(cwt.at, i);
|
|
|
|
shiftpoint ci1 = V * get_corner_position(cwt.at, (i+1) % cwt.at->type);
|
2019-11-27 00:01:20 +00:00
|
|
|
|
2020-07-27 16:49:04 +00:00
|
|
|
shiftpoint cn = V * nearcorner(cwt.at, i);
|
|
|
|
shiftpoint cf0 = V * farcorner(cwt.at, i, 0);
|
|
|
|
shiftpoint cf1 = V * farcorner(cwt.at, i, 1);
|
2018-08-20 13:24:44 +00:00
|
|
|
queuestr(ci, 20, its(i), 0x0000FF, 1);
|
|
|
|
if(vid.grid)
|
|
|
|
queuestr(cn, 20, its(i), 0x00FF00, 1);
|
2019-11-27 00:01:20 +00:00
|
|
|
else
|
|
|
|
queuestr(V * currentmap->adj(cwt.at, i) * C0, 20, its(i), 0x00FFFF, 1);
|
2018-08-18 15:38:07 +00:00
|
|
|
queueline(V * C0, ci, 0xFFFFFFFF, 3);
|
|
|
|
queueline(ci, ci1, 0xFFFF00FF, 3);
|
|
|
|
queueline(ci, cn, 0xFF00FFFF, 3);
|
|
|
|
queueline(ci1, cn, 0xFF0000FF, 3);
|
|
|
|
queueline(ci, cf0, 0x00FFFFFF, 3);
|
|
|
|
queueline(cn, cf0, 0x00FF00FF, 3);
|
|
|
|
queueline(cn, cf1, 0x0000FFFF, 3);
|
|
|
|
}
|
2018-05-07 18:13:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-31 00:58:03 +00:00
|
|
|
auto floor_hook = arg::add1("-floordebug", [] { floorshape_debug = true; });
|
2019-03-11 17:46:34 +00:00
|
|
|
#endif
|
|
|
|
|
2020-07-03 12:42:33 +00:00
|
|
|
#if MAXMDIM < 4 || !CAP_GL
|
|
|
|
EX void ensure_vertex_number(basic_textureinfo& bti, int qty) {}
|
|
|
|
EX void ensure_vertex_number(hpcshape& sh) {}
|
|
|
|
EX void bind_floor_texture(hpcshape& li, int id) {}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if MAXMDIM >= 4 && CAP_GL
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2020-04-16 01:36:48 +00:00
|
|
|
EX ld floor_texture_square_size;
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void draw_shape_for_texture(floorshape* sh) {
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
int id = sh->id;
|
2019-11-29 00:50:18 +00:00
|
|
|
|
|
|
|
const ld s1 = 1;
|
|
|
|
const ld s3 = 3 * s1;
|
|
|
|
const ld sd = s1/2;
|
2019-03-16 21:15:48 +00:00
|
|
|
|
2019-11-29 00:50:18 +00:00
|
|
|
ld gx = (id % 8) * s3 - 3.5 * s3;
|
|
|
|
ld gy = (id / 8) * s3 - 3.5 * s3;
|
2019-03-16 21:15:48 +00:00
|
|
|
|
|
|
|
if(1) {
|
|
|
|
dynamicval<ld> v(vid.linewidth, 8);
|
2019-11-29 00:50:18 +00:00
|
|
|
curvepoint(eupush(gx+s1, gy-s1) * C0);
|
|
|
|
curvepoint(eupush(gx+s1, gy+s1) * C0);
|
|
|
|
curvepoint(eupush(gx-s1, gy+s1) * C0);
|
|
|
|
curvepoint(eupush(gx-s1, gy-s1) * C0);
|
|
|
|
curvepoint(eupush(gx+s1, gy-s1) * C0);
|
2020-07-27 16:49:04 +00:00
|
|
|
queuecurve(shiftless(Id), 0x000000FF, 0xFFFFFFFF - 0x1010100 * (sh->pstrength * 24/10), PPR::LAKELEV);
|
2019-03-16 21:15:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
poly_outline = 0xFFFFFFFF - 0x1010100 * (sh->pstrength * 3/2);
|
|
|
|
|
2019-03-11 17:46:34 +00:00
|
|
|
for(int a=-1; a<=1; a++)
|
|
|
|
for(int b=-1; b<=1; b++)
|
2020-07-27 16:49:04 +00:00
|
|
|
queuepoly(shiftless(eupush(gx+a, gy+b)), sh->b[0], 0xFFFFFFFF);
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
if(sh == &cgi.shCrossFloor) {
|
2020-07-27 16:49:04 +00:00
|
|
|
queuepoly(shiftless(eupush(gx, gy) * spin(M_PI/4)), cgi.shCross, 0x808080FF);
|
2019-03-16 21:15:48 +00:00
|
|
|
}
|
|
|
|
|
2019-03-11 17:46:34 +00:00
|
|
|
if(1) {
|
|
|
|
dynamicval<ld> v(vid.linewidth, 8);
|
2019-11-29 00:50:18 +00:00
|
|
|
curvepoint(eupush(gx+sd, gy-sd) * C0);
|
|
|
|
curvepoint(eupush(gx+sd, gy+sd) * C0);
|
|
|
|
curvepoint(eupush(gx-sd, gy+sd) * C0);
|
|
|
|
curvepoint(eupush(gx-sd, gy-sd) * C0);
|
|
|
|
curvepoint(eupush(gx+sd, gy-sd) * C0);
|
2020-07-27 16:49:04 +00:00
|
|
|
queuecurve(shiftless(Id), 0x40404000 + sh->fstrength * 192/10, 0, PPR::LINE);
|
2019-03-11 17:46:34 +00:00
|
|
|
}
|
|
|
|
|
2021-06-01 11:04:36 +00:00
|
|
|
for(int i=0; i<(ISMOBILE ? 10 : 1000); i++) {
|
2020-11-22 11:34:44 +00:00
|
|
|
hyperpoint h1 = hpxy(sd * (6*randd()-3), sd * (6*randd()-3));
|
|
|
|
hyperpoint h2 = hpxy(sd * (6*randd()-3), sd * (6*randd()-3));
|
2021-02-04 20:17:28 +00:00
|
|
|
ld d = hdist(h1, h2);
|
|
|
|
hyperpoint h3 = h1 + (h2-h1) /d * min(d, .1);
|
2020-11-22 11:34:44 +00:00
|
|
|
for(int a=0; a<4; a++) {
|
|
|
|
curvepoint(eupush(gx,gy) * eupush(spin(90*degree*a) * h1) * C0);
|
2021-02-04 20:17:28 +00:00
|
|
|
curvepoint(eupush(gx,gy) * eupush(spin(90*degree*a) * h3) * C0);
|
2020-11-22 11:34:44 +00:00
|
|
|
queuecurve(shiftless(Id), 0x10101010, 0, PPR::LINE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
auto& ftv = floor_texture_vertices[sh->id];
|
|
|
|
ftv.tvertices.clear();
|
|
|
|
ftv.texture_id = floor_textures->renderedTexture;
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2019-05-09 15:20:31 +00:00
|
|
|
hyperpoint center = eupush(gx, gy) * C0;
|
2019-11-29 00:50:18 +00:00
|
|
|
hyperpoint v1 = hpxyz3(sd, sd, 0, 0);
|
|
|
|
hyperpoint v2 = hpxyz3(sd, -sd, 0, 0);
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2019-10-26 08:32:44 +00:00
|
|
|
if(1) {
|
|
|
|
hyperpoint inmodel;
|
2020-07-27 16:49:04 +00:00
|
|
|
applymodel(shiftless(center), inmodel);
|
2019-10-26 08:32:44 +00:00
|
|
|
glvertex tmap;
|
2020-04-16 22:53:58 +00:00
|
|
|
tmap[0] = (1 + inmodel[0] * pconf.scale) / 2;
|
|
|
|
tmap[1] = (1 - inmodel[1] * pconf.scale) / 2;
|
2020-07-27 16:49:04 +00:00
|
|
|
applymodel(shiftless(center + v1), inmodel);
|
2020-04-16 22:53:58 +00:00
|
|
|
tmap[2] = (1 + inmodel[0] * pconf.scale) / 2 - tmap[0];
|
2019-10-26 08:32:44 +00:00
|
|
|
floor_texture_map[sh->id] = tmap;
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:36:48 +00:00
|
|
|
auto tvec_at = [&] (ld x, ld y) {
|
2020-01-18 15:03:32 +00:00
|
|
|
hyperpoint h = center + v1 * x + v2 * y;
|
|
|
|
hyperpoint inmodel;
|
2020-07-27 16:49:04 +00:00
|
|
|
applymodel(shiftless(h), inmodel);
|
2020-01-18 15:03:32 +00:00
|
|
|
glvec2 v;
|
2020-04-16 22:53:58 +00:00
|
|
|
v[0] = (1 + inmodel[0] * pconf.scale) / 2;
|
|
|
|
v[1] = (1 - inmodel[1] * pconf.scale) / 2;
|
2020-04-16 01:36:48 +00:00
|
|
|
return v;
|
|
|
|
};
|
|
|
|
|
|
|
|
// SL2 needs 6 times more
|
|
|
|
texture_order([&] (ld x, ld y) {
|
|
|
|
auto v = tvec_at(x, y);
|
2020-01-18 15:03:32 +00:00
|
|
|
ftv.tvertices.push_back(glhr::makevertex(v[0], v[1], 0));
|
|
|
|
});
|
2020-04-16 01:36:48 +00:00
|
|
|
|
|
|
|
floor_texture_square_size = 2 * (tvec_at(1, 0)[0] - tvec_at(0, 0)[0]);
|
2020-01-18 15:03:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** copy the texture vertices so that there are at least qty of them */
|
|
|
|
EX void ensure_vertex_number(basic_textureinfo& bti, int qty) {
|
|
|
|
int s = isize(bti.tvertices);
|
2020-04-06 08:43:28 +00:00
|
|
|
if(!s) return;
|
2020-01-18 15:03:32 +00:00
|
|
|
while(isize(bti.tvertices) <= qty) {
|
|
|
|
for(int i=0; i<s; i++) bti.tvertices.push_back(bti.tvertices[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** ensure_vertex_number for a hpcshape */
|
|
|
|
EX void ensure_vertex_number(hpcshape& sh) {
|
|
|
|
ensure_vertex_number(*sh.tinf, sh.e - sh.s);
|
2019-03-11 17:46:34 +00:00
|
|
|
}
|
|
|
|
|
2020-01-18 15:59:16 +00:00
|
|
|
EX void bind_floor_texture(hpcshape& li, int id) {
|
|
|
|
li.tinf = &floor_texture_vertices[id];
|
|
|
|
ensure_vertex_number(li);
|
|
|
|
}
|
|
|
|
|
2020-04-16 01:36:48 +00:00
|
|
|
#if HDR
|
2019-03-11 17:46:34 +00:00
|
|
|
const int FLOORTEXTURESIZE = 4096;
|
2020-04-16 01:36:48 +00:00
|
|
|
#endif
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void geometry_information::make_floor_textures_here() {
|
|
|
|
require_shapes();
|
2019-03-11 17:46:34 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
dynamicval<videopar> vi(vid, vid);
|
|
|
|
vid.xres = FLOORTEXTURESIZE;
|
|
|
|
vid.yres = FLOORTEXTURESIZE;
|
2020-04-16 22:53:58 +00:00
|
|
|
pconf.scale = 0.125;
|
|
|
|
pconf.camera_angle = 0;
|
|
|
|
pconf.alpha = 1;
|
2019-05-26 16:04:02 +00:00
|
|
|
dynamicval<ld> lw(vid.linewidth, 2);
|
|
|
|
|
|
|
|
floor_textures = new renderbuffer(vid.xres, vid.yres, vid.usingGL);
|
|
|
|
resetbuffer rb;
|
|
|
|
|
2019-10-26 08:32:44 +00:00
|
|
|
int q = isize(all_escher_floorshapes) + isize(all_plain_floorshapes);
|
|
|
|
floor_texture_vertices.resize(q);
|
|
|
|
floor_texture_map.resize(q);
|
2019-05-26 16:04:02 +00:00
|
|
|
|
|
|
|
auto cd = current_display;
|
|
|
|
cd->xtop = cd->ytop = 0;
|
|
|
|
cd->xsize = cd->ysize = FLOORTEXTURESIZE;
|
|
|
|
cd->xcenter = cd->ycenter = cd->scrsize = FLOORTEXTURESIZE/2;
|
|
|
|
|
2020-04-16 22:53:58 +00:00
|
|
|
cd->radius = cd->scrsize * pconf.scale;
|
2019-05-26 16:04:02 +00:00
|
|
|
|
|
|
|
floor_textures->enable();
|
2020-11-19 17:20:06 +00:00
|
|
|
#if CAP_VR
|
|
|
|
dynamicval<int> i(vrhr::state, 0);
|
|
|
|
#endif
|
2019-05-26 16:04:02 +00:00
|
|
|
floor_textures->clear(0); // 0xE8E8E8 = 1
|
|
|
|
|
|
|
|
// gradient vertices
|
|
|
|
vector<glhr::colored_vertex> gv;
|
|
|
|
gv.emplace_back(-1, -1, 0, 0, 0);
|
|
|
|
gv.emplace_back(+1, -1, 0, 0, 0);
|
|
|
|
gv.emplace_back(+1, +1, 1, 1, 1);
|
|
|
|
gv.emplace_back(-1, -1, 0, 0, 0);
|
|
|
|
gv.emplace_back(+1, +1, 1, 1, 1);
|
|
|
|
gv.emplace_back(-1, +1, 1, 1, 1);
|
2019-10-21 20:34:20 +00:00
|
|
|
|
2020-03-21 18:05:17 +00:00
|
|
|
#if CAP_RAY
|
2019-11-16 02:04:01 +00:00
|
|
|
dynamicval<bool> riu(ray::in_use, false);
|
2020-03-21 18:05:17 +00:00
|
|
|
#endif
|
2019-11-16 02:04:01 +00:00
|
|
|
|
2019-10-21 20:34:20 +00:00
|
|
|
if(1) {
|
|
|
|
current_display->next_shader_flags = GF_VARCOLOR;
|
|
|
|
dynamicval<eModel> m(pmodel, mdPixel);
|
2020-07-27 16:49:04 +00:00
|
|
|
current_display->set_all(0,0);
|
2019-10-21 20:34:20 +00:00
|
|
|
glhr::new_projection();
|
|
|
|
glhr::id_modelview();
|
|
|
|
glhr::prepare(gv);
|
|
|
|
glhr::set_depthtest(false);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, isize(gv));
|
|
|
|
}
|
2019-05-26 16:04:02 +00:00
|
|
|
|
|
|
|
shOverFloor.pstrength = 20;
|
|
|
|
shFeatherFloor.pstrength = 40;
|
|
|
|
shFeatherFloor.fstrength = 5;
|
|
|
|
shTrollFloor.pstrength = 25;
|
|
|
|
shCaveFloor.pstrength = 40;
|
|
|
|
shCaveFloor.fstrength = 0;
|
|
|
|
shDesertFloor.pstrength = 30;
|
|
|
|
shDesertFloor.fstrength =10;
|
|
|
|
shRoseFloor.pstrength = 30;
|
|
|
|
shDragonFloor.pstrength = 30;
|
|
|
|
shBarrowFloor.pstrength = 40;
|
|
|
|
|
|
|
|
// all using Tortoise
|
|
|
|
for(auto v: all_escher_floorshapes) if(v->shapeid2 == 178) v->pstrength = 20;
|
|
|
|
|
|
|
|
ptds.clear();
|
|
|
|
|
|
|
|
for(auto v: all_plain_floorshapes) draw_shape_for_texture(v);
|
|
|
|
for(auto v: all_escher_floorshapes) draw_shape_for_texture(v);
|
|
|
|
|
|
|
|
drawqueue();
|
|
|
|
|
|
|
|
/*
|
|
|
|
SDL_Surface *sdark = floor_textures->render();
|
|
|
|
IMAGESAVE(sdark, "texture-test.png");
|
|
|
|
*/
|
|
|
|
rb.reset();
|
2019-06-18 14:01:28 +00:00
|
|
|
last_texture_step = vid.texture_step;
|
2019-05-26 16:04:02 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 20:37:11 +00:00
|
|
|
EX void make_floor_textures() {
|
2019-11-09 10:18:52 +00:00
|
|
|
if(noGUI || !vid.usingGL) return;
|
2019-05-26 16:04:02 +00:00
|
|
|
DEBBI(DF_POLY, ("make_floor_textures"));
|
|
|
|
dynamicval<eGeometry> g(geometry, gEuclidSquare);
|
|
|
|
dynamicval<eModel> gm(pmodel, mdDisk);
|
|
|
|
dynamicval<eVariation> va(variation, eVariation::pure);
|
2019-08-22 09:24:25 +00:00
|
|
|
dynamicval<geometryinfo1> gie(ginf[geometry].g, giEuclid2);
|
|
|
|
dynamicval<geometryinfo1> gih(ginf[gNormal].g, giHyperb2);
|
2019-05-29 14:27:24 +00:00
|
|
|
dynamicval<bool> a3(vid.always3, false);
|
2019-05-26 16:04:02 +00:00
|
|
|
dynamicval<bool> hq(inHighQual, true);
|
|
|
|
dynamicval<int> hd(darken, 0);
|
2019-11-03 12:36:06 +00:00
|
|
|
dynamicval<ld> hll(levellines, 0);
|
2019-05-29 14:27:24 +00:00
|
|
|
dynamicval<ld> gd(vid.depth, 1);
|
|
|
|
dynamicval<ld> gc(vid.camera, 1);
|
2019-05-26 16:04:02 +00:00
|
|
|
dynamicval<geometry_information*> dcgip(cgip, cgip);
|
2019-06-24 20:30:22 +00:00
|
|
|
dynamicval<eStereo> gvs(vid.stereo_mode, sOFF);
|
|
|
|
dynamicval<int> vgp(global_projection, 0);
|
2019-05-26 16:04:02 +00:00
|
|
|
check_cgi();
|
|
|
|
cgi.make_floor_textures_here();
|
2019-08-20 10:57:05 +00:00
|
|
|
/* update texture ID in existing cgi's */
|
|
|
|
for(auto& c: cgis) c.second.models_texture.texture_id = floor_textures->renderedTexture;
|
2019-03-11 17:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2018-06-10 23:58:31 +00:00
|
|
|
}
|