mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-24 05:17:17 +00:00
improved spherical display of low-face polyhedra
This commit is contained in:
parent
e6bdba1441
commit
0fd9cc46f2
@ -1673,7 +1673,7 @@ geometryinfo ginf[gGUARD] = {
|
|||||||
{"four hexagons", "4x6", 6, 4, 0, gcHyperbolic, 0x08400, {{5, 3}}},
|
{"four hexagons", "4x6", 6, 4, 0, gcHyperbolic, 0x08400, {{5, 3}}},
|
||||||
{"four heptagons", "4x7", 7, 4, 0, gcHyperbolic, 0x08600, {{4, 3}}},
|
{"four heptagons", "4x7", 7, 4, 0, gcHyperbolic, 0x08600, {{4, 3}}},
|
||||||
{"cube", "3x4", 4, 3, 0, gcSphere, 0x10000, {{SEE_ALL, SEE_ALL}}},
|
{"cube", "3x4", 4, 3, 0, gcSphere, 0x10000, {{SEE_ALL, SEE_ALL}}},
|
||||||
{"tetrahedron (buggy)", "3x3", 3, 3, 0, gcSphere, 0x10200, {{SEE_ALL, SEE_ALL}}},
|
{"tetrahedron", "3x3", 3, 3, 0, gcSphere, 0x10200, {{SEE_ALL, SEE_ALL}}},
|
||||||
{"square grid", "4x4", 4, 4, 0, gcEuclid, 0x10400, {{7, 7}}},
|
{"square grid", "4x4", 4, 4, 0, gcEuclid, 0x10400, {{7, 7}}},
|
||||||
{"cube/elliptic", "e3x4", 4, 3, qNONOR, gcSphere, 0x10600, {{SEE_ALL, SEE_ALL}}},
|
{"cube/elliptic", "e3x4", 4, 3, qNONOR, gcSphere, 0x10600, {{SEE_ALL, SEE_ALL}}},
|
||||||
{"Klein Quartic", "Klein", 7, 3, qSMALL, gcHyperbolic, 0x18000, {{7, 5}}},
|
{"Klein Quartic", "Klein", 7, 3, qSMALL, gcHyperbolic, 0x18000, {{7, 5}}},
|
||||||
|
83
polygons.cpp
83
polygons.cpp
@ -188,34 +188,66 @@ 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;
|
return pow(x1 * x2 + y2 * y2, 2) < (x1*x1+y1*y1)*(x2*x2+y2*y2)*.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool knowgood;
|
||||||
|
hyperpoint goodpoint;
|
||||||
|
vector<pair<int, hyperpoint>> tofix;
|
||||||
|
|
||||||
|
bool correct_side(const hyperpoint& H) {
|
||||||
|
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
|
||||||
|
double horizon = curnorm / vid.alpha;
|
||||||
|
return (spherespecial>0) ^ (H[2] <= -horizon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixpoint(array<float, 3>& hscr, hyperpoint H) {
|
||||||
|
hyperpoint bad = H, good = goodpoint;
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++) {
|
||||||
|
hyperpoint mid = midz(bad, good);
|
||||||
|
if(correct_side(mid))
|
||||||
|
good = mid;
|
||||||
|
else
|
||||||
|
bad = mid;
|
||||||
|
}
|
||||||
|
hyperpoint Hscr;
|
||||||
|
applymodel(good, Hscr);
|
||||||
|
hscr = make_array<GLfloat>(Hscr[0]*vid.radius, Hscr[1]*vid.radius*vid.stretch, Hscr[2]*vid.radius);
|
||||||
|
}
|
||||||
|
|
||||||
void addpoint(const hyperpoint& H) {
|
void addpoint(const hyperpoint& H) {
|
||||||
if(true) {
|
if(true) {
|
||||||
hyperpoint Hscr;
|
ld z = vid.radius;
|
||||||
applymodel(H, Hscr);
|
|
||||||
for(int i=0; i<3; i++) Hscr[i] *= vid.radius;
|
|
||||||
Hscr[1] *= vid.stretch;
|
|
||||||
// if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
|
// if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
|
||||||
|
|
||||||
if(spherespecial) {
|
if(spherespecial) {
|
||||||
|
|
||||||
|
if(correct_side(H)) {
|
||||||
|
poly_flags |= POLY_INFRONT, last_infront = false;
|
||||||
|
if(!knowgood || (spherespecial > 0 ? H[2]>goodpoint[2] : H[2]<goodpoint[2])) goodpoint = H, knowgood = true;
|
||||||
|
}
|
||||||
|
else if(poly_flags & POLY_ISSIDE) {
|
||||||
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
|
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
|
||||||
double horizon = curnorm / vid.alpha;
|
double horizon = curnorm / vid.alpha;
|
||||||
|
|
||||||
if((spherespecial>0) ^ (H[2] <= -horizon)) poly_flags |= POLY_INFRONT, last_infront = false;
|
|
||||||
else {
|
|
||||||
poly_flags |= POLY_NOTINFRONT;
|
poly_flags |= POLY_NOTINFRONT;
|
||||||
if(last_infront && nif_error_in(glcoords.back()[0], glcoords.back()[1], Hscr[0], Hscr[1]))
|
if(last_infront && nif_error_in(glcoords.back()[0], glcoords.back()[1], H[0], H[1]))
|
||||||
poly_flags |= POLY_NIF_ERROR;
|
poly_flags |= POLY_NIF_ERROR;
|
||||||
|
|
||||||
last_infront = true;
|
last_infront = true;
|
||||||
|
|
||||||
double coef =
|
z *=
|
||||||
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
|
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
|
||||||
(sqrt(curnorm - H[2]*H[2]) / (vid.alpha+H[2]));
|
(sqrt(curnorm - H[2]*H[2]) / (vid.alpha+H[2]));
|
||||||
|
}
|
||||||
// double coef = (vid.alpha + horizon) / (vid.alpha + H[2]); -< that one has a funny effect, seriously
|
else {
|
||||||
Hscr[0] *= coef;
|
poly_flags |= POLY_NOTINFRONT;
|
||||||
Hscr[1] *= coef;
|
tofix.push_back(make_pair(glcoords.size(), H));
|
||||||
|
add1(H);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hyperpoint Hscr;
|
||||||
|
applymodel(H, Hscr);
|
||||||
|
for(int i=0; i<3; i++) Hscr[i] *= z;
|
||||||
|
Hscr[1] *= vid.stretch;
|
||||||
add1(Hscr);
|
add1(Hscr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,6 +265,7 @@ void coords_to_poly() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addpoly(const transmatrix& V, const vector<glvertex> &tab, int ofs, int cnt) {
|
void addpoly(const transmatrix& V, const vector<glvertex> &tab, int ofs, int cnt) {
|
||||||
|
tofix.clear(); knowgood = false;
|
||||||
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);
|
||||||
@ -256,6 +289,30 @@ void addpoly(const transmatrix& V, const vector<glvertex> &tab, int ofs, int cnt
|
|||||||
if(firstleave[0] * enter[0] + firstleave[1] * enter[1] < 0) poly_flags |= POLY_BEHIND;
|
if(firstleave[0] * enter[0] + firstleave[1] * enter[1] < 0) poly_flags |= POLY_BEHIND;
|
||||||
else addpoint(firstleave);
|
else addpoint(firstleave);
|
||||||
}
|
}
|
||||||
|
if(knowgood && isize(tofix)) {
|
||||||
|
|
||||||
|
if(true) {
|
||||||
|
hyperpoint Hx = V * C0, Hy = goodpoint;
|
||||||
|
for(int i=0; i<20; i++) {
|
||||||
|
hyperpoint mid = midz(Hx, Hy);
|
||||||
|
if(correct_side(mid)) Hy = mid;
|
||||||
|
else Hx = mid;
|
||||||
|
}
|
||||||
|
using namespace hyperpoint_vec;
|
||||||
|
goodpoint = midz(Hy, goodpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& p: tofix)
|
||||||
|
fixpoint(glcoords[p.first], p.second);
|
||||||
|
/*
|
||||||
|
hyperpoint Hscr;
|
||||||
|
applymodel(goodpoint, Hscr);
|
||||||
|
glcoords.push_back(make_array<GLfloat>(Hscr[0]*vid.radius+10, Hscr[1]*vid.radius*vid.stretch, Hscr[2]*vid.radius));
|
||||||
|
glcoords.push_back(make_array<GLfloat>(Hscr[0]*vid.radius, Hscr[1]*vid.radius*vid.stretch+10, Hscr[2]*vid.radius));
|
||||||
|
glcoords.push_back(make_array<GLfloat>(Hscr[0]*vid.radius-10, Hscr[1]*vid.radius*vid.stretch, Hscr[2]*vid.radius));
|
||||||
|
glcoords.push_back(make_array<GLfloat>(Hscr[0]*vid.radius, Hscr[1]*vid.radius*vid.stretch-10, Hscr[2]*vid.radius));
|
||||||
|
glcoords.push_back(make_array<GLfloat>(Hscr[0]*vid.radius+10, Hscr[1]*vid.radius*vid.stretch, Hscr[2]*vid.radius)); */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CAP_SDLGFX
|
#if CAP_SDLGFX
|
||||||
|
Loading…
Reference in New Issue
Block a user