mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
fixed some glitches in the spherical projections
This commit is contained in:
parent
31b75bd2bd
commit
9589fcb4b1
72
polygons.cpp
72
polygons.cpp
@ -56,6 +56,12 @@ static const int POLY_CENTERIN = 16384;
|
||||
// force wide lines
|
||||
static const int POLY_FORCEWIDE = (1<<15);
|
||||
|
||||
// points not in front
|
||||
static const int POLY_NOTINFRONT = (1<<16);
|
||||
|
||||
// points moved to the outline cross the image, disable
|
||||
static const int POLY_NIF_ERROR = (1<<17);
|
||||
|
||||
vector<hyperpoint> hpc;
|
||||
|
||||
int prehpc;
|
||||
@ -176,6 +182,12 @@ hyperpoint be_just_on_view(const hyperpoint& H1, const hyperpoint &H2) {
|
||||
return H1 * t + H2 * (1-t);
|
||||
}
|
||||
|
||||
bool last_infront;
|
||||
|
||||
bool nif_error_in(ld x1, ld y1, ld x2, ld y2) {
|
||||
return pow(x1 * x2 + y2 * y2, 2) < (x1*x1+y1*y1)*(x2*x2+y2*y2)*.5;
|
||||
}
|
||||
|
||||
void addpoint(const hyperpoint& H) {
|
||||
if(true) {
|
||||
hyperpoint Hscr;
|
||||
@ -188,8 +200,13 @@ void addpoint(const hyperpoint& H) {
|
||||
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
|
||||
double horizon = curnorm / vid.alpha;
|
||||
|
||||
if((spherespecial>0) ^ (H[2] <= -horizon)) poly_flags |= POLY_INFRONT;
|
||||
if((spherespecial>0) ^ (H[2] <= -horizon)) poly_flags |= POLY_INFRONT, last_infront = false;
|
||||
else {
|
||||
poly_flags |= POLY_NOTINFRONT;
|
||||
if(last_infront && nif_error_in(glcoords.back()[0], glcoords.back()[1], Hscr[0], Hscr[1]))
|
||||
poly_flags |= POLY_NIF_ERROR;
|
||||
last_infront = true;
|
||||
|
||||
double coef =
|
||||
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
|
||||
(sqrt(curnorm - H[2]*H[2]) / (vid.alpha+H[2]));
|
||||
@ -228,23 +245,7 @@ void addpoly(const transmatrix& V, const vector<glvertex> &tab, int ofs, int cnt
|
||||
hyperpoint h = be_just_on_view(last, curr);
|
||||
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);
|
||||
}
|
||||
} */
|
||||
else if(h[0] * enter[0] + h[1] * enter[1] < 0) poly_flags |= POLY_BEHIND;
|
||||
addpoint(h);
|
||||
last_behind = !last_behind;
|
||||
}
|
||||
@ -692,8 +693,10 @@ void drawpolyline(polytodraw& p) {
|
||||
/* pp.outline = 0x80808080;
|
||||
p.col = 0; */
|
||||
|
||||
last_infront = false;
|
||||
|
||||
addpoly(pp.V, *pp.tab, pp.offset, pp.cnt);
|
||||
for(int i=1; i<isize(glcoords); i++) {
|
||||
if(!(sphere && vid.alpha < .9)) 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;
|
||||
@ -717,13 +720,37 @@ void drawpolyline(polytodraw& p) {
|
||||
|
||||
bool nofill = false;
|
||||
|
||||
if(poly_flags & POLY_NIF_ERROR) return;
|
||||
|
||||
if(spherespecial == 1 && (poly_flags & POLY_INFRONT) && (poly_flags & POLY_NOTINFRONT) && vid.alpha <= 1) {
|
||||
bool around_center = false;
|
||||
for(int i=0; i<isize(glcoords)-1; i++) {
|
||||
double x1 = glcoords[i][0];
|
||||
double y1 = glcoords[i][1];
|
||||
double x2 = glcoords[i+1][0];
|
||||
double y2 = glcoords[i+1][1];
|
||||
if(asign(y1, y2)) {
|
||||
ld x = xcross(x1, y1, x2, y2);
|
||||
if(x < -1e-6) around_center = !around_center;
|
||||
}
|
||||
}
|
||||
if(around_center) return;
|
||||
}
|
||||
|
||||
if((spherespecial > 0 || (sphere && equi)) && !(poly_flags & POLY_ISSIDE)) {
|
||||
|
||||
if(!pp.tinf) {
|
||||
|
||||
hyperpoint hscr;
|
||||
hyperpoint h1 = pp.V * intester;
|
||||
if(is_behind(h1)) nofill = true;
|
||||
if(is_behind(h1)) {
|
||||
if(sphere) {
|
||||
for(int i=0; i<3; i++) h1[i] = -h1[i];
|
||||
poly_flags &= ~POLY_CENTERIN;
|
||||
}
|
||||
else
|
||||
nofill = true;
|
||||
}
|
||||
applymodel(h1, hscr); hscr[0] *= vid.radius; hscr[1] *= vid.radius * vid.stretch;
|
||||
for(int i=0; i<isize(glcoords)-1; i++) {
|
||||
double x1 = glcoords[i][0] - hscr[0];
|
||||
@ -1126,7 +1153,10 @@ void drawqueue() {
|
||||
if(ptd.kind == pkPoly || ptd.kind == pkLine) {
|
||||
unsigned c = ptd.col;
|
||||
int alpha = ptd.col & 255;
|
||||
if(alpha == 255)
|
||||
if(vid.alpha <= 1) {
|
||||
ptd.col = 0;
|
||||
}
|
||||
else if(alpha == 255)
|
||||
ptd.col = (gradient(backcolor, c>>8, 0, backbrightness, 1)<<8) | 0xFF;
|
||||
else ptd.col = ptd.col - alpha + int(backbrightness * alpha);
|
||||
drawqueueitem(ptd);
|
||||
|
Loading…
Reference in New Issue
Block a user