1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-30 15:39:54 +00:00

hemisphere model

This commit is contained in:
Zeno Rogue 2018-03-24 13:26:16 +01:00
parent 83b9e161ec
commit 74cc23f1c2
5 changed files with 48 additions and 7 deletions

View File

@ -299,7 +299,7 @@ void setGLProjection(int col) {
//glLineWidth(1.0f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(pmodel == mdBall || pmodel == mdHyperboloid) {
if(pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere) {
#ifdef GL_ES
glClearDepthf(1.0f);
#else

View File

@ -543,7 +543,7 @@ namespace conformal {
const char *modelnames[MODELCOUNT] = {
"disk", "half-plane", "band", "polygonal", "polynomial",
"azimuthal equidistant", "azimuthal equi-area",
"ball model", "hyperboloid"
"ball model", "hyperboloid", "hemisphere"
};
void show() {
@ -561,13 +561,16 @@ namespace conformal {
XLAT(
pmodel == mdBand && sphere ? "Mercator" :
pmodel == mdHalfplane && euclid ? "inversion" :
pmodel == mdHemisphere && !hyperbolic ? "sphere" :
pmodel == mdHyperboloid && euclid ? "plane" :
pmodel == mdHyperboloid && sphere ? "sphere" :
modelnames[pmodel]), 'm');
dialog::addSelItem(XLAT("rotation"), directions[pmodel][rotation&3], 'r');
if(pmodel == mdBand && sphere)
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
if(abs(vid.alpha-1) > 1e-3 && pmodel != mdBall && pmodel != mdHyperboloid) {
if(abs(vid.alpha-1) > 1e-3 && pmodel != mdBall && pmodel != mdHyperboloid && pmodel != mdHemisphere) {
dialog::addBreak(50);
dialog::addInfo("NOTE: this works 'correctly' only if the Poincaré model/stereographic projection is used.");
dialog::addBreak(50);
@ -637,7 +640,7 @@ namespace conformal {
switchagain: {
pmodel = eModel((pmodel + (shiftmul > 0 ? 1 : -1) + MODELCOUNT) % MODELCOUNT);
if(!mdEqui() && pmodel != mdDisk && pmodel != mdPolynomial && pmodel != mdHyperboloid) {
if(!mdEqui() && pmodel != mdDisk && pmodel != mdPolynomial && pmodel != mdHyperboloid && pmodel != mdHemisphere) {
if(sphere && pmodel != mdBand)
goto switchagain;
if(euclid && pmodel != mdHalfplane && pmodel != mdBall)

View File

@ -452,7 +452,7 @@ void animallegs(const transmatrix& V, eMonster mo, int col, double footphase) {
void ShadowV(const transmatrix& V, const hpcshape& bp, int prio) {
#if CAP_POLY
if(mmspatial) {
if(pmodel == mdHyperboloid || pmodel == mdBall)
if(pmodel == mdHyperboloid || pmodel == mdBall || pmodel == mdHemisphere)
return; // shadows break the depth testing
dynamicval<int> p(poly_outline, OUTLINE_TRANS);
queuepolyat(V, bp, SHADOW_MON, prio);
@ -3038,7 +3038,7 @@ bool noAdjacentChasms(cell *c) {
}
void floorShadow(cell *c, const transmatrix& V, int col, bool warp) {
if(pmodel == mdHyperboloid || pmodel == mdBall)
if(pmodel == mdHyperboloid || pmodel == mdBall || pmodel == mdHemisphere)
return; // shadows break the depth testing
if(shmup::on || nonbitrunc) warp = false;
dynamicval<int> p(poly_outline, OUTLINE_TRANS);

View File

@ -1527,7 +1527,9 @@ void setcameraangle(bool b);
enum eModel {
mdDisk, mdHalfplane, mdBand, mdPolygonal, mdPolynomial,
mdEquidistant, mdEquiarea, mdBall, mdHyperboloid, mdGUARD, mdUnchanged };
mdEquidistant, mdEquiarea, mdBall, mdHyperboloid,
mdHemisphere,
mdGUARD, mdUnchanged };
#define MODELCOUNT ((int) mdGUARD)

View File

@ -123,6 +123,42 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
return;
}
if(pmodel == mdHemisphere) {
ld ball = vid.ballangle * M_PI / 180;
using namespace hyperpoint_vec;
switch(cgclass) {
case gcHyperbolic: {
ret = H / H[2];
ret[2] = sqrt(1 - sqhypot2(ret));
break;
}
case gcEuclid: {
// stereographic projection to a sphere
auto hd = hdist0(H) / H[2];
if(hd == 0) H[2] = -1;
else {
ld x = 2 * hd / (1 + hd * hd);
ld y = x / hd;
H = H * x / (hd * H[2]);
H[2] = 1 - y;
}
break;
}
case gcSphere: {
ret = H;
break;
}
}
ret = rotmatrix(0, 2, ball) * ret;
ghcheck(ret, H);
return;
}
if(pmodel == mdHyperboloid) {
ld ball = vid.ballangle * M_PI / 180;