2015-08-08 13:57:52 +00:00
|
|
|
// Hyperbolic Rogue
|
2016-08-26 09:58:03 +00:00
|
|
|
// geometrical constants
|
|
|
|
|
2018-02-08 23:40:26 +00:00
|
|
|
// Copyright (C) 2011-2018 Zeno Rogue, see 'hyper.cpp' for details
|
2015-08-08 13:57:52 +00:00
|
|
|
|
2018-06-10 23:58:31 +00:00
|
|
|
namespace hr {
|
|
|
|
|
2016-08-26 09:58:03 +00:00
|
|
|
// the results are:
|
|
|
|
// hexf = 0.378077 hcrossf = 0.620672 tessf = 1.090550
|
2017-03-23 10:53:57 +00:00
|
|
|
// hexhexdist = 0.566256
|
|
|
|
|
2017-10-27 18:07:58 +00:00
|
|
|
ld hcrossf7 = 0.620672;
|
2017-10-28 08:04:28 +00:00
|
|
|
ld hexf7 = 0.378077;
|
2017-10-27 18:07:58 +00:00
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
// the distance between two hexagon centers
|
2015-08-08 13:57:52 +00:00
|
|
|
|
2019-07-21 21:12:16 +00:00
|
|
|
bool scale_used() { return (shmup::on && geometry == gNormal && BITRUNCATED) ? (cheater || autocheat) : true; }
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void geometry_information::prepare_basics() {
|
2015-08-08 13:57:52 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("prepare_basics"));
|
2017-10-27 18:07:58 +00:00
|
|
|
|
|
|
|
hexshift = 0;
|
2016-08-26 09:58:03 +00:00
|
|
|
|
2017-10-28 08:04:28 +00:00
|
|
|
ld fmin, fmax;
|
|
|
|
|
2018-08-19 21:06:32 +00:00
|
|
|
if(archimedean)
|
|
|
|
ginf[gArchimedean].cclass = gcHyperbolic;
|
2018-08-17 11:29:00 +00:00
|
|
|
|
2018-08-18 22:25:43 +00:00
|
|
|
if(euclid) {
|
2017-10-28 08:04:28 +00:00
|
|
|
// dynamicval<eGeometry> g(geometry, gNormal);
|
|
|
|
// for(int i=0; i<S84; i++) spinmatrix[i] = spin(i * M_PI / S42);
|
2018-08-28 15:17:34 +00:00
|
|
|
if(a4 && !BITRUNCATED) {
|
2017-12-18 12:00:36 +00:00
|
|
|
crossf = .5;
|
|
|
|
hexf = .5;
|
|
|
|
hcrossf = crossf * sqrt(2) / 2;
|
|
|
|
hexhexdist = crossf;
|
|
|
|
hexvdist = hexf;
|
|
|
|
hepvdist = hexf;
|
|
|
|
rhexf = crossf * sqrt(2) / 2;
|
2018-05-07 23:59:57 +00:00
|
|
|
tessf = crossf;
|
2017-12-18 12:00:36 +00:00
|
|
|
}
|
2018-08-28 15:17:34 +00:00
|
|
|
else if(a4 && BITRUNCATED) {
|
2017-12-18 12:00:36 +00:00
|
|
|
ld s2 = sqrt(2);
|
|
|
|
ld xx = 1 - s2 / 2;
|
|
|
|
crossf = .5;
|
|
|
|
tessf = crossf * s2;
|
|
|
|
hexf = .5 * xx * s2;
|
|
|
|
hcrossf = crossf;
|
|
|
|
hexhexdist = crossf * s2;
|
|
|
|
hexvdist = crossf * hypot(1-xx, xx);
|
|
|
|
hepvdist = crossf;
|
|
|
|
rhexf = hexf;
|
2018-05-07 23:59:57 +00:00
|
|
|
tessf = crossf;
|
2017-12-18 12:00:36 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
crossf = .5;
|
|
|
|
tessf = crossf * sqrt(3);
|
|
|
|
hexf = tessf/3;
|
|
|
|
hcrossf = crossf;
|
|
|
|
hexhexdist = crossf;
|
|
|
|
hexvdist = hexf;
|
|
|
|
hepvdist = crossf;
|
|
|
|
rhexf = hexf;
|
|
|
|
}
|
2017-10-28 08:04:28 +00:00
|
|
|
goto finish;
|
2017-10-27 18:09:59 +00:00
|
|
|
}
|
2019-02-25 12:17:53 +00:00
|
|
|
|
2019-05-08 16:33:08 +00:00
|
|
|
if((sphere || hyperbolic) && WDIM == 3 && !binarytiling) {
|
2019-02-25 12:17:53 +00:00
|
|
|
rhexf = hexf = 0.378077;
|
|
|
|
crossf = hcrossf = 0.620672;
|
|
|
|
tessf = 1.090550;
|
|
|
|
hexhexdist = 0.566256;
|
|
|
|
goto finish;
|
|
|
|
}
|
2016-08-26 09:58:03 +00:00
|
|
|
|
2019-04-28 10:12:02 +00:00
|
|
|
tessf = edge_of_triangle_with_angles(2*M_PI/S3, M_PI/S7, M_PI/S7);
|
2015-08-08 13:57:52 +00:00
|
|
|
|
2018-05-01 17:34:09 +00:00
|
|
|
if(elliptic && S7 == 4) tessf = M_PI/2;
|
2015-08-08 13:57:52 +00:00
|
|
|
|
2019-04-28 10:12:02 +00:00
|
|
|
hcrossf = edge_of_triangle_with_angles(M_PI/2, M_PI/S7, M_PI/S3);
|
|
|
|
|
2018-08-28 15:17:34 +00:00
|
|
|
crossf = BITRUNCATED ? hcrossf : tessf;
|
2015-08-08 13:57:52 +00:00
|
|
|
|
|
|
|
fmin = 0, fmax = tessf;
|
|
|
|
for(int p=0; p<100; p++) {
|
|
|
|
ld f = (fmin+fmax) / 2;
|
2018-08-19 14:28:36 +00:00
|
|
|
hyperpoint H = xpush0(f);
|
2017-03-23 10:53:57 +00:00
|
|
|
hyperpoint H1 = spin(2*M_PI/S7) * H;
|
2018-08-19 14:28:36 +00:00
|
|
|
hyperpoint H2 = xpush0(tessf-f);
|
2015-08-08 13:57:52 +00:00
|
|
|
ld v1 = intval(H, H1), v2 = intval(H, H2);
|
|
|
|
if(v1 < v2) fmin = f; else fmax = f;
|
|
|
|
}
|
|
|
|
hexf = fmin;
|
|
|
|
|
2018-08-28 15:17:34 +00:00
|
|
|
rhexf = BITRUNCATED ? hexf : hcrossf;
|
2017-10-29 16:12:40 +00:00
|
|
|
|
2018-08-28 15:17:34 +00:00
|
|
|
if(!euclid && BITRUNCATED && !(S7&1))
|
2017-10-28 08:04:28 +00:00
|
|
|
hexshift = ALPHA/2 + ALPHA * ((S7-1)/2) + M_PI;
|
|
|
|
|
|
|
|
finish:
|
2017-10-28 23:57:34 +00:00
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
for(int d=0; d<S7; d++)
|
2015-08-08 13:57:52 +00:00
|
|
|
heptmove[d] = spin(-d * ALPHA) * xpush(tessf) * spin(M_PI);
|
2017-10-27 18:07:58 +00:00
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
for(int d=0; d<S7; d++)
|
2017-10-27 18:07:58 +00:00
|
|
|
hexmove[d] = spin(hexshift-d * ALPHA) * xpush(-crossf)* spin(M_PI);
|
2016-08-26 09:58:03 +00:00
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
for(int d=0; d<S7; d++) invheptmove[d] = inverse(heptmove[d]);
|
|
|
|
for(int d=0; d<S7; d++) invhexmove[d] = inverse(hexmove[d]);
|
|
|
|
|
2018-08-19 14:28:36 +00:00
|
|
|
hexhexdist = hdist(xpush0(crossf), xspinpush0(M_PI*2/S7, crossf));
|
2017-03-23 10:53:57 +00:00
|
|
|
|
2018-08-19 14:28:36 +00:00
|
|
|
hexvdist = hdist(xpush0(hexf), xspinpush0(ALPHA/2, hcrossf));
|
2017-10-29 16:12:40 +00:00
|
|
|
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBB(DF_GEOM | DF_POLY,
|
|
|
|
(format("S7=%d S6=%d hexf = " LDF" hcross = " LDF" tessf = " LDF" hexshift = " LDF " hexhex = " LDF " hexv = " LDF "\n", S7, S6, hexf, hcrossf, tessf, hexshift,
|
|
|
|
hexhexdist, hexvdist)));
|
2017-10-29 16:12:40 +00:00
|
|
|
|
2018-08-28 15:17:34 +00:00
|
|
|
base_distlimit = ginf[geometry].distlimit[!BITRUNCATED];
|
2018-08-28 17:05:57 +00:00
|
|
|
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_GP
|
2018-04-09 15:40:12 +00:00
|
|
|
gp::compute_geometry();
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
|
|
|
#if CAP_IRR
|
2018-07-16 18:05:23 +00:00
|
|
|
irr::compute_geometry();
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
|
|
|
#if CAP_ARCM
|
2018-08-28 17:05:57 +00:00
|
|
|
if(archimedean) {
|
|
|
|
arcm::current.compute_geometry();
|
|
|
|
crossf = hcrossf7 * arcm::current.scale();
|
|
|
|
hexvdist = arcm::current.scale() * .5;
|
|
|
|
rhexf = arcm::current.scale() * .5;
|
|
|
|
}
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2019-02-28 14:03:17 +00:00
|
|
|
#if CAP_BT
|
2018-08-28 17:05:57 +00:00
|
|
|
if(binarytiling) hexvdist = rhexf = 1, tessf = 1, scalefactor = 1, crossf = hcrossf7;
|
2019-08-06 10:00:46 +00:00
|
|
|
if(geometry == gHoroRec || penrose || sol || nil) hexvdist = rhexf = .5, tessf = .5, scalefactor = .5, crossf = hcrossf7/2;
|
2019-02-28 14:03:17 +00:00
|
|
|
#endif
|
|
|
|
#if CAP_BT && MAXMDIM >= 4
|
2019-07-22 09:21:27 +00:00
|
|
|
if(binarytiling) binary::build_tmatrix();
|
2019-02-28 14:03:17 +00:00
|
|
|
#endif
|
2019-02-28 02:41:59 +00:00
|
|
|
|
2018-08-28 17:05:57 +00:00
|
|
|
scalefactor = crossf / hcrossf7;
|
|
|
|
orbsize = crossf;
|
|
|
|
|
2019-07-21 21:12:16 +00:00
|
|
|
if(scale_used()) scalefactor *= vid.creature_scale;
|
2019-02-28 02:41:59 +00:00
|
|
|
|
2018-08-28 17:05:57 +00:00
|
|
|
zhexf = BITRUNCATED ? hexf : crossf* .55;
|
2019-07-21 21:12:16 +00:00
|
|
|
if(scale_used()) zhexf *= vid.creature_scale;
|
2019-05-15 16:43:40 +00:00
|
|
|
if(WDIM == 2 && GDIM == 3) zhexf *= 1.5, orbsize *= 1.2;
|
2018-08-28 17:05:57 +00:00
|
|
|
|
2019-05-08 23:40:29 +00:00
|
|
|
floorrad0 = hexvdist* (GDIM == 3 ? 1 : 0.92);
|
|
|
|
floorrad1 = rhexf * (GDIM == 3 ? 1 : 0.94);
|
2018-08-28 17:05:57 +00:00
|
|
|
|
|
|
|
if(euclid4) {
|
|
|
|
if(!BITRUNCATED)
|
2019-05-08 23:40:29 +00:00
|
|
|
floorrad0 = floorrad1 = rhexf * (GDIM == 3 ? 1 : .94);
|
2018-08-28 17:05:57 +00:00
|
|
|
else
|
2019-05-08 23:40:29 +00:00
|
|
|
floorrad0 = hexvdist * (GDIM == 3 ? 1 : .9),
|
|
|
|
floorrad1 = rhexf * (GDIM == 3 ? 1 : .8);
|
2018-08-28 17:05:57 +00:00
|
|
|
}
|
2018-09-23 11:56:00 +00:00
|
|
|
|
|
|
|
set_sibling_limit();
|
2019-05-26 16:04:02 +00:00
|
|
|
|
|
|
|
prepare_compute3();
|
|
|
|
if(hyperbolic && &currfp != &fieldpattern::fp_invalid)
|
|
|
|
currfp.analyze();
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
|
|
|
|
2018-08-19 13:52:39 +00:00
|
|
|
transmatrix xspinpush(ld dir, ld dist) {
|
2017-03-23 10:53:57 +00:00
|
|
|
if(euclid)
|
2019-02-26 13:34:37 +00:00
|
|
|
return eupush(cos(dir) * dist, -sin(dir) * dist);
|
2017-03-23 10:53:57 +00:00
|
|
|
else
|
2018-08-19 13:52:39 +00:00
|
|
|
return spin(dir) * xpush(dist) * spin(-dir);
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
|
|
|
|
2019-05-08 19:09:22 +00:00
|
|
|
purehookset hooks_swapdim;
|
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
namespace geom3 {
|
|
|
|
|
|
|
|
// Here we convert between the following parameters:
|
|
|
|
|
|
|
|
// abslev: level below the plane
|
|
|
|
// lev: level above the world (abslev = depth-lev)
|
|
|
|
// projection: projection parameter
|
|
|
|
// factor: zoom factor
|
2015-08-08 13:57:52 +00:00
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
ld abslev_to_projection(ld abslev) {
|
2019-05-29 14:27:24 +00:00
|
|
|
if(sphere || euclid) return vid.camera+abslev;
|
|
|
|
return tanh(abslev) / tanh(vid.camera);
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
ld projection_to_abslev(ld proj) {
|
2019-05-29 14:27:24 +00:00
|
|
|
if(sphere || euclid) return proj-vid.camera;
|
2017-03-23 10:53:57 +00:00
|
|
|
// tanh(abslev) / tanh(camera) = proj
|
2019-05-29 14:27:24 +00:00
|
|
|
return atanh(proj * tanh(vid.camera));
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
ld lev_to_projection(ld lev) {
|
2019-05-29 14:27:24 +00:00
|
|
|
return abslev_to_projection(vid.depth - lev);
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
2017-03-23 10:53:57 +00:00
|
|
|
|
|
|
|
ld projection_to_factor(ld proj) {
|
|
|
|
return lev_to_projection(0) / proj;
|
|
|
|
}
|
|
|
|
|
|
|
|
ld factor_to_projection(ld fac) {
|
|
|
|
return lev_to_projection(0) / fac;
|
|
|
|
}
|
|
|
|
|
|
|
|
ld lev_to_factor(ld lev) {
|
2019-05-08 16:33:08 +00:00
|
|
|
if(WDIM == 3) return lev;
|
2019-05-29 14:27:24 +00:00
|
|
|
if(GDIM == 3) return vid.depth - lev;
|
2017-03-23 10:53:57 +00:00
|
|
|
return projection_to_factor(lev_to_projection(lev));
|
|
|
|
}
|
|
|
|
ld factor_to_lev(ld fac) {
|
2019-02-22 20:26:37 +00:00
|
|
|
if(DIM == 3) return fac;
|
2019-05-29 14:27:24 +00:00
|
|
|
return vid.depth - projection_to_abslev(factor_to_projection(fac));
|
2017-03-23 10:53:57 +00:00
|
|
|
}
|
|
|
|
|
2019-06-01 17:58:07 +00:00
|
|
|
void do_auto_eye() {
|
|
|
|
if(!vid.auto_eye) return;
|
|
|
|
auto& cs = getcs();
|
|
|
|
if(cs.charid < 4)
|
|
|
|
vid.eye = cgi.eyelevel_human;
|
|
|
|
else if(cs.charid < 8)
|
|
|
|
vid.eye = cgi.eyelevel_dog;
|
|
|
|
else if(cs.charid == 8)
|
|
|
|
vid.eye = cgi.eyelevel_familiar;
|
|
|
|
}
|
|
|
|
|
2017-03-23 10:53:57 +00:00
|
|
|
// how should we scale at level lev
|
|
|
|
ld scale_at_lev(ld lev) {
|
|
|
|
if(sphere || euclid) return 1;
|
2019-05-29 14:27:24 +00:00
|
|
|
return cosh(vid.depth - lev);
|
2017-03-23 10:53:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string invalid;
|
|
|
|
|
2018-04-23 10:34:14 +00:00
|
|
|
ld actual_wall_height() {
|
2019-02-17 17:28:20 +00:00
|
|
|
#if CAP_GP
|
2019-05-29 14:27:24 +00:00
|
|
|
if(GOLDBERG && vid.gp_autoscale_heights)
|
|
|
|
return vid.wall_height * min<ld>(4 / hypot_d(2, gp::next), 1);
|
2019-02-17 17:28:20 +00:00
|
|
|
#endif
|
2019-05-29 14:27:24 +00:00
|
|
|
return vid.wall_height;
|
2018-04-23 10:34:14 +00:00
|
|
|
}
|
2019-05-26 16:04:02 +00:00
|
|
|
}
|
2018-04-23 10:34:14 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void geometry_information::prepare_compute3() {
|
|
|
|
using namespace geom3;
|
2019-05-12 23:57:40 +00:00
|
|
|
DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("geom3::compute"));
|
2017-03-23 10:53:57 +00:00
|
|
|
// tanh(depth) / tanh(camera) == vid.alpha
|
|
|
|
invalid = "";
|
|
|
|
|
2019-05-08 16:33:08 +00:00
|
|
|
if(GDIM == 3) ;
|
2019-05-29 14:27:24 +00:00
|
|
|
else if(vid.tc_alpha < vid.tc_depth && vid.tc_alpha < vid.tc_camera)
|
|
|
|
vid.alpha = tan_auto(vid.depth) / tan_auto(vid.camera);
|
|
|
|
else if(vid.tc_depth < vid.tc_alpha && vid.tc_depth < vid.tc_camera) {
|
|
|
|
ld v = vid.alpha * tan_auto(vid.camera);
|
|
|
|
if(hyperbolic && (v<1e-6-12 || v>1-1e-12)) invalid = "cannot adjust depth", vid.depth = vid.camera;
|
|
|
|
else vid.depth = atan_auto(v);
|
2017-03-23 10:53:57 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-05-29 14:27:24 +00:00
|
|
|
ld v = tan_auto(vid.depth) / vid.alpha;
|
|
|
|
if(hyperbolic && (v<1e-12-1 || v>1-1e-12)) invalid = "cannot adjust camera", vid.camera = vid.depth;
|
|
|
|
else vid.camera = atan_auto(v);
|
2017-03-23 10:53:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(fabs(vid.alpha) < 1e-6) invalid = "does not work with perfect Klein";
|
|
|
|
|
|
|
|
if(invalid != "") {
|
|
|
|
INFDEEP = .7;
|
|
|
|
BOTTOM = .8;
|
|
|
|
HELLSPIKE = .85;
|
|
|
|
LAKE = .9;
|
2019-05-08 16:33:08 +00:00
|
|
|
FLOOR = 1;
|
2017-03-23 10:53:57 +00:00
|
|
|
WALL = 1.25;
|
|
|
|
SLEV[0] = 1;
|
|
|
|
SLEV[1] = 1.08;
|
|
|
|
SLEV[2] = 1.16;
|
|
|
|
SLEV[3] = 1.24;
|
|
|
|
FLATEYE = 1.03;
|
|
|
|
LEG1 = 1.025;
|
|
|
|
LEG = 1.05;
|
|
|
|
LEG3 = 1.075;
|
|
|
|
GROIN = 1.09;
|
|
|
|
GROIN1 = 1.105;
|
|
|
|
GHOST = 1.1;
|
|
|
|
BODY = 1.15;
|
2019-02-27 18:15:58 +00:00
|
|
|
BODY1 = 1.151;
|
|
|
|
BODY2 = 1.152;
|
|
|
|
BODY3 = 1.153;
|
2017-03-23 10:53:57 +00:00
|
|
|
NECK1 = 1.16;
|
|
|
|
NECK = 1.17;
|
|
|
|
NECK3 = 1.18;
|
2019-02-27 00:15:40 +00:00
|
|
|
HEAD = 1.188;
|
|
|
|
HEAD1= 1.189;
|
|
|
|
HEAD2= 1.190;
|
2019-04-20 23:00:15 +00:00
|
|
|
HEAD3= 1.191;
|
2017-03-23 10:53:57 +00:00
|
|
|
ABODY = 1.08;
|
|
|
|
AHEAD = 1.12;
|
|
|
|
BIRD = 1.20;
|
|
|
|
}
|
|
|
|
else {
|
2019-05-29 14:27:24 +00:00
|
|
|
INFDEEP = GDIM == 3 ? (sphere ? M_PI/2 : +5) : (euclid || sphere) ? 0.01 : lev_to_projection(0) * tanh(vid.camera);
|
2018-04-23 10:34:14 +00:00
|
|
|
ld wh = actual_wall_height();
|
|
|
|
WALL = lev_to_factor(wh);
|
2019-05-08 16:33:08 +00:00
|
|
|
FLOOR = lev_to_factor(0);
|
2017-03-23 10:53:57 +00:00
|
|
|
|
2019-05-29 14:27:24 +00:00
|
|
|
human_height = vid.human_wall_ratio * wh;
|
|
|
|
if(WDIM == 3) human_height = scalefactor * vid.height_width / 2;
|
2019-05-08 16:33:08 +00:00
|
|
|
|
|
|
|
ld reduce = (WDIM == 3 ? human_height / 2 : 0);
|
2019-02-27 17:59:21 +00:00
|
|
|
|
|
|
|
LEG0 = lev_to_factor(human_height * .0 - reduce);
|
|
|
|
LEG1 = lev_to_factor(human_height * .1 - reduce);
|
|
|
|
LEG = lev_to_factor(human_height * .2 - reduce);
|
|
|
|
LEG3 = lev_to_factor(human_height * .3 - reduce);
|
|
|
|
GROIN = lev_to_factor(human_height * .4 - reduce);
|
|
|
|
GROIN1= lev_to_factor(human_height * .5 - reduce);
|
|
|
|
BODY = lev_to_factor(human_height * .6 - reduce);
|
2019-02-27 18:15:58 +00:00
|
|
|
BODY1 = lev_to_factor(human_height * .61 - reduce);
|
|
|
|
BODY2 = lev_to_factor(human_height * .62 - reduce);
|
|
|
|
BODY3 = lev_to_factor(human_height * .63 - reduce);
|
2019-02-27 17:59:21 +00:00
|
|
|
NECK1 = lev_to_factor(human_height * .7 - reduce);
|
|
|
|
NECK = lev_to_factor(human_height * .8 - reduce);
|
|
|
|
NECK3 = lev_to_factor(human_height * .9 - reduce);
|
2019-04-20 23:00:15 +00:00
|
|
|
HEAD = lev_to_factor(human_height * .97 - reduce);
|
|
|
|
HEAD1 = lev_to_factor(human_height * .98 - reduce);
|
|
|
|
HEAD2 = lev_to_factor(human_height * .99 - reduce);
|
|
|
|
HEAD3 = lev_to_factor(human_height - reduce);
|
2017-03-23 10:53:57 +00:00
|
|
|
|
2019-02-27 17:59:21 +00:00
|
|
|
reduce = (DIM == 3 ? human_height * .3 : 0);
|
|
|
|
|
2019-05-15 16:43:40 +00:00
|
|
|
STUFF = lev_to_factor(0) - max(orbsize * 0.3, zhexf * .6);
|
2019-05-08 16:33:08 +00:00
|
|
|
|
2019-02-27 17:59:21 +00:00
|
|
|
ABODY = lev_to_factor(human_height * .4 - reduce);
|
|
|
|
ALEG0 = lev_to_factor(human_height * .0 - reduce);
|
|
|
|
ALEG = lev_to_factor(human_height * .2 - reduce);
|
|
|
|
AHEAD = lev_to_factor(human_height * .6 - reduce);
|
2019-05-29 14:27:24 +00:00
|
|
|
BIRD = lev_to_factor(WDIM == 3 ? 0 : (vid.human_wall_ratio+1)/2 * wh * .8);
|
2019-05-12 18:06:24 +00:00
|
|
|
GHOST = lev_to_factor(WDIM == 3 ? 0 : human_height * .5);
|
2017-03-23 10:53:57 +00:00
|
|
|
FLATEYE = lev_to_factor(human_height * .15);
|
|
|
|
|
2019-05-29 14:27:24 +00:00
|
|
|
slev = vid.rock_wall_ratio * wh / 3;
|
2017-03-23 10:53:57 +00:00
|
|
|
for(int s=0; s<=3; s++)
|
2019-05-29 14:27:24 +00:00
|
|
|
SLEV[s] = lev_to_factor(vid.rock_wall_ratio * wh * s/3);
|
|
|
|
LAKE = lev_to_factor(-vid.lake_top);
|
|
|
|
HELLSPIKE = lev_to_factor(-(vid.lake_top+vid.lake_bottom)/2);
|
|
|
|
BOTTOM = lev_to_factor(-vid.lake_bottom);
|
2019-06-07 15:51:50 +00:00
|
|
|
LOWSKY = lev_to_factor(2 * wh);
|
2019-05-24 23:36:49 +00:00
|
|
|
HIGH = LOWSKY;
|
2019-06-07 15:51:50 +00:00
|
|
|
HIGH2 = lev_to_factor(3 * wh);
|
2019-05-20 11:40:56 +00:00
|
|
|
SKY = LOWSKY - 5;
|
2017-03-23 10:53:57 +00:00
|
|
|
}
|
|
|
|
}
|
2019-05-09 15:01:08 +00:00
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
namespace geom3 {
|
2019-05-11 06:19:38 +00:00
|
|
|
#if MAXMDIM >= 4
|
|
|
|
void switch_always3() {
|
2019-05-28 23:09:38 +00:00
|
|
|
if(dual::split(switch_always3)) return;
|
2019-05-13 10:59:49 +00:00
|
|
|
if(rug::rugged) rug::close();
|
2019-05-29 14:27:24 +00:00
|
|
|
vid.always3 = !vid.always3;
|
2019-05-10 02:03:07 +00:00
|
|
|
swapmatrix(View);
|
2019-05-09 15:01:08 +00:00
|
|
|
callhooks(hooks_swapdim);
|
|
|
|
}
|
2019-05-11 06:19:38 +00:00
|
|
|
#endif
|
2019-05-09 15:01:08 +00:00
|
|
|
|
|
|
|
void switch_tpp() {
|
2019-05-28 23:09:38 +00:00
|
|
|
if(dual::split(switch_fpp)) return;
|
2019-05-09 15:01:08 +00:00
|
|
|
if(pmodel == mdDisk && vid.camera_angle) {
|
|
|
|
vid.yshift = 0;
|
|
|
|
vid.camera_angle = 0;
|
|
|
|
vid.xposition = 0;
|
|
|
|
vid.yposition = 0;
|
|
|
|
vid.scale = 1;
|
|
|
|
vid.fixed_facing = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vid.yshift = -0.3;
|
|
|
|
vid.camera_angle = -45;
|
|
|
|
vid.scale = 18/16. * vid.xres / vid.yres / multi::players;
|
|
|
|
vid.xposition = 0;
|
|
|
|
vid.yposition = -0.9;
|
|
|
|
vid.fixed_facing = true;
|
|
|
|
vid.fixed_facing_dir = 90;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void switch_fpp() {
|
2019-05-11 06:19:38 +00:00
|
|
|
#if MAXMDIM >= 4
|
2019-05-13 10:59:49 +00:00
|
|
|
if(rug::rugged) rug::close();
|
2019-05-28 23:09:38 +00:00
|
|
|
if(dual::split(switch_fpp)) return;
|
2019-05-28 23:20:25 +00:00
|
|
|
check_cgi(); cgi.require_basics();
|
2019-06-13 15:03:32 +00:00
|
|
|
View = inverse(conformal::rotmatrix()) * View;
|
2019-05-29 14:27:24 +00:00
|
|
|
if(!vid.always3) {
|
|
|
|
vid.always3 = true;
|
2019-05-28 23:20:25 +00:00
|
|
|
ld ms = min<ld>(cgi.scalefactor, 1);
|
2019-05-29 14:27:24 +00:00
|
|
|
vid.wall_height = 1.5 * ms;
|
2019-05-09 17:15:00 +00:00
|
|
|
if(sphere) {
|
2019-05-29 14:27:24 +00:00
|
|
|
vid.depth = M_PI / 6;
|
|
|
|
vid.wall_height = M_PI / 3;
|
2019-05-09 17:15:00 +00:00
|
|
|
}
|
2019-05-29 14:27:24 +00:00
|
|
|
vid.human_wall_ratio = 0.8;
|
2019-05-28 23:20:25 +00:00
|
|
|
if(euclid && allowIncreasedSight() && vid.use_smart_range == 0) {
|
|
|
|
genrange_bonus = gamerange_bonus = sightrange_bonus = cgi.base_distlimit * 3/2;
|
|
|
|
}
|
2019-05-29 14:27:24 +00:00
|
|
|
vid.camera = 0;
|
|
|
|
vid.depth = ms;
|
2019-05-09 15:01:08 +00:00
|
|
|
if(pmodel == mdDisk) pmodel = mdPerspective;
|
2019-05-10 02:03:07 +00:00
|
|
|
swapmatrix(View);
|
2019-05-09 15:01:08 +00:00
|
|
|
callhooks(hooks_swapdim);
|
2019-05-13 14:01:52 +00:00
|
|
|
#if CAP_RACING
|
|
|
|
racing::player_relative = true;
|
|
|
|
#endif
|
2019-05-09 15:01:08 +00:00
|
|
|
}
|
|
|
|
else {
|
2019-05-29 14:27:24 +00:00
|
|
|
vid.always3 = false;
|
|
|
|
vid.wall_height = .3;
|
|
|
|
vid.human_wall_ratio = .7;
|
|
|
|
vid.camera = 1;
|
|
|
|
vid.depth = 1;
|
2019-05-09 15:01:08 +00:00
|
|
|
if(pmodel == mdPerspective) pmodel = mdDisk;
|
2019-05-10 02:03:07 +00:00
|
|
|
swapmatrix(View);
|
2019-05-09 15:01:08 +00:00
|
|
|
callhooks(hooks_swapdim);
|
|
|
|
}
|
2019-06-13 15:03:32 +00:00
|
|
|
View = conformal::rotmatrix() * View;
|
2019-05-11 06:19:38 +00:00
|
|
|
#endif
|
2019-06-13 15:03:32 +00:00
|
|
|
}
|
2019-05-09 15:01:08 +00:00
|
|
|
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
geometry_information *cgip;
|
|
|
|
map<string, geometry_information> cgis;
|
|
|
|
|
2019-06-18 14:01:28 +00:00
|
|
|
int last_texture_step;
|
|
|
|
|
2019-06-18 14:16:09 +00:00
|
|
|
int ntimestamp;
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
void check_cgi() {
|
|
|
|
string s;
|
|
|
|
auto V = [&] (string a, string b) { s += a; s += ": "; s += b; s += "; "; };
|
|
|
|
V("GEO", its(int(geometry)));
|
|
|
|
V("VAR", its(int(variation)));
|
|
|
|
|
|
|
|
if(GOLDBERG) V("GP", its(gp::param.first) + "," + its(gp::param.second));
|
|
|
|
if(IRREGULAR) V("IRR", its(irr::irrid));
|
|
|
|
|
|
|
|
if(geometry == gArchimedean) V("ARCM", arcm::current.symbol);
|
|
|
|
|
|
|
|
if(geometry == gCrystal) V("CRYSTAL", its(ginf[gCrystal].sides) + its(ginf[gCrystal].vertex));
|
|
|
|
|
|
|
|
if(binarytiling || DIM == 3) V("WQ", its(vid.texture_step));
|
|
|
|
|
|
|
|
if(binarytiling) V("BT", fts(vid.binary_width));
|
|
|
|
|
|
|
|
if(GDIM == 2) {
|
2019-05-29 14:27:24 +00:00
|
|
|
V("CAMERA", fts(vid.camera));
|
2019-05-26 16:04:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(WDIM == 2) {
|
2019-05-29 14:27:24 +00:00
|
|
|
V("WH", fts(vid.wall_height));
|
|
|
|
V("HW", fts(vid.human_wall_ratio));
|
|
|
|
V("RW", fts(vid.rock_wall_ratio));
|
|
|
|
V("DEPTH", fts(vid.depth));
|
|
|
|
V("ASH", ONOFF(vid.gp_autoscale_heights));
|
|
|
|
V("LT", fts(vid.lake_top));
|
|
|
|
V("LB", fts(vid.lake_bottom));
|
2019-05-26 16:04:02 +00:00
|
|
|
}
|
|
|
|
|
2019-05-29 14:27:24 +00:00
|
|
|
V("3D", ONOFF(vid.always3));
|
2019-05-26 16:04:02 +00:00
|
|
|
|
2019-07-21 21:12:16 +00:00
|
|
|
if(scale_used()) V("CS", fts(vid.creature_scale));
|
2019-05-26 16:04:02 +00:00
|
|
|
|
2019-07-21 21:12:16 +00:00
|
|
|
if(WDIM == 3) V("HTW", fts(vid.height_width));
|
|
|
|
|
2019-05-26 16:04:02 +00:00
|
|
|
V("LQ", its(vid.linequality));
|
|
|
|
|
|
|
|
cgip = &cgis[s];
|
2019-06-18 14:16:09 +00:00
|
|
|
cgi.timestamp = ++ntimestamp;
|
2019-06-18 14:01:28 +00:00
|
|
|
|
2019-06-18 14:16:09 +00:00
|
|
|
if(isize(cgis) > 4) {
|
2019-06-18 14:01:28 +00:00
|
|
|
cgi.timestamp = ticks;
|
|
|
|
vector<pair<int, string>> timestamps;
|
|
|
|
for(auto& t: cgis) timestamps.emplace_back(-t.second.timestamp, t.first);
|
|
|
|
sort(timestamps.begin(), timestamps.end());
|
2019-06-18 14:16:09 +00:00
|
|
|
while(isize(timestamps) > 4) {
|
2019-06-18 14:01:28 +00:00
|
|
|
println(hlog, "erasing geometry ", timestamps.back().second);
|
|
|
|
cgis.erase(timestamps.back().second);
|
|
|
|
timestamps.pop_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(floor_textures && last_texture_step != vid.texture_step) {
|
|
|
|
println(hlog, "changed ", last_texture_step, " to ", vid.texture_step);
|
|
|
|
delete floor_textures;
|
|
|
|
floor_textures = NULL;
|
|
|
|
}
|
|
|
|
|
2019-07-12 21:17:00 +00:00
|
|
|
#if MAXMDIM >= 4
|
2019-06-18 14:01:28 +00:00
|
|
|
if(!floor_textures && DIM == 3 && (cgi.state & 2))
|
|
|
|
make_floor_textures();
|
2019-07-12 21:17:00 +00:00
|
|
|
#endif
|
2019-06-18 14:01:28 +00:00
|
|
|
|
2015-08-08 13:57:52 +00:00
|
|
|
}
|
2019-05-26 16:04:02 +00:00
|
|
|
|
2019-06-18 14:01:28 +00:00
|
|
|
void clear_cgis() {
|
|
|
|
printf("clear_cgis\n");
|
|
|
|
for(auto& p: cgis) if(&p.second != &cgi) { cgis.erase(p.first); return; }
|
|
|
|
}
|
|
|
|
|
|
|
|
auto ah_clear_geo = addHook(hooks_clear_cache, 0, clear_cgis);
|
|
|
|
|
2018-06-10 23:58:31 +00:00
|
|
|
}
|