New file geometry2.cpp, with moved ggmatrix, relative_matrix, virtualRebase, and new get_corner_position family. Refactored in floorpatterns, textures, and grid to use get_corner_position family.

This commit is contained in:
Zeno Rogue 2018-08-17 16:47:06 +02:00
parent 749ad03138
commit 9faa285814
18 changed files with 753 additions and 887 deletions

View File

@ -3,29 +3,6 @@
namespace hr {
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
double cellgfxdist(cell *c, int i) {
if(gp::on || irr::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i)));
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
}
transmatrix cellrelmatrix(cell *c, int i) {
if(gp::on) return shmup::calc_relative_matrix(c->mov[i], c, i);
double d = cellgfxdist(c, i);
return ddspin(c, i) * xpush(d) * iddspin(c->mov[i], c->spin(i), euclid ? 0 : S42);
}
hyperpoint randomPointIn(int t) {
while(true) {
hyperpoint h = spin(2*M_PI*(randd()-.5)/t) * tC0(xpush(asinh(randd())));
double d =
nonbitrunc ? tessf : t == 6 ? hexhexdist : crossf;
if(hdist0(h) < hdist0(xpush(-d) * h))
return spin(2*M_PI/t * (rand() % t)) * h;
}
}
struct snowball {
transmatrix T;
transmatrix global;

View File

@ -54,6 +54,7 @@ namespace hr { namespace inv { bool on, activating; } }
#include "system.cpp"
#include "debug.cpp"
#include "geometry.cpp"
#include "geometry2.cpp"
#include "polygons.cpp"
#include "floorshapes.cpp"
#include "mapeditor.cpp"

View File

@ -337,10 +337,10 @@ namespace conformal {
// virtualRebase(v[j], false);
hyperpoint prev = shmup::calc_relative_matrix(v[j-1]->base, v[j]->base, C0) *
hyperpoint prev = calc_relative_matrix(v[j-1]->base, v[j]->base, C0) *
v[j-1]->at * C0;
hyperpoint next = shmup::calc_relative_matrix(v[j+1]->base, v[j]->base, C0) *
hyperpoint next = calc_relative_matrix(v[j+1]->base, v[j]->base, C0) *
v[j+1]->at * C0;
hyperpoint hmid = mid(prev, next);
@ -352,7 +352,7 @@ namespace conformal {
}
}
hyperpoint next0 = shmup::calc_relative_matrix(v[1]->base, v[0]->base, C0) * v[1]->at * C0;
hyperpoint next0 = calc_relative_matrix(v[1]->base, v[0]->base, C0) * v[1]->at * C0;
v[0]->at = v[0]->at * rspintox(inverse(v[0]->at) * next0);
llv = ticks;
@ -376,11 +376,11 @@ namespace conformal {
viewctr.h = v[ph]->base->master;
viewctr.spin = 0;
View = inverse(shmup::master_relative(v[ph]->base) * v[ph]->at);
View = inverse(master_relative(v[ph]->base) * v[ph]->at);
hyperpoint now = v[ph]->at * C0;
hyperpoint next = shmup::calc_relative_matrix(v[ph+1]->base, v[ph]->base, C0) *
hyperpoint next = calc_relative_matrix(v[ph+1]->base, v[ph]->base, C0) *
v[ph+1]->at * C0;
View = spin(M_PI/180 * rotation) * xpush(-(phase-ph) * hdist(now, next)) * View;
@ -411,7 +411,7 @@ namespace conformal {
for(int j=0; j<siz-1; j++) {
hyperpoint next =
inverse(v[j]->at) *
shmup::calc_relative_matrix(v[j+1]->base, v[j]->base, C0) *
calc_relative_matrix(v[j+1]->base, v[j]->base, C0) *
v[j+1]->at * C0;
hyperpoint nextscr;
@ -494,7 +494,7 @@ namespace conformal {
drawfullmap();
if(last_base) {
hyperpoint last = shmup::ggmatrix(last_base) * last_relative;
hyperpoint last = ggmatrix(last_base) * last_relative;
hyperpoint hscr;
applymodel(last, hscr);
ld bwidth = -vid.radius * hscr[0];
@ -529,7 +529,7 @@ namespace conformal {
}
last_base = viewctr.h->c7;
last_relative = inverse(shmup::ggmatrix(last_base)) * C0;
last_relative = inverse(ggmatrix(last_base)) * C0;
}
}

View File

@ -55,7 +55,7 @@ bool mouseout2() {
movedir vectodir(const hyperpoint& P) {
transmatrix U = shmup::ggmatrix(cwt.c);
transmatrix U = ggmatrix(cwt.c);
hyperpoint H = sphereflip * tC0(U);
transmatrix Centered = sphereflip * rgpushxto0(H);
@ -104,14 +104,14 @@ void movepckeydir(int d) {
void calcMousedest() {
if(mouseout()) return;
if(vid.revcontrol == true) { mouseh[0] = -mouseh[0]; mouseh[1] = -mouseh[1]; }
ld mousedist = intval(mouseh, tC0(shmup::ggmatrix(cwt.c)));
ld mousedist = intval(mouseh, tC0(ggmatrix(cwt.c)));
mousedest.d = -1;
cellwalker bcwt = cwt;
ld dists[MAX_EDGE];
transmatrix U = shmup::ggmatrix(cwt.c);
transmatrix U = ggmatrix(cwt.c);
for(int i=0; i<cwt.c->type; i++) {
transmatrix T;
@ -120,7 +120,7 @@ void calcMousedest() {
else
dists[i] = HUGE_VAL;
}
// confusingGeometry() ? shmup::ggmatrix(cwt.c) * shmup::calc_relative_matrix(cwt.c->mov[i], cwt.c, i) : shmup::ggmatrix(cwt.c->mov[i])));
// confusingGeometry() ? ggmatrix(cwt.c) * calc_relative_matrix(cwt.c->mov[i], cwt.c, i) : shmup::ggmatrix(cwt.c->mov[i])));
/* printf("curcell = %Lf\n", mousedist);
for(int i=0; i<cwt.c->type; i++)

View File

@ -199,10 +199,6 @@ void bshape2(hpcshape& sh, int p, int shapeid, matrixlist& m) {
hpcpush(hpc[last->s]);
}
hyperpoint get_horopoint(ld y, ld x) {
return xpush(-y) * binary::parabolic(x) * C0;
}
void horopoint(ld y, ld x) {
hpcpush(get_horopoint(y, x));
}
@ -223,6 +219,9 @@ void horoline(ld y, ld x1, ld x2, cell &fc, int c) {
void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
fsh.b.resize(2);
fsh.shadow.resize(2);
if(binarytiling) {
bshape(fsh.b[id], fsh.prio);
@ -275,120 +274,213 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
namespace irr { void generate_floorshapes(); }
void generate_floorshapes() {
template<class T> void sizeto(T& t, int n) {
if(isize(t) <= n) t.resize(n+1);
}
if(irr::on) {
printf("generating irregular floorshapes...\n");
irr::generate_floorshapes();
printf("done\n");
return;
}
if(gp::on) {
return;
}
// !siid equals pseudohept(c)
void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
for(auto pfsh: all_plain_floorshapes) {
auto& fsh = *pfsh;
ld hexside = fsh.rad0, heptside = fsh.rad1;
fsh.b.resize(2);
fsh.shadow.resize(2);
for(int k=0; k<SIDEPARS; k++) fsh.side[k].resize(2);
int td = ((nonbitrunc || euclid) && !(S7&1)) ? S42+S6 : 0;
if(&fsh == &shBigHepta) td += S6;
int b = 0;
if(S3 == 4 && !nonbitrunc) b += S14;
bshape(fsh.b[0], fsh.prio);
if(nonbitrunc) {
if(&fsh == &shTriheptaFloor)
bshape_regular(fsh, 0, S7/2, 0, hexside);
else if(&fsh == &shBigTriangle)
bshape_regular(fsh, 0, S7/2, S12, hexside);
else
bshape_regular(fsh, 0, S7, td, heptside);
}
else if(&fsh == &shBigTriangle)
bshape_regular(fsh, 0, S3, b+S14, hexside);
else if(&fsh == &shTriheptaFloor)
bshape_regular(fsh, 0, S3, b, hexside);
else
bshape_regular(fsh, 0, S6, S7, hexside);
if(!gp::on && !irr::on) {
// standard and binary
ld hexside = fsh.rad0, heptside = fsh.rad1;
for(int k=0; k<SIDEPARS; k++) sizeto(fsh.side[k], id);
int td = ((nonbitrunc || euclid) && !(S7&1)) ? S42+S6 : 0;
if(&fsh == &shBigHepta) td += S6;
int b = 0;
if(S3 == 4 && !nonbitrunc) b += S14;
bshape_regular(fsh, 1, S7, td, heptside);
if(id == 1)
bshape_regular(fsh, 1, S7, td, heptside);
else if(nonbitrunc) {
if(&fsh == &shTriheptaFloor)
bshape_regular(fsh, 0, S7/2, 0, hexside);
else if(&fsh == &shBigTriangle)
bshape_regular(fsh, 0, S7/2, S12, hexside);
else
bshape_regular(fsh, 0, S7, td, heptside);
}
else if(&fsh == &shBigTriangle)
bshape_regular(fsh, 0, S3, b+S14, hexside);
else if(&fsh == &shTriheptaFloor)
bshape_regular(fsh, 0, S3, b, hexside);
else
bshape_regular(fsh, 0, S6, S7, hexside);
continue;
}
// special
ld sca = 3 * shFullFloor.rad0 / fsh.rad0;
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--;
ri = fixdir(ri, c);
cornerlist.push_back(mid(get_corner_position(c, ri, 3.1), get_corner_position(c, (ri+1) % c->type, 3.1)));
}
}
}
else if(&fsh == &shBigTriangle) {
if(!siid) {
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
}
else {
for(int i=0; i<cor; i++) {
int ri = i;
if((i&1) != ((sidir+siid)&1)) ri--;
ri = fixdir(ri, c);
hyperpoint nc = nearcorner(c, ri);
cornerlist.push_back(mid_at(hpxy(0,0), nc, .94));
}
}
}
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));
}
}
else {
for(int j=0; j<cor; j++)
cornerlist.push_back(get_corner_position(c, j, sca));
}
sizeto(fsh.b, id);
bshape(fsh.b[id], fsh.prio);
for(int i=0; i<=cor; i++) hpcpush(cornerlist[i%cor]);
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));
// printf("at = %d,%d cor = %d sca = %lf\n", li.relative.first, li.relative.second, cor, sca);
for(int k=0; k<SIDEPARS; k++)
for(int cid=0; cid<cor; cid++) {
sizeto(fsh.gpside[k][cid], id);
bshape(fsh.gpside[k][cid][id], fsh.prio);
hpcpush(iddspin(c, cid) * cornerlist[cid]);
hpcpush(iddspin(c, cid) * cornerlist[(cid+1)%cor]);
chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
}
for(auto pfsh: all_escher_floorshapes) {
auto& fsh = *pfsh;
generate_matrices_scale(fsh.scale, fsh.noftype);
fsh.b.resize(2);
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
auto& m = hept_matrices;
for(int id=0; id<2; id++) {
int cor = 6 + id;
hyperpoint vertices[7];
vertices[0] = get_horopoint(-yy, xx);
vertices[1] = get_horopoint(yy, 2*xx);
vertices[2] = get_horopoint(yy, xx);
vertices[3] = get_horopoint(yy, -xx);
vertices[4] = get_horopoint(yy, -2*xx);
vertices[5] = get_horopoint(-yy, -xx);
if(id) vertices[6] = get_horopoint(-yy, 0);
hyperpoint neis[7];
neis[0] = get_horopoint(0, 1);
neis[1] = get_horopoint(yy*2, 1);
neis[2] = get_horopoint(yy*2, 0);
neis[3] = get_horopoint(yy*2, -1);
neis[4] = get_horopoint(0, -1);
if(id)
neis[5] = get_horopoint(-yy*2, -.5),
neis[6] = get_horopoint(-yy*2, +.5);
else
neis[5] = get_horopoint(-yy*2, 0);
int sid = fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1;
int i = 0;
for(int d=0; d<m.o.sym; d++) {
hyperpoint center = hpxy(0,0);
for(int c=0; c<cor; c++) {
hyperpoint nlcorner = vertices[(d+c+1) % cor];
hyperpoint nrcorner = vertices[(d+c+2) % cor];
hyperpoint nfar = neis[(d+c+1) % cor];
hyperpoint nlfar = nfar;
hyperpoint nrfar = nfar;
m.v[i].second[c] = build_matrix(center, nlcorner, nrcorner);
m.v[i+1].second[c] = build_matrix(nfar, nlcorner, nrcorner);
m.v[i+2].second[c] = build_matrix(nfar, nlcorner, nlfar);
m.v[i+3].second[c] = build_matrix(nfar, nrcorner, nrfar);
}
i += 4;
}
if(i != isize(m.v)) printf("warning: i=%d sm=%d\n", i, isize(m.v));
m.n.sym = cor;
bshape2(fsh.b[id], fsh.prio, sid, hept_matrices);
sizeto(fsh.b, id);
if(!gp::on && !irr::on && !binarytiling) {
generate_matrices_scale(fsh.scale, fsh.noftype);
if(nonbitrunc && geosupport_graveyard() < 2 && fsh.shapeid2) {
if(id == 0) bshape2(fsh.b[0], fsh.prio, fsh.shapeid2, hept_matrices);
if(id == 1) bshape2(fsh.b[1], fsh.prio, fsh.shapeid2, hept_matrices);
}
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);
}
}
else if(nonbitrunc && geosupport_graveyard() < 2 && fsh.shapeid2) {
bshape2(fsh.b[0], fsh.prio, fsh.shapeid2, hept_matrices);
bshape2(fsh.b[1], fsh.prio, fsh.shapeid2, hept_matrices);
}
else {
bshape2(fsh.b[0], fsh.prio, fsh.shapeid0, hex_matrices);
bshape2(fsh.b[1], fsh.prio, fsh.shapeid1, hept_matrices);
generate_matrices_scale(fsh.scale, fsh.noftype);
auto& m = (siid && geosupport_graveyard() == 2) ? hex_matrices : hept_matrices;
int cor = c->type;
m.n.sym = cor;
int i = 0;
int v = sidir+siid;
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);
hyperpoint nrcorner = get_corner_position(c, (d+cid+v+2) % cor, 3 / fsh.scale);
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);
m.v[i].second[cid] = build_matrix(center, nlcorner, nrcorner);
m.v[i+1].second[cid] = build_matrix(nfar, nlcorner, nrcorner);
m.v[i+2].second[cid] = build_matrix(nfar, nlcorner, nlfar);
m.v[i+3].second[cid] = build_matrix(nfar, nrcorner, nrfar);
}
i += 4;
}
if(i != isize(m.v)) printf("warning: i=%d sm=%d\n", i, isize(m.v));
bshape2(fsh.b[id], fsh.prio, (fsh.shapeid2 && geosupport_graveyard() < 2) ? fsh.shapeid2 : siid?fsh.shapeid0:fsh.shapeid1, m);
}
}
}
void generate_floorshapes() {
if(irr::on) {
printf("generating irregular floorshapes...\n");
cell model;
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);
}
printf("done\n");
}
else if(gp::on) { /* will be generated on the fly */ }
else {
cell model;
model.type = S6; generate_floorshapes_for(0, &model, 0, 0);
model.type = S7; generate_floorshapes_for(1, &model, 1, 0);
}
}
namespace gp {
int pshid[3][8][32][32][8];
int nextid;
@ -404,35 +496,11 @@ namespace gp {
nextid = 0;
}
hyperpoint nearcorner(cell *c, local_info& li, int i) {
cellwalker cw(c, i);
cw += wstep;
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c, i);
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
return cwm * C0;
}
hyperpoint hypercorner(cell *c, local_info& li, int i) {
cellwalker cw(c, i);
cw += wstep;
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c, i);
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
auto li1 = get_local_info(cw.c);
return cwm * get_corner_position(li1, (cw+2).spin);
}
hyperpoint midcorner(cell *c, local_info& li, int i, ld v) {
auto hcor = hypercorner(c, li, i);
auto tcor = get_corner_position(li, i, 3);
return mid_at(tcor, hcor, v);
}
bool just_matrices = false;
map<cell*, matrixlist> usedml;
void build_plainshape(int& id, gp::local_info& li, cell *c0, int siid, int sidir) {
if(!just_matrices)
id = nextid++;
bool master = !(li.relative.first||li.relative.second);
@ -440,130 +508,8 @@ namespace gp {
if(master) li.last_dir = -1;
if(debug_geometry)
printf("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);
for(auto pfsh: all_escher_floorshapes) {
auto& fsh = *pfsh;
generate_matrices_scale(1, fsh.noftype);
auto& m = (siid && geosupport_graveyard() == 2) ? hex_matrices : hept_matrices;
m.n.sym = cor;
int i = 0;
/* if(siid == 0)
for(auto& ma: m.v) ma.first = ma.first * pispin; */
for(int d=0; d<m.o.sym; d++) {
hyperpoint center = hpxy(0,0);
for(int c=0; c<cor; c++) {
hyperpoint nlcorner = get_corner_position(li, d+c+sidir+siid+1, 3 / fsh.scale);
hyperpoint nrcorner = get_corner_position(li, d+c+sidir+siid+2, 3 / fsh.scale);
cellwalker cw(c0, c);
cw += d+sidir+siid+1;
int hint = cw.spin;
cw += wstep;
transmatrix cwm = shmup::calc_relative_matrix(cw.c, c0, hint);
hyperpoint nfar = cwm*C0;
auto li1 = get_local_info(cw.c);
hyperpoint nlfar = cwm * get_corner_position(li1, (cw+2).spin);
hyperpoint nrfar = cwm * get_corner_position(li1, (cw-1).spin);
m.v[i].second[c] = build_matrix(center, nlcorner, nrcorner);
m.v[i+1].second[c] = build_matrix(nfar, nlcorner, nrcorner);
m.v[i+2].second[c] = build_matrix(nfar, nlcorner, nlfar);
m.v[i+3].second[c] = build_matrix(nfar, nrcorner, nrfar);
}
i += 4;
}
if(i != isize(m.v)) printf("warning: i=%d sm=%d\n", i, isize(m.v));
if(just_matrices) return;
usedml[c0] = m;
fsh.b.resize(nextid);
m.n.sym = cor;
bshape2(fsh.b[id], fsh.prio, (fsh.shapeid2 && geosupport_graveyard() < 2) ? fsh.shapeid2 : siid?fsh.shapeid0:fsh.shapeid1, m);
}
for(auto pfsh: all_plain_floorshapes) {
auto& fsh = *pfsh;
ld sca = 3 * shFullFloor.rad0 / fsh.rad0;
fsh.b.resize(nextid);
vector<hyperpoint> cornerlist;
if(&fsh == &shTriheptaFloor) {
if(!siid) {
for(int i=0; i<cor; i++)
cornerlist.push_back(midcorner(c0, li, i, .49));
}
else {
for(int i=0; i<cor; i++) {
int ri = i;
if((i&1) == ((sidir+siid)&1)) ri--;
cornerlist.push_back(mid(get_corner_position(li, ri, 3.1), get_corner_position(li, ri+1, 3.1)));
}
}
}
else if(&fsh == &shBigTriangle) {
if(!siid) {
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
}
else {
for(int i=0; i<cor; i++) {
int ri = i;
if((i&1) != ((sidir+siid)&1)) ri--;
ri = fixdir(ri, c0);
hyperpoint nc = nearcorner(c0, li, ri);
cornerlist.push_back(mid_at(hpxy(0,0), nc, .94));
}
}
}
else if(&fsh == &shBigHepta) {
if(!siid) {
for(int i=0; i<cor; i++) {
hyperpoint nc = nearcorner(c0, li, 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));
}
}
else {
for(int j=0; j<cor; j++)
cornerlist.push_back(get_corner_position(li, j, sca));
}
bshape(fsh.b[id], fsh.prio);
for(int i=0; i<=cor; i++) hpcpush(cornerlist[i%cor]);
fsh.shadow.resize(nextid);
bshape(fsh.shadow[id], fsh.prio);
for(int i=0; i<=cor; i++)
hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL));
cell fc;
fc.type = cor;
// printf("at = %d,%d cor = %d sca = %lf\n", li.relative.first, li.relative.second, cor, sca);
for(int k=0; k<SIDEPARS; k++)
for(int c=0; c<cor; c++) {
fsh.gpside[k][c].resize(nextid);
bshape(fsh.gpside[k][c][id], fsh.prio);
hpcpush(iddspin(&fc, c) * cornerlist[c]);
hpcpush(iddspin(&fc, c) * cornerlist[(c+1)%cor]);
chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
}
generate_floorshapes_for(id, c0, siid, sidir);
finishshape(); last = NULL;
extra_vertices();
@ -593,163 +539,6 @@ namespace gp {
}
}
namespace irr {
map<int, matrixlist> usedml;
void generate_floorshapes() {
if(irr::cells.empty()) return;
int cc = isize(irr::cells);
for(auto pfsh: all_escher_floorshapes) {
auto& fsh = *pfsh;
generate_matrices_scale(1, fsh.noftype);
/* if(siid == 0)
for(auto& ma: m.v) ma.first = ma.first * pispin; */
fsh.b.resize(cc);
for(int id=0; id<cc; id++) {
auto& vs = irr::cells[id];
auto& m = (geosupport_graveyard() == 2 && !vs.is_pseudohept) ? hex_matrices : hept_matrices;
int cor = isize(vs.vertices);
m.n.sym = cor;
int i = 0;
for(int d=0; d<m.o.sym; d++) {
hyperpoint center = hpxy(0,0);
for(int c=0; c<cor; c++) {
hyperpoint nlcorner = vs.vertices[(d+c+1) % cor];
hyperpoint nrcorner = vs.vertices[(d+c+2) % cor];
int neid = vs.neid[(d+c+1) % cor];
int spin = vs.spin[(d+c+1) % cor];
auto &vs2 = irr::cells[neid];
int cor2 = isize(vs2.vertices);
hyperpoint nfar = vs.jpoints[neid];
transmatrix rel = vs.rpusher * vs.relmatrices[vs2.owner] * vs2.pusher;
hyperpoint nlfar = rel * vs2.vertices[(spin+2)%cor2];
hyperpoint nrfar = rel * vs2.vertices[(spin+cor2-1)%cor2];
m.v[i].second[c] = build_matrix(center, nlcorner, nrcorner);
m.v[i+1].second[c] = build_matrix(nfar, nlcorner, nrcorner);
m.v[i+2].second[c] = build_matrix(nfar, nlcorner, nlfar);
m.v[i+3].second[c] = build_matrix(nfar, nrcorner, nrfar);
}
i += 4;
}
usedml[id] = m;
m.n.sym = cor;
bshape2(fsh.b[id], fsh.prio, (fsh.shapeid2 && geosupport_graveyard() < 2) ? fsh.shapeid2 : !vs.is_pseudohept?fsh.shapeid0:fsh.shapeid1, m);
}
}
for(auto pfsh: all_plain_floorshapes) {
auto& fsh = *pfsh;
ld sca = fsh.rad0 / shFullFloor.rad0;
fsh.b.resize(cc);
fsh.shadow.resize(cc);
for(int i=0; i<cc; i++) {
auto& vs = irr::cells[i];
vector<hyperpoint> cornerlist;
int cor = isize(vs.vertices);
if(&fsh == &shBigTriangle) {
if(vs.is_pseudohept) {
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
}
else for(int i=0; i<cor; i++) {
int ri = i;
if(!irr::cells[vs.neid[i]].is_pseudohept) ri--;
if(ri<0) ri += cor;
hyperpoint nc = vs.jpoints[vs.neid[ri]];
cornerlist.push_back(mid_at(C0, nc, .94));
}
}
else if(&fsh == &shBigHepta) {
if(vs.is_pseudohept) {
for(int i=0; i<cor; i++) {
cornerlist.push_back(mid_at(hpxy(0,0), vs.jpoints[vs.neid[i]], .94));
}
}
else {
for(int i=0; i<cor; i++) cornerlist.push_back(hpxy(0,0));
}
}
else if(&fsh == &shTriheptaFloor) {
if(vs.is_pseudohept) {
for(int i=0; i<cor; i++) {
int neid = vs.neid[i];
int spin = vs.spin[i];
auto &vs2 = irr::cells[neid];
int cor2 = isize(vs2.vertices);
hyperpoint nfar = vs.vertices[i];
transmatrix rel = vs.rpusher * vs.relmatrices[vs2.owner] * vs2.pusher;
hyperpoint nlfar = rel * vs2.vertices[(spin+2)%cor2];
cornerlist.push_back(mid_at(nfar, nlfar, .49));
/*
hyperpoint next = vs.jpoints[vs.neid[i]];
hyperpoint last = vs.jpoints[vs.neid[(i+cor-1)%cor]];
cornerlist.push_back(mid_at(C0, mid(next, last), .98));
*/
}
}
else {
for(int i=0; i<cor; i++) {
int ri = i;
if(irr::cells[vs.neid[i]].is_pseudohept) ri--;
if(ri<0) ri += cor;
cornerlist.push_back(mid_at(C0, mid(vs.vertices[ri], vs.vertices[(ri+1)%cor]), .97));
}
}
}
else for(int j=0; j<cor; j++)
cornerlist.push_back(mid_at_actual(vs.vertices[j], sca));
bshape(fsh.b[i], fsh.prio);
for(int j=0; j<=cor; j++) hpcpush(cornerlist[j%cor]);
bshape(fsh.shadow[i], fsh.prio);
for(int j=0; j<=cor; j++)
hpcpush(mid_at(hpxy(0,0), cornerlist[j%cor], SHADMUL));
cell fc;
fc.type = cor;
irr::cellindex[&fc] = i;
// printf("at = %d,%d cor = %d sca = %lf\n", li.relative.first, li.relative.second, cor, sca);
for(int k=0; k<SIDEPARS; k++)
for(int c=0; c<cor; c++) {
fsh.gpside[k][c].resize(cc);
bshape(fsh.gpside[k][c][i], fsh.prio);
hpcpush(iddspin(&fc, c) * cornerlist[c]);
hpcpush(iddspin(&fc, c) * cornerlist[(c+1)%cor]);
chasmifyPoly(dlow_table[k], dhi_table[k], k);
}
}
}
finishshape(); last = NULL;
extra_vertices();
}
}
qfloorinfo qfi;
qfloorinfo qfi_dc;

472
geometry2.cpp Normal file
View File

@ -0,0 +1,472 @@
// Hyperbolic Rogue
// advanced geometry
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
namespace hr {
transmatrix &ggmatrix(cell *c);
void fixelliptic(transmatrix& at) {
if(elliptic && at[2][2] < 0) {
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
at[i][j] = -at[i][j];
}
}
void fixelliptic(hyperpoint& h) {
if(elliptic && h[2] < 0)
for(int i=0; i<3; i++) h[i] = -h[i];
}
transmatrix master_relative(cell *c, bool get_inverse) {
if(irr::on) {
int id = irr::cellindex[c];
ld alpha = 2 * M_PI / S7 * irr::periodmap[c->master].base.spin;
return get_inverse ? irr::cells[id].rpusher * spin(-alpha-master_to_c7_angle()): spin(alpha + master_to_c7_angle()) * irr::cells[id].pusher;
}
else if(gp::on) {
if(c == c->master->c7) {
return spin((get_inverse?-1:1) * master_to_c7_angle());
}
else {
auto li = gp::get_local_info(c);
transmatrix T = spin(master_to_c7_angle()) * gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][gp::fixg6(li.total_dir)];
if(get_inverse) T = inverse(T);
return T;
}
}
else if(!nonbitrunc && !euclid) {
for(int d=0; d<S7; d++) if(c->master->c7->mov[d] == c)
return (get_inverse?invhexmove:hexmove)[d];
return Id;
}
else
return pispin * Id;
}
transmatrix calc_relative_matrix(cell *c2, cell *c1, int direction_hint) {
return calc_relative_matrix(c2, c1, ddspin(c1, direction_hint) * xpush(1e-2) * C0);
}
// target, source, direction from source to target
namespace gp { extern gp::local_info draw_li; }
transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
if(sphere) {
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
auto bak = gp::draw_li;
swap(gmatrix, gmatrix0);
just_gmatrix = true;
drawrec(viewctr, hsOrigin, Id);
just_gmatrix = false;
swap(gmatrix, gmatrix0);
gp::draw_li = bak;
}
if(gmatrix0.count(c2) && gmatrix0.count(c1)) {
transmatrix T = inverse(gmatrix0[c1]) * gmatrix0[c2];
if(elliptic && T[2][2] < 0)
T = centralsym * T;
return T;
}
else {
printf("error: gmatrix0 not known\n");
return Id;
}
}
if(binarytiling) return binary::relative_matrix(c2->master, c1->master);
if(syntetic) return synt::relative_matrix(c2->master, c1->master);
if(torus) {
transmatrix t = Id;
if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));
int mirrors = 0;
approach:
int d = celldistance(c2, c1);
forCellIdEx(c3, i, c2) {
if(celldistance(c3, c1) < d) {
if(whateveri) printf(" %d [%p,%d]", i, c3, celldistance(c3, c1));
if(c2->type < 8)
t = eumovedir(i+(euclid6?3:2)) * t;
else if(i&1)
t = eumovedir(2+i/2) * eumovedir(2+(i+1)/2) * t;
else
t = eumovedir(2+i/2) * t;
if(c2->mirror(i)) mirrors++;
c2 = c3;
goto approach;
}
}
if(d != 0) printf("ERROR not reached\n");
if(mirrors&1) t = Mirror * t * Mirror;
if(whateveri) printf(" => %p\n", c1);
return t;
}
if(euclid) return inverse(gmatrix0[c1]) * gmatrix0[c2];
heptagon *h1 = c1->master;
transmatrix gm = master_relative(c1, true);
heptagon *h2 = c2->master;
transmatrix where = master_relative(c2);
// always add to last!
//bool hsol = false;
//transmatrix sol;
while(h1 != h2) {
if(quotient & qSMALL) {
transmatrix T;
ld bestdist = 1e9;
for(int d=0; d<S7; d++) if(h2->move[d]) {
int sp = h2->spin(d);
transmatrix S = heptmove[sp] * spin(2*M_PI*d/S7);
if(h2->move[d] == h1) {
transmatrix T1 = gm * S * where;
auto curdist = hdist(tC0(T1), point_hint);
if(curdist < bestdist) T = T1, bestdist = curdist;
}
for(int e=0; e<S7; e++) if(h2->move[d]->move[e] == h1) {
int sp2 = h2->move[d]->spin(e);
transmatrix T1 = gm * heptmove[sp2] * spin(2*M_PI*e/S7) * S * where;
auto curdist = hdist(tC0(T1), point_hint);
if(curdist < bestdist) T = T1, bestdist = curdist;
}
}
if(bestdist < 1e8) return T;
}
for(int d=0; d<S7; d++) if(h2->move[d] == h1) {
int sp = h2->spin(d);
return gm * heptmove[sp] * spin(2*M_PI*d/S7) * where;
}
if(geometry == gFieldQuotient) {
int bestdist = 1000, bestd = 0;
for(int d=0; d<S7; d++) {
int dist = celldistance(h2->move[d]->c7, c1);
if(dist < bestdist) bestdist = dist, bestd = d;
}
int sp = h2->spin(bestd);
where = heptmove[sp] * spin(2*M_PI*bestd/S7) * where;
h2 = h2->move[bestd];
}
else if(h1->distance < h2->distance) {
int sp = h2->spin(0);
h2 = h2->move[0];
where = heptmove[sp] * where;
}
else {
int sp = h1->spin(0);
h1 = h1->move[0];
gm = gm * invheptmove[sp];
}
}
/*if(hsol) {
transmatrix sol2 = gm * where;
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
if(fabs(sol2[i][j]-sol[i][j] > 1e-3)) {
printf("ERROR\n");
display(sol);
display(sol2);
exit(1);
}
} */
return gm * where;
}
transmatrix &ggmatrix(cell *c) {
transmatrix& t = gmatrix[c];
if(t[2][2] == 0) {
if(torus && centerover.c)
t = calc_relative_matrix(c, centerover.c, C0);
else if(euclid) {
if(!centerover.c) centerover = cwt;
t = View * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
}
else
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h->c7, C0);
}
return t;
}
transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) {
transmatrix gm = Id;
heptagon *h2 = c->master;
transmatrix where = Id;
if(gp::on && c != c->master->c7) {
auto li = gp::get_local_info(c);
where = gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)];
}
else if(!nonbitrunc) for(int d=0; d<S7; d++) if(h2->c7->mov[d] == c)
where = hexmove[d];
// always add to last!
while(h1 != h2) {
for(int d=0; d<S7; d++) if(h1->move[d] == h2) printf("(adj) ");
if(h1->distance < h2->distance) {
int sp = h2->spin(0);
printf("A%d ", sp);
h2 = h2->move[0];
where = heptmove[sp] * where;
}
else {
int sp = h1->spin(0);
printf("B%d ", sp);
h1 = h1->move[0];
gm = gm * invheptmove[sp];
}
}
printf("OK\n");
display(gm * where);
return gm * where;
}
template<class T, class U>
void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
if(euclid || sphere) {
again:
if(torus) for(int i=0; i<6; i++) {
auto newat = eumovedir(3+i) * at;
if(hdist0(check(newat)) < hdist0(check(at))) {
at = newat;
base = createMov(base, i);
goto again;
}
}
else forCellCM(c2, base) {
auto newat = inverse(ggmatrix(c2)) * ggmatrix(base) * at;
if(hypot(check(newat)[0], check(newat)[1])
< hypot(check(at)[0], check(at)[1])) {
at = newat;
base = c2;
goto again;
}
}
fixelliptic(at);
return;
}
at = master_relative(base) * at;
base = base->master->c7;
while(true) {
double currz = check(at)[2];
heptagon *h = base->master;
cell *newbase = NULL;
transmatrix bestV;
for(int d=0; d<S7; d++) {
heptspin hs;
hs.h = h;
hs.spin = d;
heptspin hs2 = hs + wstep;
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * invheptmove[d];
double newz = check(V2 * at) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
newbase = hs2.h->c7;
}
}
if(newbase) {
base = newbase;
at = bestV * at;
}
else {
if(tohex && !nonbitrunc) for(int d=0; d<S7; d++) {
cell *c = createMov(base, d);
transmatrix V2 = spin(-base->spn(d)*2*M_PI/S6) * invhexmove[d];
double newz = check(V2 *at) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
newbase = c;
}
}
if(newbase) {
base = newbase;
at = bestV * at;
}
else at = master_relative(base, true) * at;
break;
}
}
}
void virtualRebase(cell*& base, transmatrix& at, bool tohex) {
virtualRebase(base, at, tohex, tC0);
}
void virtualRebase(cell*& base, hyperpoint& h, bool tohex) {
virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return h; });
}
double cellgfxdist(cell *c, int i) {
if(gp::on || irr::on) return hdist0(tC0(calc_relative_matrix(c->mov[i], c, i)));
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
}
transmatrix cellrelmatrix(cell *c, int i) {
if(gp::on) return calc_relative_matrix(c->mov[i], c, i);
double d = cellgfxdist(c, i);
return ddspin(c, i) * xpush(d) * iddspin(c->mov[i], c->spin(i), euclid ? 0 : S42);
}
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
hyperpoint randomPointIn(int t) {
while(true) {
hyperpoint h = spin(2*M_PI*(randd()-.5)/t) * tC0(xpush(asinh(randd())));
double d =
nonbitrunc ? tessf : t == 6 ? hexhexdist : crossf;
if(hdist0(h) < hdist0(xpush(-d) * h))
return spin(2*M_PI/t * (rand() % t)) * h;
}
}
hyperpoint get_horopoint(ld y, ld x) {
return xpush(-y) * binary::parabolic(x) * C0;
}
hyperpoint get_corner_position(cell *c, int cid, ld cf = 3) {
if(gp::on) return gp::get_corner_position(c, cid, cf);
if(irr::on) {
auto& vs = irr::cells[irr::cellindex[c]];
return mid_at_actual(vs.vertices[cid], 3/cf);
}
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
hyperpoint vertices[7];
vertices[0] = get_horopoint(-yy, xx);
vertices[1] = get_horopoint(yy, 2*xx);
vertices[2] = get_horopoint(yy, xx);
vertices[3] = get_horopoint(yy, -xx);
vertices[4] = get_horopoint(yy, -2*xx);
vertices[5] = get_horopoint(-yy, -xx);
vertices[6] = get_horopoint(-yy, 0);
return mid_at_actual(vertices[cid], 3/cf);
}
if(nonbitrunc) {
return ddspin(c,cid,S6) * xpush0(hcrossf * 3 / cf);
}
if(!nonbitrunc) {
if(!ishept(c))
return ddspin(c,cid,S7) * xpush0(hexvdist * 3 / cf);
else
return ddspin(c,cid,S6) * xpush0(rhexf * 3 / cf);
}
return C0;
}
hyperpoint hypercorner(cell *c, gp::local_info& li, int i) {
cellwalker cw(c, i);
cw += wstep;
transmatrix cwm = calc_relative_matrix(cw.c, c, i);
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
return cwm * gp::get_corner_position(cw.c, (cw+2).spin);
}
hyperpoint midcorner(cell *c, int i, ld v) {
if(gp::on) {
auto li = gp::get_local_info(c);
auto hcor = hypercorner(c, li, i);
auto tcor = get_corner_position(li, i, 3);
return mid_at(tcor, hcor, v);
}
if(irr::on) {
auto& vs = irr::cells[irr::cellindex[c]];
int neid = vs.neid[i];
int spin = vs.spin[i];
auto &vs2 = irr::cells[neid];
int cor2 = isize(vs2.vertices);
hyperpoint nfar = vs.vertices[i];
transmatrix rel = vs.rpusher * vs.relmatrices[vs2.owner] * vs2.pusher;
hyperpoint nlfar = rel * vs2.vertices[(spin+2)%cor2];
return mid_at(nfar, nlfar, .49);
}
printf("midcorner not handled\n");
exit(1);
}
hyperpoint nearcorner(cell *c, int i) {
if(gp::on) {
cellwalker cw(c, i);
cw += wstep;
transmatrix cwm = calc_relative_matrix(cw.c, c, i);
if(elliptic && cwm[2][2] < 0) cwm = centralsym * cwm;
return cwm * C0;
}
if(irr::on) {
auto& vs = irr::cells[irr::cellindex[c]];
hyperpoint nc = vs.jpoints[vs.neid[i]];
return mid_at(C0, nc, .94);
}
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
// ld xx = 1 / sqrt(2)/2;
hyperpoint neis[7];
neis[0] = get_horopoint(0, 1);
neis[1] = get_horopoint(yy*2, 1);
neis[2] = get_horopoint(yy*2, 0);
neis[3] = get_horopoint(yy*2, -1);
neis[4] = get_horopoint(0, -1);
if(c->type == 7)
neis[5] = get_horopoint(-yy*2, -.5),
neis[6] = get_horopoint(-yy*2, +.5);
else
neis[5] = get_horopoint(-yy*2, 0);
return neis[i];
}
printf("nearcorner not handled\n");
exit(1);
}
hyperpoint farcorner(cell *c, int i, int which) {
if(gp::on) {
cellwalker cw(c, i);
int hint = cw.spin;
cw += wstep;
transmatrix cwm = calc_relative_matrix(cw.c, c, hint);
// hyperpoint nfar = cwm*C0;
auto li1 = gp::get_local_info(cw.c);
if(which == 0)
return cwm * get_corner_position(li1, (cw+2).spin);
if(which == 1)
return cwm * get_corner_position(li1, (cw-1).spin);
}
if(irr::on) {
auto& vs = irr::cells[irr::cellindex[c]];
int neid = vs.neid[i];
int spin = vs.spin[i];
auto &vs2 = irr::cells[neid];
int cor2 = isize(vs2.vertices);
transmatrix rel = vs.rpusher * vs.relmatrices[vs2.owner] * vs2.pusher;
if(which == 0) return rel * vs2.vertices[(spin+2)%cor2];
if(which == 1) return rel * vs2.vertices[(spin+cor2-1)%cor2];
}
if(binarytiling)
return nearcorner(c, (i+which) % c->type); // lazy
printf("farcorner not handled\n");
exit(1);
}
hyperpoint get_warp_corner(cell *c, int cid) {
if(gp::on) return gp::get_corner_position(c, cid, 2);
if(irr::on) return midcorner(c, cid, .5);
return ddspin(c,cid,S6) * xpush0(tessf/2);
}
}

View File

@ -633,7 +633,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks,
cell *c1 = c ? findcompass(c) : NULL;
transmatrix V2;
if(c1) {
transmatrix P = shmup::ggmatrix(c1);
transmatrix P = ggmatrix(c1);
hyperpoint P1 = tC0(P);
if(isPlayerOn(c)) {
@ -2110,7 +2110,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir));
}
else if(gp::on || irr::on) {
transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c, c->mondir);
transmatrix T = calc_relative_matrix(c->mov[c->mondir], c, c->mondir);
Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length);
}
else {
@ -4721,7 +4721,10 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
}
if(vid.grid) {
vid.linewidth *= 3;
dynamicval<ld> lw(vid.linewidth, vid.linewidth);
if(gp::on) vid.linewidth *= gp::scale * 2;
// sphere: 0.3948
// sphere heptagonal: 0.5739
// sphere trihepta: 0.3467
@ -4733,29 +4736,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
int prec = sphere ? 3 : 1;
prec += vid.linequality;
if(irr::on) {
int id = irr::cellindex[c];
auto &vs = irr::cells[id];
for(int t=0; t<c->type; t++)
if(c->mov[t] && c->mov[t] < c)
queueline(V * vs.vertices[t], V * vs.vertices[(1+t)%c->type], gridcolor(c, c->mov[t]), prec);
}
else if(gp::on) {
vid.linewidth *= gp::scale * 2;
if(isWarped(c) && has_nice_dual()) {
if(pseudohept(c)) for(int t=0; t<c->type; t++)
queueline(V * gp::get_corner_position(c, t%c->type, 2),
V * gp::get_corner_position(c, (t+1)%c->type, 2),
gridcolor(c, c->mov[t]), prec);
}
else for(int t=0; t<c->type; t++)
if(c->mov[t] && c->mov[t] < c)
queueline(V * gp::get_corner_position(c, t),
V * gp::get_corner_position(c, (t+1)%c->type),
gridcolor(c, c->mov[t]), prec);
vid.linewidth /= gp::scale * 2;
}
else if(binarytiling) {
if(binarytiling) {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
@ -4771,31 +4752,19 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
horizontal(yy, xx, -xx, 8, binary::bd_up);
horizontal(yy, -xx, -2*xx, 4, binary::bd_up_left);
}
else if(nonbitrunc) {
double x = hcrossf;
for(int t=0; t<S7; t++)
if(c->mov[t] && c->mov[t] < c)
queueline(V * ddspin(c,t,-S6) * xpush0(x),
V * ddspin(c,t,S6) * xpush0(x),
else if(isWarped(c) && has_nice_dual()) {
if(pseudohept(c)) for(int t=0; t<c->type; t++)
queueline(V * get_warp_corner(c, t%c->type),
V * get_warp_corner(c, (t+1)%c->type),
gridcolor(c, c->mov[t]), prec);
}
else if(isWarped(c)) {
double x = hexhexdist/2;
if(!ishept(c)) for(int t=0; t<S6; t++) if(c->mov[t] && ishept(c->mov[t]))
queueline(V * ddspin(c,t,-S14) * xpush0(x),
V * ddspin(c,t,+S14) * xpush0(x),
gridcolor(c, c->mov[t]), prec);
}
else if(ishept(c) && !(euclid&&!a4)) ;
else {
double x = hexvdist;
for(int t=0; t< S6; t++)
if((euclid&&!a4) ? c->mov[t]<c : (((t^1)&1) || c->mov[t] < c))
queueline(V * ddspin(c,t,-S7) * xpush0(x),
V * ddspin(c,t,+S7) * xpush0(x),
for(int t=0; t<c->type; t++)
if(true) // c->mov[t] && c->mov[t] < c)
queueline(V * get_corner_position(c, t),
V * get_corner_position(c, (t+1)%c->type),
gridcolor(c, c->mov[t]), prec);
}
vid.linewidth /= 3;
}
if(!euclid) {
@ -4996,7 +4965,7 @@ void drawMarkers() {
if(inscreenrange(c))
keycell = c;
}
hyperpoint H = tC0(shmup::ggmatrix(keycell));
hyperpoint H = tC0(ggmatrix(keycell));
queuechr(H, 2*vid.fsize, 'X', 0x10101 * int(128 + 100 * sin(ticks / 150.)));
queuestr(H, vid.fsize, its(celldistance(cwt.c, yi[yii].key())), 0x10101 * int(128 - 100 * sin(ticks / 150.)));
addauraspecial(H, iinf[itOrbYendor].color, 0);
@ -5037,7 +5006,7 @@ void drawMarkers() {
if((vid.axes == 4 || (vid.axes == 1 && !mousing)) && !shmup::on) {
if(multi::players == 1) {
forCellIdAll(c2, d, cwt.c) IG(c2) drawMovementArrows(c2, confusingGeometry() ? Gm(cwt.c) * shmup::calc_relative_matrix(c2, cwt.c, d) : Gm(c2));
forCellIdAll(c2, d, cwt.c) IG(c2) drawMovementArrows(c2, confusingGeometry() ? Gm(cwt.c) * calc_relative_matrix(c2, cwt.c, d) : Gm(c2));
}
else if(multi::players > 1) for(int p=0; p<multi::players; p++) {
if(multi::playerActive(p) && (vid.axes == 4 || !drawstaratvec(multi::mdx[p], multi::mdy[p])))
@ -5045,7 +5014,7 @@ void drawMarkers() {
multi::cpid = p;
dynamicval<transmatrix> ttm(cwtV, multi::whereis[p]);
dynamicval<cellwalker> tcw(cwt, multi::player[p]);
drawMovementArrows(c2, confusingGeometry() ? Gm(cwt.c) * shmup::calc_relative_matrix(c2, cwt.c, d) : Gm(c2));
drawMovementArrows(c2, confusingGeometry() ? Gm(cwt.c) * calc_relative_matrix(c2, cwt.c, d) : Gm(c2));
}
}
}
@ -5090,7 +5059,7 @@ void drawFlashes() {
flashes.pop_back(); k--;
continue;
}
else V = shmup::ggmatrix(f.where);
else V = ggmatrix(f.where);
int tim = ticks - f.t;
@ -5443,8 +5412,8 @@ void drawfullmap() {
if(conformal::on) {
char ch = 'A';
for(auto& v: conformal::v) {
queuepoly(shmup::ggmatrix(v->base) * v->at, shTriangle, 0x306090C0);
queuechr(shmup::ggmatrix(v->base) * v->at * C0, 10, ch++, 0xFF0000);
queuepoly(ggmatrix(v->base) * v->at, shTriangle, 0x306090C0);
queuechr(ggmatrix(v->base) * v->at * C0, 10, ch++, 0xFF0000);
}
}
*/
@ -5813,7 +5782,7 @@ int revhint(cell *c, int hint) {
bool compute_relamatrix(cell *src, cell *tgt, int direction_hint, transmatrix& T) {
if(confusingGeometry()) {
T = shmup::calc_relative_matrix(src, tgt, revhint(src, direction_hint));
T = calc_relative_matrix(src, tgt, revhint(src, direction_hint));
}
else {
if(gmatrix.count(src) && gmatrix.count(tgt))
@ -5893,7 +5862,7 @@ void animateReplacement(cell *a, cell *b, int layer, int direction_hinta, int di
void drawBug(const cellwalker& cw, int col) {
#if CAP_POLY
initquickqueue();
transmatrix V = shmup::ggmatrix(cw.c);
transmatrix V = ggmatrix(cw.c);
if(cw.spin) V = V * ddspin(cw.c, cw.spin, S42);
queuepoly(V, shBugBody, col);
quickqueue();

View File

@ -326,7 +326,7 @@ void drawMobileArrow(int i) {
ld scale = vid.mobilecompasssize * (sphere ? 7 : euclid ? 6 : 5);
// m2[0][0] = scale; m2[1][1] = scale; m2[2][2] = 1;
transmatrix U = shmup::ggmatrix(cwt.c);
transmatrix U = ggmatrix(cwt.c);
hyperpoint H = sphereflip * tC0(U);
transmatrix Centered = sphereflip * rgpushxto0(H);

15
hyper.h
View File

@ -718,16 +718,9 @@ namespace shmup {
void destroyBoats(cell *c);
bool boatAt(cell *c);
void virtualRebase(cell*& base, transmatrix& at, bool tohex);
void virtualRebase(cell*& base, hyperpoint& h, bool tohex);
void virtualRebase(shmup::monster *m, bool tohex);
transmatrix calc_relative_matrix(cell *c, cell *c1, const hyperpoint& point_hint);
transmatrix calc_relative_matrix(cell *c, cell *c1, int direction_hint);
void fixStorage();
void addShmupHelp(string& out);
void activateArrow(cell *c);
transmatrix& ggmatrix(cell *c);
transmatrix master_relative(cell *c, bool get_inverse = false);
void pushmonsters();
void popmonsters();
@ -739,8 +732,16 @@ namespace shmup {
void turn(int);
extern monster *lmousetarget;
void virtualRebase(shmup::monster *m, bool tohex);
}
transmatrix& ggmatrix(cell *c);
transmatrix master_relative(cell *c, bool get_inverse = false);
void virtualRebase(cell*& base, transmatrix& at, bool tohex);
void virtualRebase(cell*& base, hyperpoint& h, bool tohex);
transmatrix calc_relative_matrix(cell *c, cell *c1, const hyperpoint& point_hint);
transmatrix calc_relative_matrix(cell *c, cell *c1, int direction_hint);
static const int NOHINT = -1;
// graph

View File

@ -580,7 +580,7 @@ void drawrec(cell *c, const transmatrix& V) {
void drawrec(const heptspin& hs, hstate s, const transmatrix& V) {
// shmup::calc_relative_matrix(cwt.c, hs.h);
// calc_relative_matrix(cwt.c, hs.h);
cell *c = hs.h->c7;

View File

@ -106,12 +106,12 @@ int black_adjacent, white_three;
void set_relmatrices(cellinfo& ci) {
auto& all = base->allcells();
ci.relmatrices.clear();
for(auto c0: all) ci.relmatrices[c0] = shmup::calc_relative_matrix(c0, ci.owner, ci.p);
for(auto c0: all) ci.relmatrices[c0] = calc_relative_matrix(c0, ci.owner, ci.p);
}
void rebase(cellinfo& ci) {
cell *cx = ci.owner;
shmup::virtualRebase(ci.owner, ci.p, false);
virtualRebase(ci.owner, ci.p, false);
if(ci.owner != cx) {
printf("rebased %p to %p\n", cx, ci.owner);
set_relmatrices(ci);
@ -158,7 +158,7 @@ void bitruncate() {
s.neid.push_back(-1);
s.neid.push_back(next);
s.neid.push_back(-1);
shmup::virtualRebase(s.owner, s.p, false);
virtualRebase(s.owner, s.p, false);
set_relmatrices(s);
}
}
@ -262,7 +262,7 @@ bool step(int delta) {
cell *c = all[k];
map<cell*, transmatrix> relmatrices;
hyperpoint h = randomPointIn(c->type);
for(auto c0: all) relmatrices[c0] = shmup::calc_relative_matrix(c0, c, h);
for(auto c0: all) relmatrices[c0] = calc_relative_matrix(c0, c, h);
ld mindist = 1e6;
for(auto p: cells) {
if(!relmatrices.count(p.owner)) continue;
@ -490,7 +490,7 @@ bool step(int delta) {
ld dists[8];
for(int i=0; i<S7; i++) {
dists[i] = hdist(s.p, spin(hexshift - i * ALPHA) * xpush(-hcrossf) * C0);
// shmup::calc_relative_matrix(s.owner->mov[i], s.owner, s.p) * C0);
// calc_relative_matrix(s.owner->mov[i], s.owner, s.p) * C0);
// spin(2 * M_PI * i / S7) * xpush(hcrossf) * C0);
if(dists[i] < dist)
d = i, dist = dists[i];
@ -537,7 +537,7 @@ bool draw_cell_schematics(cell *c, transmatrix V) {
queueline(V * p.p, V * C0, 0xFF0000FF);
if(p.patterndir != -1)
queueline(V * p.p, V * shmup::calc_relative_matrix(c->master->move[p.patterndir]->c7, c, p.p) * C0, 0x00FF00FF);
queueline(V * p.p, V * calc_relative_matrix(c->master->move[p.patterndir]->c7, c, p.p) * C0, 0x00FF00FF);
}
}
}
@ -864,7 +864,7 @@ bool load_map(const string &fname) {
double a, b, c;
ignore(fscanf(f, "%lf%lf%lf", &a, &b, &c));
s.p = hpxyz(a, b, c);
for(auto c0: all) s.relmatrices[c0] = shmup::calc_relative_matrix(c0, h, s.p);
for(auto c0: all) s.relmatrices[c0] = calc_relative_matrix(c0, h, s.p);
s.owner = h;
}
}
@ -1087,7 +1087,7 @@ auto hook =
/*
if(mouseover && !ctof(mouseover)) {
for(auto h: gp::get_masters(mouseover))
queueline(shmup::ggmatrix(h->c7)*C0, shmup::ggmatrix(mouseover)*C0, 0xFFFFFFFF);
queueline(ggmatrix(h->c7)*C0, shmup::ggmatrix(mouseover)*C0, 0xFFFFFFFF);
}
*/

View File

@ -201,8 +201,8 @@ void bantar_note(cell *c) {
using bantar_config = pair<cell*, cell*>;
tuple<ld,bool,ld> quality(bantar_config cp) {
hyperpoint h1 = tC0(shmup::ggmatrix(cp.first));
hyperpoint h2 = tC0(shmup::ggmatrix(cp.second));
hyperpoint h1 = tC0(ggmatrix(cp.first));
hyperpoint h2 = tC0(ggmatrix(cp.second));
return make_tuple(hdist0(h1) * hdist0(h2), h2[1] > 0, abs(h2[0] / h2[1]));
}
@ -334,7 +334,7 @@ void bantar_frame() {
View = Id;
transmatrix tView = actualV(cth(xcw), Id) * shmup::calc_relative_matrix(cwt.c, xcw.c, NOHINT) * inverse(actualV(cth(cwt), Id));
transmatrix tView = actualV(cth(xcw), Id) * calc_relative_matrix(cwt.c, xcw.c, NOHINT) * inverse(actualV(cth(cwt), Id));
if(tphase < 2) part = 0;
else if(tphase == 2)

View File

@ -286,7 +286,7 @@ void analyze() {
int gaussian = 0;
double mydistance(cell *c1, cell *c2) {
if(gaussian == 2) return hdist(tC0(shmup::ggmatrix(c1)), tC0(shmup::ggmatrix(c2)));
if(gaussian == 2) return hdist(tC0(ggmatrix(c1)), tC0(shmup::ggmatrix(c2)));
else return celldistance(c1, c2);
}
@ -648,7 +648,7 @@ void sominit(int initto) {
else allcells = currentmap->allcells();
if(isize(allcells) > kohrestrict) {
sort(allcells.begin(), allcells.end(), [] (cell *c1, cell *c2) { return hdist0(tC0(shmup::ggmatrix(c1))) < hdist0(tC0(shmup::ggmatrix(c2))); });
sort(allcells.begin(), allcells.end(), [] (cell *c1, cell *c2) { return hdist0(tC0(ggmatrix(c1))) < hdist0(tC0(shmup::ggmatrix(c2))); });
allcells.resize(kohrestrict);
}

View File

@ -163,11 +163,11 @@ hyperpoint where(int i, cell *base) {
auto m = vdata[i].m;
if(m->base == base) return tC0(m->at);
else if(quotient || elliptic || torus) {
return shmup::calc_relative_matrix(m->base, base, C0) * tC0(m->at);
return calc_relative_matrix(m->base, base, C0) * tC0(m->at);
}
else {
// notimpl(); // actually probably that's a buug
return inverse(shmup::ggmatrix(currentmap->gamestart())) * (shmup::ggmatrix(m->base) * tC0(m->at));
return inverse(ggmatrix(currentmap->gamestart())) * (shmup::ggmatrix(m->base) * tC0(m->at));
}
}
@ -191,7 +191,7 @@ void addedge(int i, int j, edgeinfo *ei) {
addedge(i, id, ei);
addedge(id, j, ei);
shmup::virtualRebase(vdata[i].m, true);
virtualRebase(vdata[i].m, true);
}
else addedge0(i, j, ei);
}
@ -1078,7 +1078,7 @@ map<pair<cell*, cell*>, transmatrix> relmatrices;
transmatrix& memo_relative_matrix(cell *c1, cell *c2) {
auto& p = relmatrices[make_pair(c1, c2)];
if(p[2][2] == 0)
p = shmup::calc_relative_matrix(c1, c2, C0);
p = calc_relative_matrix(c1, c2, C0);
return p;
}
@ -1130,10 +1130,10 @@ bool drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
transmatrix gm1 =
multidraw ? V * memo_relative_matrix(vd1.m->base, c) :
shmup::ggmatrix(vd1.m->base);
ggmatrix(vd1.m->base);
transmatrix gm2 =
multidraw ? V * memo_relative_matrix(vd2.m->base, c) :
shmup::ggmatrix(vd2.m->base);
ggmatrix(vd2.m->base);
hyperpoint h1 = gm1 * vd1.m->at * C0;
hyperpoint h2 = gm2 * vd2.m->at * C0;
@ -1169,7 +1169,7 @@ bool drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
if(pmodel || onspiral) {
if(onspiral) {
const int prec = 20;
transmatrix T = shmup::ggmatrix(currentmap->gamestart());
transmatrix T = ggmatrix(currentmap->gamestart());
hyperpoint l1 = T*tC0(spiral::at(1+ei->i));
for(int z=1; z<=prec; z++) {
hyperpoint l2 = T*tC0(spiral::at(1+ei->i+(ei->j-ei->i) * z / (prec+.0)));
@ -1193,7 +1193,7 @@ bool drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
ei->orig = center; // cwt.c;
ei->prec.clear();
transmatrix T = inverse(shmup::ggmatrix(ei->orig));
transmatrix T = inverse(ggmatrix(ei->orig));
if(kind == kSpiral && abs(ei->i - ei->j) == 1) {
ei->orig = currentmap->gamestart();
@ -1209,7 +1209,7 @@ bool drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
else
storeline(ei->prec, T*h1, T*h2);
}
queuetable(multidraw ? V : shmup::ggmatrix(ei->orig), ei->prec, isize(ei->prec), col, 0,
queuetable(multidraw ? V : ggmatrix(ei->orig), ei->prec, isize(ei->prec), col, 0,
PPR_STRUCT0);
}
}
@ -1226,7 +1226,7 @@ bool drawVertex(const transmatrix &V, cell *c, shmup::monster *m) {
bool doshow = true;
if(kind == kTree && i > 0 && !vd.virt) {
vertexdata& vdp = vdata[vd.data];
hyperpoint h2 = shmup::ggmatrix(vdp.m->base) * vdp.m->at * C0;
hyperpoint h2 = ggmatrix(vdp.m->base) * vdp.m->at * C0;
if(hdist(h2, V * m->at * C0) < 0.1) doshow = false;
}

View File

@ -583,7 +583,7 @@ void buildRug() {
map<cell*, rugpoint *> vptr;
for(int i=0; i<isize(cl.lst); i++)
vptr[cl.lst[i]] = addRugpoint(shmup::ggmatrix(cl.lst[i])*C0, cl.dists[i]);
vptr[cl.lst[i]] = addRugpoint(ggmatrix(cl.lst[i])*C0, cl.dists[i]);
for(auto& p: vptr) {
cell *c = p.first;
@ -1236,7 +1236,7 @@ void prepareTexture() {
drawthemap();
if(mousing && !renderonce) {
for(int i=0; i<numplayers(); i++) if(multi::playerActive(i))
queueline(tC0(shmup::ggmatrix(playerpos(i))), mouseh, 0xFF00FF, 8 + vid.linequality);
queueline(tC0(ggmatrix(playerpos(i))), mouseh, 0xFF00FF, 8 + vid.linequality);
}
if(finger_center) {
transmatrix V = rgpushxto0(finger_center->h);

275
shmup.cpp
View File

@ -923,8 +923,6 @@ void profile(const char *buf) {
namespace shmup {
transmatrix &ggmatrix(cell *c);
using namespace multi;
eItem targetRangedOrbKey(orbAction a);
@ -978,18 +976,6 @@ cell *findbaseAroundRepeat(const transmatrix& H, cell *around) {
return asinh(h[2]);
} */
void fixelliptic(transmatrix& at) {
if(elliptic && at[2][2] < 0) {
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
at[i][j] = -at[i][j];
}
}
void fixelliptic(hyperpoint& h) {
if(elliptic && h[2] < 0)
for(int i=0; i<3; i++) h[i] = -h[i];
}
void monster::store() {
monstersAt.insert(make_pair(base, this));
}
@ -3344,267 +3330,6 @@ transmatrix master_relative(cell *c, bool get_inverse) {
return pispin * Id;
}
transmatrix calc_relative_matrix(cell *c2, cell *c1, int direction_hint) {
return calc_relative_matrix(c2, c1, ddspin(c1, direction_hint) * xpush(1e-2) * C0);
}
// target, source, direction from source to target
transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) {
if(sphere) {
if(!gmatrix0.count(c2) || !gmatrix0.count(c1)) {
printf("building gmatrix0 (size=%d)\n", isize(gmatrix0));
auto bak = gp::draw_li;
swap(gmatrix, gmatrix0);
just_gmatrix = true;
drawrec(viewctr, hsOrigin, Id);
just_gmatrix = false;
swap(gmatrix, gmatrix0);
gp::draw_li = bak;
}
if(gmatrix0.count(c2) && gmatrix0.count(c1)) {
transmatrix T = inverse(gmatrix0[c1]) * gmatrix0[c2];
if(elliptic && T[2][2] < 0)
T = centralsym * T;
return T;
}
else {
printf("error: gmatrix0 not known\n");
return Id;
}
}
if(binarytiling) return binary::relative_matrix(c2->master, c1->master);
if(syntetic) return synt::relative_matrix(c2->master, c1->master);
if(torus) {
transmatrix t = Id;
if(whateveri) printf("[%p,%d] ", c2, celldistance(c2, c1));
int mirrors = 0;
approach:
int d = celldistance(c2, c1);
forCellIdEx(c3, i, c2) {
if(celldistance(c3, c1) < d) {
if(whateveri) printf(" %d [%p,%d]", i, c3, celldistance(c3, c1));
if(c2->type < 8)
t = eumovedir(i+(euclid6?3:2)) * t;
else if(i&1)
t = eumovedir(2+i/2) * eumovedir(2+(i+1)/2) * t;
else
t = eumovedir(2+i/2) * t;
if(c2->mirror(i)) mirrors++;
c2 = c3;
goto approach;
}
}
if(d != 0) printf("ERROR not reached\n");
if(mirrors&1) t = Mirror * t * Mirror;
if(whateveri) printf(" => %p\n", c1);
return t;
}
if(euclid) return inverse(gmatrix0[c1]) * gmatrix0[c2];
heptagon *h1 = c1->master;
transmatrix gm = master_relative(c1, true);
heptagon *h2 = c2->master;
transmatrix where = master_relative(c2);
// always add to last!
//bool hsol = false;
//transmatrix sol;
while(h1 != h2) {
if(quotient & qSMALL) {
transmatrix T;
ld bestdist = 1e9;
for(int d=0; d<S7; d++) if(h2->move[d]) {
int sp = h2->spin(d);
transmatrix S = heptmove[sp] * spin(2*M_PI*d/S7);
if(h2->move[d] == h1) {
transmatrix T1 = gm * S * where;
auto curdist = hdist(tC0(T1), point_hint);
if(curdist < bestdist) T = T1, bestdist = curdist;
}
for(int e=0; e<S7; e++) if(h2->move[d]->move[e] == h1) {
int sp2 = h2->move[d]->spin(e);
transmatrix T1 = gm * heptmove[sp2] * spin(2*M_PI*e/S7) * S * where;
auto curdist = hdist(tC0(T1), point_hint);
if(curdist < bestdist) T = T1, bestdist = curdist;
}
}
if(bestdist < 1e8) return T;
}
for(int d=0; d<S7; d++) if(h2->move[d] == h1) {
int sp = h2->spin(d);
return gm * heptmove[sp] * spin(2*M_PI*d/S7) * where;
}
if(geometry == gFieldQuotient) {
int bestdist = 1000, bestd = 0;
for(int d=0; d<S7; d++) {
int dist = celldistance(h2->move[d]->c7, c1);
if(dist < bestdist) bestdist = dist, bestd = d;
}
int sp = h2->spin(bestd);
where = heptmove[sp] * spin(2*M_PI*bestd/S7) * where;
h2 = h2->move[bestd];
}
else if(h1->distance < h2->distance) {
int sp = h2->spin(0);
h2 = h2->move[0];
where = heptmove[sp] * where;
}
else {
int sp = h1->spin(0);
h1 = h1->move[0];
gm = gm * invheptmove[sp];
}
}
/*if(hsol) {
transmatrix sol2 = gm * where;
for(int i=0; i<3; i++) for(int j=0; j<3; j++)
if(fabs(sol2[i][j]-sol[i][j] > 1e-3)) {
printf("ERROR\n");
display(sol);
display(sol2);
exit(1);
}
} */
return gm * where;
}
transmatrix &ggmatrix(cell *c) {
transmatrix& t = gmatrix[c];
if(t[2][2] == 0) {
if(torus && centerover.c)
t = calc_relative_matrix(c, centerover.c, C0);
else if(euclid) {
if(!centerover.c) centerover = cwt;
t = View * eumove(cell_to_vec(c) - cellwalker_to_vec(centerover));
}
else
t = actualV(viewctr, cview()) * calc_relative_matrix(c, viewctr.h->c7, C0);
}
return t;
}
transmatrix calc_relative_matrix_help(cell *c, heptagon *h1) {
transmatrix gm = Id;
heptagon *h2 = c->master;
transmatrix where = Id;
if(gp::on && c != c->master->c7) {
auto li = gp::get_local_info(c);
where = gp::Tf[li.last_dir][li.relative.first&31][li.relative.second&31][fix6(li.total_dir)];
}
else if(!nonbitrunc) for(int d=0; d<S7; d++) if(h2->c7->mov[d] == c)
where = hexmove[d];
// always add to last!
while(h1 != h2) {
for(int d=0; d<S7; d++) if(h1->move[d] == h2) printf("(adj) ");
if(h1->distance < h2->distance) {
int sp = h2->spin(0);
printf("A%d ", sp);
h2 = h2->move[0];
where = heptmove[sp] * where;
}
else {
int sp = h1->spin(0);
printf("B%d ", sp);
h1 = h1->move[0];
gm = gm * invheptmove[sp];
}
}
printf("OK\n");
display(gm * where);
return gm * where;
}
template<class T, class U>
void virtualRebase(cell*& base, T& at, bool tohex, const U& check) {
if(euclid || sphere) {
again:
if(torus) for(int i=0; i<6; i++) {
auto newat = eumovedir(3+i) * at;
if(hdist0(check(newat)) < hdist0(check(at))) {
at = newat;
base = createMov(base, i);
goto again;
}
}
else forCellCM(c2, base) {
auto newat = inverse(ggmatrix(c2)) * ggmatrix(base) * at;
if(hypot(check(newat)[0], check(newat)[1])
< hypot(check(at)[0], check(at)[1])) {
at = newat;
base = c2;
goto again;
}
}
fixelliptic(at);
return;
}
at = master_relative(base) * at;
base = base->master->c7;
while(true) {
double currz = check(at)[2];
heptagon *h = base->master;
cell *newbase = NULL;
transmatrix bestV;
for(int d=0; d<S7; d++) {
heptspin hs;
hs.h = h;
hs.spin = d;
heptspin hs2 = hs + wstep;
transmatrix V2 = spin(-hs2.spin*2*M_PI/S7) * invheptmove[d];
double newz = check(V2 * at) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
newbase = hs2.h->c7;
}
}
if(newbase) {
base = newbase;
at = bestV * at;
}
else {
if(tohex && !nonbitrunc) for(int d=0; d<S7; d++) {
cell *c = createMov(base, d);
transmatrix V2 = spin(-base->spn(d)*2*M_PI/S6) * invhexmove[d];
double newz = check(V2 *at) [2];
if(newz < currz) {
currz = newz;
bestV = V2;
newbase = c;
}
}
if(newbase) {
base = newbase;
at = bestV * at;
}
else at = master_relative(base, true) * at;
break;
}
}
}
void virtualRebase(cell*& base, transmatrix& at, bool tohex) {
virtualRebase(base, at, tohex, tC0);
}
void virtualRebase(cell*& base, hyperpoint& h, bool tohex) {
virtualRebase(base, h, tohex, [] (const hyperpoint& h) { return h; });
}
void virtualRebase(shmup::monster *m, bool tohex) {
virtualRebase(m->base, m->at, tohex);
}

View File

@ -756,7 +756,7 @@ void show_surfaces() {
if(coverage_style == 2) {
if(rug::rugged) rug::close();
}
coverage_matrix = inverse(shmup::ggmatrix(coverage_center = cwt.c));
coverage_matrix = inverse(ggmatrix(coverage_center = cwt.c));
}
else if(rug::handlekeys(sym, uni)) ;
else if(doexiton(sym, uni)) popScreen();
@ -818,7 +818,7 @@ auto surface_hook = addHook(hooks_args, 100, surface_args);
void display_coverage() {
transmatrix M =
coverage_style == 3 ? shmup::ggmatrix(coverage_center) * coverage_matrix
coverage_style == 3 ? ggmatrix(coverage_center) * coverage_matrix
: Id;
if(coverage_style)

View File

@ -262,41 +262,15 @@ void texture_config::mapTextureTriangle(textureinfo &mi, const array<hyperpoint,
texture_triangle *edited_triangle;
textureinfo *edited_tinfo;
hyperpoint *compute_binary_vertices() {
ld yx = log(2) / 2;
ld yy = yx;
ld xx = 1 / sqrt(2)/2;
static hyperpoint vertices[8];
vertices[0] = get_horopoint(-yy, xx);
vertices[1] = get_horopoint(yy, 2*xx);
vertices[2] = get_horopoint(yy, xx);
vertices[3] = get_horopoint(yy, 0);
vertices[4] = get_horopoint(yy, -xx);
vertices[5] = get_horopoint(yy, -2*xx);
vertices[6] = get_horopoint(-yy, -xx);
vertices[7] = get_horopoint(-yy, 0);
return vertices;
}
int celltriangles(cell *c) {
if(binarytiling) return 8;
else return c->type;
return c->type;
}
#define no_patterndir (gp::on || irr::on || binarytiling)
array<hyperpoint, 3> findTextureTriangle(cell *c, patterns::patterninfo& si, int i) {
if(binarytiling) {
transmatrix M = shmup::ggmatrix(c);
auto vertices = compute_binary_vertices();
return make_array(M * C0, M * vertices[i], M * vertices[(i+1)%8]);
}
// auto si = getpatterninfo0(c);
transmatrix M = shmup::ggmatrix(c) * applyPatterndir(c, si);
ld z = ctof(c) ? rhexf : hexvdist;
hyperpoint h1 = spin(M_PI + M_PI * (2*i -1) / c->type) * xpush(z) * C0;
hyperpoint h2 = spin(M_PI + M_PI * (2*i +1) / c->type) * xpush(z) * C0;
return make_array(M * C0, M * h1, M * h2);
transmatrix M = no_patterndir ? ggmatrix(c) : ggmatrix(c) * applyPatterndir(c, si);
return make_array(M * C0, M * get_corner_position(c, i), M * get_corner_position(c, i+1));
}
// using: mouseh, mouseouver
@ -325,55 +299,13 @@ void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const trans
mi.symmetries = si.symmetries;
mi.current_type = celltriangles(c);
if(gp::on) {
mi.M = T;
mi.triangles.clear();
for(int i=0; i<c->type; i++) {
int d = si.dir;
int i0 = fixdir(i + d + 0, c);
int i1 = fixdir(i + d + 1, c);
hyperpoint h1 = gp::get_corner_position(c, i0);
hyperpoint h2 = gp::get_corner_position(c, i1);
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
}
mi.M = no_patterndir ? T : T * applyPatterndir(c, si);
mi.triangles.clear();
else if(irr::on) {
mi.M = T;
mi.triangles.clear();
auto& vs = irr::cells[irr::cellindex[c]];
for(int i=0; i<c->type; i++) {
hyperpoint h1 = vs.vertices[i];
hyperpoint h2 = vs.vertices[(i+1)%c->type];
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
}
else if(binarytiling) {
mi.M = T;
mi.triangles.clear();
auto vertices = compute_binary_vertices();
for(int i=0; i<8; i++) {
hyperpoint h1 = vertices[i];
hyperpoint h2 = vertices[(i+1)%8];
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
}
else {
mi.M = T * applyPatterndir(c, si);
ld z = ctof(c) ? rhexf : hexvdist;
mi.triangles.clear();
for(int i=0; i<c->type; i++) {
int i2 = i+shift;
hyperpoint h1 = spin(M_PI + M_PI * (2*i2 -1) / c->type) * xpush(z) * C0;
hyperpoint h2 = spin(M_PI + M_PI * (2*i2 +1) / c->type) * xpush(z) * C0;
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
for(int i=0; i<c->type; i++) {
hyperpoint h1 = get_corner_position(c, (i + shift) % c->type);
hyperpoint h2 = get_corner_position(c, (i + shift + 1) % c->type);
mi.triangles.emplace_back(make_array(C0, h1, h2), make_array(mi.M*C0, mi.M*h1, mi.M*h2));
}
}
@ -416,7 +348,7 @@ bool texture_config::apply(cell *c, const transmatrix &V, int col) {
set_floor(shFullFloor);
qfi.tinf = &mi;
qfi.spin = (gp::on || irr::on || binarytiling) ? Id : applyPatterndir(c, si);
qfi.spin = no_patterndir ? Id : applyPatterndir(c, si);
if(grid_color) {
draw_floorshape(c, V, shFullFloor, 0, PPR_FLOOR);
@ -678,7 +610,7 @@ ld magic_quality() {
ld q = 0;
for(auto& p: amp) {
hyperpoint inmodel;
applymodel(shmup::ggmatrix(p.c) * p.cell_relative, inmodel);
applymodel(ggmatrix(p.c) * p.cell_relative, inmodel);
inmodel[0] *= vid.radius * 1. / vid.scrsize;
inmodel[1] *= vid.radius * 1. / vid.scrsize;
q += intvalxy(inmodel, p.texture_coords);
@ -1045,7 +977,7 @@ void showMagicMenu() {
initquickqueue();
char letter = 'A';
for(auto& am: amp) {
hyperpoint h = shmup::ggmatrix(am.c) * am.cell_relative;
hyperpoint h = ggmatrix(am.c) * am.cell_relative;
queuechr(h, vid.fsize, letter, 0xC00000, 1);
/*
@ -1514,7 +1446,7 @@ void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_ma
auto& mi2 = texture_map[si.id];
mi2 = mi;
mapTexture(c, mi2, si, shmup::ggmatrix(c), pshift);
mapTexture(c, mi2, si, ggmatrix(c), pshift);
mapTexture2(mi2);
mi2.tvertices = move(new_tvertices);
// printf("%08x remapping %d vertices to %d vertices\n", si.id, isize(mi.tvertices), isize(mi2.tvertices));