mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
new system for inverting stereographic projections, and other improvements in the spherical perspective
This commit is contained in:
parent
1bc9bbd808
commit
12dd76b216
105
polygons.cpp
105
polygons.cpp
@ -6,6 +6,18 @@
|
|||||||
|
|
||||||
namespace hr {
|
namespace hr {
|
||||||
|
|
||||||
|
ld signum(ld x) { return x<0?-1:x>0?1:0; }
|
||||||
|
|
||||||
|
bool asign(ld y1, ld y2) {
|
||||||
|
return signum(y1) != signum(y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ld xcross(ld x1, ld y1, ld x2, ld y2) {
|
||||||
|
return x1 + (x2 - x1) * y1 / (y1 - y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
hyperpoint intester;
|
||||||
|
|
||||||
// draw the lines
|
// draw the lines
|
||||||
static const int POLY_DRAWLINES = 1;
|
static const int POLY_DRAWLINES = 1;
|
||||||
// draw the area
|
// draw the area
|
||||||
@ -38,6 +50,9 @@ static const int POLY_VCONVEX = 4096;
|
|||||||
// Convex shape (central)
|
// Convex shape (central)
|
||||||
static const int POLY_CCONVEX = 8192;
|
static const int POLY_CCONVEX = 8192;
|
||||||
|
|
||||||
|
// new system of side checking
|
||||||
|
static const int POLY_CENTERIN = 16384;
|
||||||
|
|
||||||
vector<hyperpoint> hpc;
|
vector<hyperpoint> hpc;
|
||||||
|
|
||||||
int prehpc;
|
int prehpc;
|
||||||
@ -200,16 +215,41 @@ void addpoly(const transmatrix& V, const vector<glvertex> &tab, int ofs, int cnt
|
|||||||
hyperpoint last = V * glhr::gltopoint(tab[ofs]);
|
hyperpoint last = V * glhr::gltopoint(tab[ofs]);
|
||||||
bool last_behind = is_behind(last);
|
bool last_behind = is_behind(last);
|
||||||
if(!last_behind) addpoint(last);
|
if(!last_behind) addpoint(last);
|
||||||
|
hyperpoint enter;
|
||||||
|
hyperpoint firstleave;
|
||||||
|
int start_behind = last_behind ? 1 : 0;
|
||||||
for(int i=ofs+1; i<ofs+cnt; i++) {
|
for(int i=ofs+1; i<ofs+cnt; i++) {
|
||||||
hyperpoint curr = V*glhr::gltopoint(tab[i]);
|
hyperpoint curr = V*glhr::gltopoint(tab[i]);
|
||||||
if(is_behind(curr) != last_behind) {
|
if(is_behind(curr) != last_behind) {
|
||||||
addpoint(be_just_on_view(last, curr));
|
hyperpoint h = be_just_on_view(last, curr);
|
||||||
last = curr; last_behind = !last_behind;
|
if(start_behind == 1) start_behind = 2, firstleave = h;
|
||||||
|
if(!last_behind) enter = h;
|
||||||
|
else if(h[0] * enter[0] + h[1] * enter[1] < 0) poly_flags |= POLY_BEHIND; /*{
|
||||||
|
using namespace hyperpoint_vec;
|
||||||
|
ld zl = zlevel(h);
|
||||||
|
ld sca2 = zl*zl - pow(vid.alpha - BEHIND_LIMIT, 2);
|
||||||
|
|
||||||
|
// h[0]** + h[1]** + h[2]** == zl*zl
|
||||||
|
// he[0]** + he[1]** + he[2]** ==
|
||||||
|
// (he[0]** + he[1]**) * sca2 / sqhypot2(he) + he[2]**
|
||||||
|
|
||||||
|
if(sca2 > 0) {
|
||||||
|
hyperpoint he = (h + enter) / 2;
|
||||||
|
ld sca = sqrt(sca2) / hypot2(he);
|
||||||
|
he[0] *= sca; h[1] *= sca;
|
||||||
|
printf("sca2 = %lf zl=%lf/%lf\n", sca2, zlevel(h), zlevel(he));
|
||||||
|
addpoint(he);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
addpoint(h);
|
||||||
|
last_behind = !last_behind;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if(!last_behind) addpoint(curr);
|
if(!last_behind) addpoint(curr);
|
||||||
last = curr;
|
last = curr;
|
||||||
}
|
}
|
||||||
|
if(start_behind == 2) {
|
||||||
|
if(firstleave[0] * enter[0] + firstleave[1] * enter[1] < 0) poly_flags |= POLY_BEHIND;
|
||||||
|
else addpoint(firstleave);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +686,12 @@ void drawpolyline(polytodraw& p) {
|
|||||||
p.col = 0; */
|
p.col = 0; */
|
||||||
|
|
||||||
addpoly(pp.V, *pp.tab, pp.offset, pp.cnt);
|
addpoly(pp.V, *pp.tab, pp.offset, pp.cnt);
|
||||||
// if(poly_flags & POLY_BEHIND) return;
|
for(int i=1; i<isize(glcoords); i++) {
|
||||||
|
ld dx = glcoords[i][0] - glcoords[i-1][0];
|
||||||
|
ld dy = glcoords[i][1] - glcoords[i-1][1];
|
||||||
|
if(dx > vid.xres * 2 || dy > vid.yres * 2) return;
|
||||||
|
}
|
||||||
|
if(poly_flags & POLY_BEHIND) return;
|
||||||
if(isize(glcoords) <= 1) return;
|
if(isize(glcoords) <= 1) return;
|
||||||
|
|
||||||
mercator_loop_min = mercator_loop_max = 0;
|
mercator_loop_min = mercator_loop_max = 0;
|
||||||
@ -663,7 +708,39 @@ void drawpolyline(polytodraw& p) {
|
|||||||
|
|
||||||
bool equi = mdAzimuthalEqui() || pmodel == mdFisheye;
|
bool equi = mdAzimuthalEqui() || pmodel == mdFisheye;
|
||||||
|
|
||||||
|
bool nofill = false;
|
||||||
|
|
||||||
if((spherespecial > 0 || (sphere && equi)) && !(poly_flags & POLY_ISSIDE)) {
|
if((spherespecial > 0 || (sphere && equi)) && !(poly_flags & POLY_ISSIDE)) {
|
||||||
|
|
||||||
|
if(true) {
|
||||||
|
|
||||||
|
hyperpoint hscr;
|
||||||
|
hyperpoint h1 = pp.V * intester;
|
||||||
|
if(is_behind(h1)) nofill = true;
|
||||||
|
applymodel(h1, hscr); hscr[0] *= vid.radius; hscr[1] *= vid.radius;
|
||||||
|
for(int i=0; i<isize(glcoords)-1; i++) {
|
||||||
|
double x1 = glcoords[i][0] - hscr[0];
|
||||||
|
double y1 = glcoords[i][1] - hscr[1];
|
||||||
|
double x2 = glcoords[i+1][0] - hscr[0];
|
||||||
|
double y2 = glcoords[i+1][1] - hscr[1];
|
||||||
|
if(asign(y1, y2)) {
|
||||||
|
ld x = xcross(x1, y1, x2, y2);
|
||||||
|
if(x < -1e-6) poly_flags ^= POLY_CENTERIN;
|
||||||
|
else if (x < 1e-6) nofill = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
poly_flags &= ~POLY_INVERSE;
|
||||||
|
if(poly_flags & POLY_CENTERIN) {
|
||||||
|
poly_flags |= POLY_INVERSE;
|
||||||
|
/* nofill = true;
|
||||||
|
pp.outline = (pp.flags & POLY_CENTERIN) ? 0x00FF00FF : 0xFF0000FF;
|
||||||
|
addpoint(hscr); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
double rarea = 0;
|
double rarea = 0;
|
||||||
for(int i=0; i<isize(glcoords)-1; i++)
|
for(int i=0; i<isize(glcoords)-1; i++)
|
||||||
rarea += glcoords[i][0] * glcoords[i+1][1] - glcoords[i][1] * glcoords[i+1][0];
|
rarea += glcoords[i][0] * glcoords[i+1][1] - glcoords[i][1] * glcoords[i+1][0];
|
||||||
@ -673,6 +750,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
|
|
||||||
if(rarea>0)
|
if(rarea>0)
|
||||||
poly_flags ^= POLY_INVERSE;
|
poly_flags ^= POLY_INVERSE;
|
||||||
|
}
|
||||||
|
|
||||||
if(poly_flags & POLY_INVERSE) {
|
if(poly_flags & POLY_INVERSE) {
|
||||||
if(curradius < vid.alpha - 1e-6) return;
|
if(curradius < vid.alpha - 1e-6) return;
|
||||||
@ -697,8 +775,6 @@ void drawpolyline(polytodraw& p) {
|
|||||||
lastl = l;
|
lastl = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nofill = false;
|
|
||||||
|
|
||||||
if(equi && (poly_flags & POLY_INVERSE)) {
|
if(equi && (poly_flags & POLY_INVERSE)) {
|
||||||
if(abs(zlevel(pp.V * C0) - 1) < 1e-6 && !pp.tinf) {
|
if(abs(zlevel(pp.V * C0) - 1) < 1e-6 && !pp.tinf) {
|
||||||
// we should fill the other side
|
// we should fill the other side
|
||||||
@ -1249,6 +1325,17 @@ void finishshape() {
|
|||||||
if(abs(area) < 1e-9) last->flags |= POLY_ISSIDE;
|
if(abs(area) < 1e-9) last->flags |= POLY_ISSIDE;
|
||||||
if(area >= 0) last->flags |= POLY_INVERSE;
|
if(area >= 0) last->flags |= POLY_INVERSE;
|
||||||
|
|
||||||
|
for(int i=last->s; i<last->e-1; i++) {
|
||||||
|
ld x1 = hpc[i][0] - intester[0], y1 = hpc[i][1] - intester[1], x2 = hpc[i+1][0] - intester[0], y2 = hpc[i+1][1] - intester[1];
|
||||||
|
if(asign(y1, y2)) {
|
||||||
|
ld x = xcross(x1, y1, x2, y2);
|
||||||
|
if(abs(x) < 1e-6 && !(last->flags & POLY_ISSIDE)) {
|
||||||
|
printf("close call, x = %lf\n", x);
|
||||||
|
}
|
||||||
|
if(x < 0) last->flags ^= POLY_CENTERIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool allplus = true, allminus = true;
|
bool allplus = true, allminus = true;
|
||||||
for(int i=last->s; i<last->e-1; i++) {
|
for(int i=last->s; i<last->e-1; i++) {
|
||||||
ld v = hpc[i][0] * hpc[i+1][1] - hpc[i+1][0] * hpc[i][1];
|
ld v = hpc[i][0] * hpc[i+1][1] - hpc[i+1][0] * hpc[i][1];
|
||||||
@ -1416,6 +1503,8 @@ ld dlow_table[SIDEPARS], dhi_table[SIDEPARS];
|
|||||||
|
|
||||||
void buildpolys() {
|
void buildpolys() {
|
||||||
|
|
||||||
|
intester = hpxy(1e-3, 1.3e-3);
|
||||||
|
|
||||||
symmetriesAt.clear();
|
symmetriesAt.clear();
|
||||||
allshapes.clear();
|
allshapes.clear();
|
||||||
geom3::compute();
|
geom3::compute();
|
||||||
@ -1483,7 +1572,7 @@ void buildpolys() {
|
|||||||
x *= gp::scale;
|
x *= gp::scale;
|
||||||
if(gp::scale != 1) x /= 2;
|
if(gp::scale != 1) x /= 2;
|
||||||
for(int t=0; t<=S6; t++) { hpcpush(C0); if(t) hpcpush(ddi(S7 + t*S14, x) * C0);
|
for(int t=0; t<=S6; t++) { hpcpush(C0); if(t) hpcpush(ddi(S7 + t*S14, x) * C0);
|
||||||
last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW;
|
last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW | POLY_ISSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = rhexf;
|
x = rhexf;
|
||||||
@ -1491,7 +1580,7 @@ void buildpolys() {
|
|||||||
// x *= gp::scale;
|
// x *= gp::scale;
|
||||||
bshape(shFullCross[1], PPR_FLOOR);
|
bshape(shFullCross[1], PPR_FLOOR);
|
||||||
for(int t=0; t<=S7; t++) { hpcpush(C0); if(t) hpcpush(ddi(t*S12+td, x) * C0); }
|
for(int t=0; t<=S7; t++) { hpcpush(C0); if(t) hpcpush(ddi(t*S12+td, x) * C0); }
|
||||||
last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW;
|
last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW | POLY_ISSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
double floorrad0 = hexvdist*0.92;
|
double floorrad0 = hexvdist*0.92;
|
||||||
|
Loading…
Reference in New Issue
Block a user