moved all projection-related parameters to a special struct; another copy of that struct created for rug

This commit is contained in:
Zeno Rogue 2020-04-17 00:53:58 +02:00
parent f8cbf67a8e
commit 0472bf764f
29 changed files with 580 additions and 562 deletions

View File

@ -842,12 +842,12 @@ EX ld realradius() {
ld vradius = current_display->radius;
if(sphere) {
if(sphereflipped())
vradius /= sqrt(vid.alpha*vid.alpha - 1);
vradius /= sqrt(pconf.alpha*pconf.alpha - 1);
else
vradius = 1e12; // use the following
}
if(euclid)
vradius = current_display->radius * get_sightrange() / (1 + vid.alpha) / 2.5;
vradius = current_display->radius * get_sightrange() / (1 + pconf.alpha) / 2.5;
vradius = min<ld>(vradius, min(vid.xres, vid.yres) / 2);
return vradius;
}
@ -857,14 +857,14 @@ EX void drawmessage(const string& s, int& y, color_t col) {
int space;
if(dual::state)
space = vid.xres;
else if(y > current_display->ycenter + rrad * vid.stretch)
else if(y > current_display->ycenter + rrad * pconf.stretch)
space = vid.xres;
else if(y > current_display->ycenter)
space = current_display->xcenter - rhypot(rrad, (y-current_display->ycenter) / vid.stretch);
space = current_display->xcenter - rhypot(rrad, (y-current_display->ycenter) / pconf.stretch);
else if(y > current_display->ycenter - vid.fsize)
space = current_display->xcenter - rrad;
else if(y > current_display->ycenter - vid.fsize - rrad * vid.stretch)
space = current_display->xcenter - rhypot(rrad, (current_display->ycenter-vid.fsize-y) / vid.stretch);
else if(y > current_display->ycenter - vid.fsize - rrad * pconf.stretch)
space = current_display->xcenter - rhypot(rrad, (current_display->ycenter-vid.fsize-y) / pconf.stretch);
else
space = vid.xres;
@ -949,7 +949,7 @@ EX void drawCircle(int x, int y, int size, color_t color, color_t fillcolor IS(0
if(ISMOBILE && pts > 72) pts = 72;
for(int r=0; r<pts; r++) {
float rr = (M_PI * 2 * r) / pts;
glcoords.push_back(glhr::makevertex(x + size * sin(rr), y + size * vid.stretch * cos(rr), 0));
glcoords.push_back(glhr::makevertex(x + size * sin(rr), y + size * pconf.stretch * cos(rr), 0));
}
current_display->set_all(0);
glhr::vertices(glcoords);
@ -969,13 +969,13 @@ EX void drawCircle(int x, int y, int size, color_t color, color_t fillcolor IS(0
#if CAP_XGD
gdpush(4); gdpush(color); gdpush(x); gdpush(y); gdpush(size);
#elif CAP_SDLGFX
if(vid.stretch == 1) {
if(pconf.stretch == 1) {
if(fillcolor) filledCircleColor(s, x, y, size, fillcolor);
if(color) ((vid.antialias && AA_NOGL)?aacircleColor:circleColor) (s, x, y, size, color);
}
else {
if(fillcolor) filledEllipseColor(s, x, y, size, size * vid.stretch, fillcolor);
if(color) ((vid.antialias && AA_NOGL)?aaellipseColor:ellipseColor) (s, x, y, size, size * vid.stretch, color);
if(fillcolor) filledEllipseColor(s, x, y, size, size * pconf.stretch, fillcolor);
if(color) ((vid.antialias && AA_NOGL)?aaellipseColor:ellipseColor) (s, x, y, size, size * pconf.stretch, color);
}
#elif CAP_SDL
int pts = size * 4;
@ -1022,7 +1022,7 @@ EX void displayColorButton(int x, int y, const string& name, int key, int align,
}
ld textscale() {
return vid.fsize / (current_display->radius * cgi.crossf) * (1+vid.alpha) * 2;
return vid.fsize / (current_display->radius * cgi.crossf) * (1+pconf.alpha) * 2;
}
EX bool setfsize = true;

View File

@ -305,10 +305,10 @@ EX void initConfig() {
addsaver(precise_width, "precisewidth", .5);
addsaver(linepatterns::width, "pattern-linewidth", 1);
addsaver(fat_edges, "fat-edges");
addsaver(vid.scale, "scale", 1);
addsaver(vid.xposition, "xposition", 0);
addsaver(vid.yposition, "yposition", 0);
addsaver(vid.alpha, "projection", 1);
addsaver(pconf.scale, "scale", 1);
addsaver(pconf.xposition, "xposition", 0);
addsaver(pconf.yposition, "yposition", 0);
addsaver(pconf.alpha, "projection", 1);
addsaver(vid.sspeed, "scrollingspeed", 0);
addsaver(vid.mspeed, "movement speed", 1);
addsaver(vid.full, "fullscreen", false);
@ -329,14 +329,14 @@ EX void initConfig() {
// special graphics
addsaver(vid.ballangle, "ball angle", 20);
addsaver(pconf.ballangle, "ball angle", 20);
addsaver(vid.yshift, "Y shift", 0);
addsaver(vid.use_wall_radar, "wallradar", true);
addsaver(vid.fixed_facing, "fixed facing", 0);
addsaver(vid.fixed_facing_dir, "fixed facing dir", 90);
addsaver(vid.fixed_yz, "fixed YZ", true);
addsaver(vid.camera_angle, "camera angle", 0);
addsaver(vid.ballproj, "ballproj", 1);
addsaver(pconf.camera_angle, "camera angle", 0);
addsaver(pconf.ballproj, "ballproj", 1);
addsaver(vid.monmode, "monster display mode", DEFAULT_MONMODE);
addsaver(vid.wallmode, "wall display mode", DEFAULT_WALLMODE);
@ -389,16 +389,16 @@ EX void initConfig() {
addsaver(models::rotation_xz, "conformal rotation_xz");
addsaver(models::rotation_xy2, "conformal rotation_2");
addsaver(models::do_rotate, "conformal rotation mode", 1);
addsaver(models::model_orientation, "model orientation", 0);
addsaver(models::model_orientation_yz, "model orientation-yz", 0);
addsaver(models::top_z, "topz", 5);
addsaver(models::model_transition, "model transition", 1);
addsaver(models::halfplane_scale, "halfplane scale", 1);
addsaver(pconf.model_orientation, "model orientation", 0);
addsaver(pconf.model_orientation_yz, "model orientation-yz", 0);
addsaver(pconf.top_z, "topz", 5);
addsaver(pconf.model_transition, "model transition", 1);
addsaver(pconf.halfplane_scale, "halfplane scale", 1);
addsaver(history::autoband, "automatic band");
addsaver(history::autobandhistory, "automatic band history");
addsaver(history::dospiral, "do spiral");
addsaver(models::clip_min, "clip-min", -1);
addsaver(models::clip_max, "clip-max", +1);
addsaver(pconf.clip_min, "clip-min", -1);
addsaver(pconf.clip_max, "clip-max", +1);
addsaver(vid.backeffects, "background particle effects", (ISMOBILE || ISPANDORA) ? false : true);
// control
@ -468,13 +468,13 @@ EX void initConfig() {
addsaver(vid.fov, "field-of-vision", 90);
addsaver(vid.desaturate, "desaturate", 0);
addsaverenum(vid.stereo_mode, "stereo-mode");
addsaver(vid.euclid_to_sphere, "euclid to sphere projection", 1.5);
addsaver(vid.twopoint_param, "twopoint parameter", 1);
addsaver(vid.fisheye_param, "fisheye parameter", 1);
addsaver(vid.stretch, "stretch", 1);
addsaver(pconf.euclid_to_sphere, "euclid to sphere projection", 1.5);
addsaver(pconf.twopoint_param, "twopoint parameter", 1);
addsaver(pconf.fisheye_param, "fisheye parameter", 1);
addsaver(pconf.stretch, "stretch", 1);
addsaver(vid.binary_width, "binary-tiling-width", 1);
addsaver(vid.collignon_parameter, "collignon-parameter", 1);
addsaver(vid.collignon_reflected, "collignon-reflect", false);
addsaver(pconf.collignon_parameter, "collignon-parameter", 1);
addsaver(pconf.collignon_reflected, "collignon-reflect", false);
addsaver(vid.plevel_factor, "plevel_factor", 0.7);
@ -545,11 +545,11 @@ EX void initConfig() {
addsaver(slr::steps, "slr-steps");
addsaver(slr::range_xy, "slr-range-xy");
addsaver(vid.skiprope, "mobius", 0);
addsaver(pconf.skiprope, "mobius", 0);
addsaver(models::formula, "formula");
addsaverenum(models::basic_model, "basic model");
addsaver(models::use_atan, "use_atan");
addsaver(pconf.formula, "formula");
addsaverenum(pconf.basic_model, "basic model");
addsaver(pconf.use_atan, "use_atan");
addsaver(arcm::current.symbol, "arcm-symbol", "4^5");
addsaverenum(hybrid::underlying, "product-underlying");
@ -670,7 +670,7 @@ EX bool inSpecialMode() {
tour::on ||
#endif
yendor::on || tactic::on || randomPatternsMode ||
geometry != gNormal || pmodel != mdDisk || vid.alpha != 1 || vid.scale != 1 ||
geometry != gNormal || pmodel != mdDisk || pconf.alpha != 1 || pconf.scale != 1 ||
rug::rugged || vid.monmode != DEFAULT_MONMODE ||
vid.wallmode != DEFAULT_WALLMODE;
}
@ -697,7 +697,7 @@ EX bool have_current_settings() {
}
EX bool have_current_graph_settings() {
if(vid.xposition || vid.yposition || vid.alpha != 1 || vid.scale != 1)
if(pconf.xposition || pconf.yposition || pconf.alpha != 1 || pconf.scale != 1)
return true;
if(pmodel != mdDisk || vid.monmode != DEFAULT_MONMODE || vid.wallmode != DEFAULT_WALLMODE)
return true;
@ -708,8 +708,8 @@ EX bool have_current_graph_settings() {
}
EX void reset_graph_settings() {
pmodel = mdDisk; vid.alpha = 1; vid.scale = 1;
vid.xposition = vid.yposition = 0;
pmodel = mdDisk; pconf.alpha = 1; pconf.scale = 1;
pconf.xposition = pconf.yposition = 0;
#if CAP_RUG
if(rug::rugged) rug::close();
#endif
@ -1431,7 +1431,7 @@ EX void showJoyConfig() {
EX void projectionDialog() {
vid.tc_alpha = ticks;
dialog::editNumber(vid.alpha, -5, 5, .1, 1,
dialog::editNumber(vpconf.alpha, -5, 5, .1, 1,
XLAT("projection"),
XLAT("HyperRogue uses the Minkowski hyperboloid model internally. "
"Klein and Poincaré models can be obtained by perspective, "
@ -1449,17 +1449,17 @@ EX void projectionDialog() {
"tanh(g)/tanh(c) units below the center. This in turn corresponds to "
"the Poincaré model for g=c, and Klein-Beltrami model for g=0."));
dialog::addSelItem(sphere ? "stereographic" : "Poincaré model", "1", 'P');
dialog::add_action([] () { *dialog::ne.editwhat = 1; vid.scale = 1; dialog::ne.s = "1"; });
dialog::add_action([] () { *dialog::ne.editwhat = 1; vpconf.scale = 1; dialog::ne.s = "1"; });
dialog::addSelItem(sphere ? "gnomonic" : "Klein model", "0", 'K');
dialog::add_action([] () { *dialog::ne.editwhat = 0; vid.scale = 1; dialog::ne.s = "0"; });
dialog::add_action([] () { *dialog::ne.editwhat = 0; vpconf.scale = 1; dialog::ne.s = "0"; });
if(hyperbolic) {
dialog::addSelItem("inverted Poincaré model", "-1", 'I');
dialog::add_action([] () { *dialog::ne.editwhat = -1; vid.scale = 1; dialog::ne.s = "-1"; });
dialog::add_action([] () { *dialog::ne.editwhat = -1; vpconf.scale = 1; dialog::ne.s = "-1"; });
}
dialog::addItem(sphere ? "orthographic" : "Gans model", 'O');
dialog::add_action([] () { vid.alpha = vid.scale = 999; dialog::ne.s = dialog::disp(vid.alpha); });
dialog::add_action([] () { vpconf.alpha = vpconf.scale = 999; dialog::ne.s = dialog::disp(vpconf.alpha); });
dialog::addItem(sphere ? "towards orthographic" : "towards Gans model", 'T');
dialog::add_action([] () { double d = 1.1; vid.alpha *= d; vid.scale *= d; dialog::ne.s = dialog::disp(vid.alpha); });
dialog::add_action([] () { double d = 1.1; vpconf.alpha *= d; vpconf.scale *= d; dialog::ne.s = dialog::disp(vpconf.alpha); });
};
}
@ -1564,7 +1564,7 @@ EX void showStereo() {
}
EX void config_camera_rotation() {
dialog::editNumber(vid.ballangle, 0, 90, 5, 0, XLAT("camera rotation in 3D models"),
dialog::editNumber(pconf.ballangle, 0, 90, 5, 0, XLAT("camera rotation in 3D models"),
"Rotate the camera in 3D models (ball model, hyperboloid, and hemisphere). "
"Note that hyperboloid and hemisphere models are also available in the "
"Hypersian Rug surfaces menu, but they are rendered differently there -- "
@ -1648,9 +1648,9 @@ EX void show3D() {
if(GDIM == 2)
dialog::addSelItem(XLAT("Projection at the ground level"), fts(vid.alpha), 'p');
dialog::addSelItem(XLAT("Projection at the ground level"), fts(pconf.alpha), 'p');
else if(!in_perspective())
dialog::addSelItem(XLAT("Projection distance"), fts(vid.alpha), 'p');
dialog::addSelItem(XLAT("Projection distance"), fts(pconf.alpha), 'p');
dialog::addBreak(50);
dialog::addSelItem(XLAT("Height of walls"), fts(vid.wall_height), 'w');
@ -1676,7 +1676,7 @@ EX void show3D() {
dialog::editNumber(mouseaim_sensitivity, -1, 1, 0.002, 0.01, XLAT("mouse aiming sensitivity"), "set to 0 to disable");
});
}
dialog::addSelItem(XLAT("camera rotation"), fts(vid.camera_angle), 's');
dialog::addSelItem(XLAT("camera rotation"), fts(vpconf.camera_angle), 's');
if(GDIM == 2) {
dialog::addSelItem(XLAT("fixed facing"), vid.fixed_facing ? fts(vid.fixed_facing_dir) : XLAT("OFF"), 'f');
dialog::add_action([] () { vid.fixed_facing = !vid.fixed_facing;
@ -1730,7 +1730,7 @@ EX void show3D() {
}
#endif
if(GDIM == 2) {
dialog::addBoolItem(XLAT("configure TPP automatically"), pmodel == mdDisk && vid.camera_angle, 'T');
dialog::addBoolItem(XLAT("configure TPP automatically"), pmodel == mdDisk && pconf.camera_angle, 'T');
dialog::add_action(geom3::switch_tpp);
}
@ -1902,7 +1902,7 @@ EX void show3D() {
};
}
else if(uni == 's')
dialog::editNumber(vid.camera_angle, -180, 180, 5, 0, XLAT("camera rotation"),
dialog::editNumber(vpconf.camera_angle, -180, 180, 5, 0, XLAT("camera rotation"),
XLAT("Rotate the camera. Can be used to obtain a first person perspective, "
"or third person perspective when combined with Y shift.")
);
@ -1961,9 +1961,9 @@ EX void showCustomizeChar() {
dynamicval<eModel> pm(pmodel, flat_model());
glClear(GL_DEPTH_BUFFER_BIT);
dynamicval<ld> va(vid.alpha, 1);
dynamicval<ld> vs(vid.scale, 1);
dynamicval<ld> vc(vid.camera_angle, 0);
dynamicval<ld> va(pconf.alpha, 1);
dynamicval<ld> vs(pconf.scale, 1);
dynamicval<ld> vc(pconf.camera_angle, 0);
initquickqueue();
transmatrix V = atscreenpos(vid.xres/2, firsty, scale);
@ -2465,7 +2465,7 @@ EX int read_config_args() {
else if(argis("-yca")) {
PHASEFROM(2);
shift_arg_formula(vid.yshift);
shift_arg_formula(vid.camera_angle);
shift_arg_formula(pconf.camera_angle);
}
else if(argis("-pside")) {
PHASEFROM(2);
@ -2473,8 +2473,8 @@ EX int read_config_args() {
}
else if(argis("-xy")) {
PHASEFROM(2);
shift_arg_formula(vid.xposition);
shift_arg_formula(vid.yposition);
shift_arg_formula(pconf.xposition);
shift_arg_formula(pconf.yposition);
}
else if(argis("-fixdir")) {
PHASEFROM(2);
@ -2582,15 +2582,15 @@ auto ah_config = addHook(hooks_args, 0, read_config_args) + addHook(hooks_args,
EX unordered_map<string, ld&> params = {
{"linewidth", vid.linewidth},
{"patternlinewidth", linepatterns::width},
{"scale", vid.scale},
{"xposition", vid.xposition},
{"yposition", vid.yposition},
{"projection", vid.alpha},
{"scale", pconf.scale},
{"xposition", pconf.xposition},
{"yposition", pconf.yposition},
{"projection", pconf.alpha},
{"sspeed", vid.sspeed},
{"mspeed", vid.mspeed},
{"ballangle", vid.ballangle},
{"ballangle", pconf.ballangle},
{"yshift", vid.yshift},
{"cameraangle", vid.camera_angle},
{"cameraangle", pconf.camera_angle},
{"eye", vid.eye},
{"depth", vid.depth},
{"camera", vid.camera},
@ -2607,22 +2607,22 @@ EX unordered_map<string, ld&> params = {
{"star", polygonal::STAR},
{"lvspeed", history::lvspeed},
{"rotation", models::rotation},
{"mori", models::model_orientation},
{"mori_yz", models::model_orientation_yz},
{"clipmin", models::clip_min},
{"clipmax", models::clip_max},
{"topz", models::top_z},
{"mtrans", models::model_transition},
{"hp", models::halfplane_scale},
{"mori", pconf.model_orientation},
{"mori_yz", pconf.model_orientation_yz},
{"clipmin", pconf.clip_min},
{"clipmax", pconf.clip_max},
{"topz", pconf.top_z},
{"mtrans", pconf.model_transition},
{"hp", pconf.halfplane_scale},
{"back", backbrightness},
{"ipd", vid.ipd},
{"lr", vid.lr_eyewidth},
{"anaglyph", vid.anaglyph_eyewidth},
{"fov", vid.fov},
{"ets", vid.euclid_to_sphere},
{"stretch", vid.stretch},
{"twopoint", vid.twopoint_param},
{"fisheye", vid.fisheye_param},
{"ets", pconf.euclid_to_sphere},
{"stretch", pconf.stretch},
{"twopoint", pconf.twopoint_param},
{"fisheye", pconf.fisheye_param},
{"bwidth", vid.binary_width},
#if CAP_ANIMATIONS
{"aperiod", anims::period},
@ -2634,10 +2634,10 @@ EX unordered_map<string, ld&> params = {
{"a", anims::a},
{"b", anims::b},
#endif
{"mobius", vid.skiprope},
{"sang", models::spiral_angle},
{"spiralx", models::spiral_x},
{"spiraly", models::spiral_y},
{"mobius", pconf.skiprope},
{"sang", pconf.spiral_angle},
{"spiralx", pconf.spiral_x},
{"spiraly", pconf.spiral_y},
#if CAP_CRYSTAL
{"cprob", crystal::compass_probability},
#endif
@ -2646,7 +2646,7 @@ EX unordered_map<string, ld&> params = {
{"fade", shot::fade},
{"mgrid", vid.multiplier_grid},
{"mring", vid.multiplier_ring},
{"collignon", vid.collignon_parameter},
{"collignon", pconf.collignon_parameter},
{"levellines", levellines},
#endif
};

View File

@ -871,7 +871,7 @@ EX void handle_event(SDL_Event& ev) {
else if(ev.button.button==SDL_BUTTON_MIDDLE || rightclick) {
sym = 1, didsomething = true;
if(anyshift)
vid.xposition = vid.yposition = 0;
pconf.xposition = pconf.yposition = 0;
}
else if(ev.button.button == SDL_BUTTON_LEFT) {
sym = getcstat, uni = getcstat, shiftmul = getcshift;
@ -880,12 +880,12 @@ EX void handle_event(SDL_Event& ev) {
else if(ev.button.button==SDL_BUTTON_WHEELDOWN) {
if(anyctrl && anyshift && !rug::rugged && GDIM == 2) {
mapeditor::scaleall(1/1.2);
vid.alpha /= 1.2;
pconf.alpha /= 1.2;
}
else if(anyctrl && !rug::rugged && GDIM == 2)
mapeditor::scaleall(pow(2, -.25));
else if(anyshift && !rug::rugged && GDIM == 2)
vid.alpha -= 0.25;
pconf.alpha -= 0.25;
else if(rollchange) {
sym = getcstat, uni = getcstat, shiftmul = getcshift, wheelclick = true;
}
@ -896,12 +896,12 @@ EX void handle_event(SDL_Event& ev) {
if(ev.button.button==SDL_BUTTON_WHEELUP) {
if(anyctrl && anyshift && !rug::rugged && GDIM == 2) {
mapeditor::scaleall(1.2);
vid.alpha *= 1.2;
pconf.alpha *= 1.2;
}
else if(anyctrl && !rug::rugged && GDIM == 2)
mapeditor::scaleall(pow(2, .25));
else if(anyshift && !rug::rugged && GDIM == 2)
vid.alpha += 0.25;
pconf.alpha += 0.25;
else if(rollchange) {
sym = getcstat, uni = getcstat, shiftmul = -getcshift, wheelclick = true;
}
@ -935,8 +935,8 @@ EX void handle_event(SDL_Event& ev) {
if((rightclick || (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_MMASK)) && !mouseout2()) {
fix_mouseh();
if(anyctrl) {
vid.xposition += (mousex - lmousex) * 1. / current_display->scrsize,
vid.yposition += (mousey - lmousey) * 1. / current_display->scrsize;
pconf.xposition += (mousex - lmousex) * 1. / current_display->scrsize,
pconf.yposition += (mousey - lmousey) * 1. / current_display->scrsize;
}
else if(mouseh[LDIM] < 50 && mouseoh[LDIM] < 50) {
panning(mouseoh, mouseh);
@ -1053,7 +1053,7 @@ EX bool gmodekeys(int sym, int uni) {
if(GDIM == 2) {
if(among(NUMBERKEY, '1', '2', '3') && !rug::rugged && euclid && WDIM == 2) {
vid.xposition = vid.yposition = 0;
pconf.xposition = pconf.yposition = 0;
ld maxs = 0;
auto& cd = current_display;
for(auto& p: gmatrix) for(int i=0; i<p.first->type; i++) {
@ -1063,15 +1063,15 @@ EX bool gmodekeys(int sym, int uni) {
maxs = max(maxs, onscreen[0] / cd->xsize);
maxs = max(maxs, onscreen[1] / cd->ysize);
}
vid.alpha = 1;
vid.scale = vid.scale / 2 / maxs / cd->radius;
if(NUMBERKEY == '3') vid.scale *= 2;
if(NUMBERKEY == '1') vid.scale /= 2;
pconf.alpha = 1;
pconf.scale = pconf.scale / 2 / maxs / cd->radius;
if(NUMBERKEY == '3') pconf.scale *= 2;
if(NUMBERKEY == '1') pconf.scale /= 2;
}
else if(NUMBERKEY == '1' && !rug::rugged) { vid.alpha = 999; vid.scale = 998; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '2' && !rug::rugged) { vid.alpha = 1; vid.scale = 0.4; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '3' && !rug::rugged) { vid.alpha = 1; vid.scale = 1; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '4' && !rug::rugged) { vid.alpha = 0; vid.scale = 1; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '1' && !rug::rugged) { pconf.alpha = 999; pconf.scale = 998; pconf.xposition = pconf.yposition = 0; }
else if(NUMBERKEY == '2' && !rug::rugged) { pconf.alpha = 1; pconf.scale = 0.4; pconf.xposition = pconf.yposition = 0; }
else if(NUMBERKEY == '3' && !rug::rugged) { pconf.alpha = 1; pconf.scale = 1; pconf.xposition = pconf.yposition = 0; }
else if(NUMBERKEY == '4' && !rug::rugged) { pconf.alpha = 0; pconf.scale = 1; pconf.xposition = pconf.yposition = 0; }
else if(NUMBERKEY == '5') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 7; }
else if(NUMBERKEY == '8') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; }
else if(uni == '%') {
@ -1189,10 +1189,10 @@ EX void show() {
dialog::addItem(XLAT("experiment with geometry"), 'g');
dialog::add_action([] () { runGeometryExperiments(); });
dialog::addSelItem(XLAT("projection"), fts(vid.alpha), 'p');
dialog::addSelItem(XLAT("projection"), fts(vpconf.alpha), 'p');
dialog::add_action([] () { projectionDialog(); });
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
dialog::addSelItem(XLAT("scale factor"), fts(vpconf.scale), 'z');
dialog::add_action([] () { editScale(); });
dialog::addItem(XLAT("spherical VR"), 'v');
@ -1201,7 +1201,7 @@ EX void show() {
mode = 0; fullcenter();
mode = 2; sensitivity = 1;
vid.stereo_mode = sLR; vid.ipd = 0.2;
vid.alpha = 0; vid.scale = 1;
vpconf.alpha = 0; vpconf.scale = 1;
});
dialog::addBreak(100);

View File

@ -66,7 +66,7 @@ void launch(int seed, int elimit, int hlimit) {
dual::switch_to(0);
specialland = firstland = laCanvas;
canvas_default_wall = waSea;
vid.scale = .5;
pconf.scale = .5;
dual::switch_to(1);
specialland = firstland = laCanvas;
shrand(seed);

View File

@ -264,13 +264,13 @@ void add1(const hyperpoint& H) {
}
bool is_behind(const hyperpoint& H) {
return pmodel == mdDisk && (hyperbolic ? H[2] >= 0 : true) && (nonisotropic ? false : vid.alpha + H[2] <= BEHIND_LIMIT);
return pmodel == mdDisk && (hyperbolic ? H[2] >= 0 : true) && (nonisotropic ? false : pconf.alpha + H[2] <= BEHIND_LIMIT);
}
hyperpoint be_just_on_view(const hyperpoint& H1, const hyperpoint &H2) {
// H1[2] * t + H2[2] * (1-t) == BEHIND_LIMIT - vid.alpha
// H2[2]- BEHIND_LIMIT + vid.alpha = t * (H2[2] - H1[2])
ld t = (H2[2] - BEHIND_LIMIT + vid.alpha) / (H2[2] - H1[2]);
// H1[2] * t + H2[2] * (1-t) == BEHIND_LIMIT - pconf.alpha
// H2[2]- BEHIND_LIMIT + pconf.alpha = t * (H2[2] - H1[2])
ld t = (H2[2] - BEHIND_LIMIT + pconf.alpha) / (H2[2] - H1[2]);
return H1 * t + H2 * (1-t);
}
@ -291,14 +291,14 @@ EX bool two_sided_model() {
if(pmodel == mdDisk) return sphere;
if(pmodel == mdHemisphere) return true;
if(pmodel == mdRotatedHyperboles) return true;
if(pmodel == mdSpiral && models::spiral_cone < 360) return true;
if(pmodel == mdSpiral && pconf.spiral_cone < 360) return true;
return false;
}
EX int get_side(const hyperpoint& H) {
if(pmodel == mdDisk && sphere) {
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
double horizon = curnorm / vid.alpha;
double horizon = curnorm / pconf.alpha;
return (H[2] <= -horizon) ? -1 : 1;
}
if(pmodel == mdRotatedHyperboles)
@ -312,7 +312,7 @@ EX int get_side(const hyperpoint& H) {
applymodel(H, res);
return res[2] < 0 ? -1 : 1;
}
if(pmodel == mdSpiral && models::spiral_cone < 360) {
if(pmodel == mdSpiral && pconf.spiral_cone < 360) {
return cone_side(H);
}
return 0;
@ -336,13 +336,13 @@ void fixpoint(glvertex& hscr, hyperpoint H) {
}
hyperpoint Hscr;
applymodel(good, Hscr);
hscr = glhr::makevertex(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*current_display->radius);
hscr = glhr::makevertex(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*pconf.stretch, Hscr[2]*current_display->radius);
}
void addpoint(const hyperpoint& H) {
if(true) {
ld z = current_display->radius;
// if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
// if(pconf.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
if(spherespecial) {
@ -352,7 +352,7 @@ void addpoint(const hyperpoint& H) {
}
else if(sphere && (poly_flags & POLY_ISSIDE)) {
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
double horizon = curnorm / vid.alpha;
double horizon = curnorm / pconf.alpha;
poly_flags |= POLY_NOTINFRONT;
if(last_infront && nif_error_in(glcoords.back()[0], glcoords.back()[1], H[0], H[1]))
poly_flags |= POLY_NIF_ERROR;
@ -360,8 +360,8 @@ void addpoint(const hyperpoint& H) {
last_infront = true;
z *=
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
(sqrt(curnorm - H[2]*H[2]) / (vid.alpha+H[2]));
(sqrt(curnorm - horizon*horizon) / (pconf.alpha - horizon)) /
(sqrt(curnorm - H[2]*H[2]) / (pconf.alpha+H[2]));
}
else {
poly_flags |= POLY_NOTINFRONT;
@ -387,12 +387,12 @@ void addpoint(const hyperpoint& H) {
}
if(GDIM == 2) {
for(int i=0; i<3; i++) Hscr[i] *= z;
Hscr[1] *= vid.stretch;
Hscr[1] *= pconf.stretch;
}
else {
Hscr[0] *= z;
Hscr[1] *= z * vid.stretch;
Hscr[2] = 1 - 2 * (-Hscr[2] - models::clip_min) / (models::clip_max - models::clip_min);
Hscr[1] *= z * pconf.stretch;
Hscr[2] = 1 - 2 * (-Hscr[2] - pconf.clip_min) / (pconf.clip_max - pconf.clip_min);
}
add1(Hscr);
}
@ -484,11 +484,11 @@ void addpoly(const transmatrix& V, const vector<glvertex> &tab, int ofs, int cnt
/*
hyperpoint Hscr;
applymodel(goodpoint, Hscr);
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch+10, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius-10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*vid.stretch-10, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*vid.stretch, Hscr[2]*vid.radius)); */
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*pconf.stretch, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*pconf.stretch+10, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius-10, Hscr[1]*current_display->radius*pconf.stretch, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*pconf.stretch-10, Hscr[2]*vid.radius));
glcoords.push_back(make_array<GLfloat>(Hscr[0]*current_display->radius+10, Hscr[1]*current_display->radius*pconf.stretch, Hscr[2]*vid.radius)); */
}
}
@ -717,7 +717,7 @@ EX ld scale_at(const transmatrix& T) {
EX ld linewidthat(const hyperpoint& h) {
if(!(vid.antialias & AA_LINEWIDTH)) return 1;
else if(hyperbolic && pmodel == mdDisk && vid.alpha == 1 && !ISWEB) {
else if(hyperbolic && pmodel == mdDisk && pconf.alpha == 1 && !ISWEB) {
double dz = h[LDIM];
if(dz < 1) return 1;
else {
@ -752,7 +752,7 @@ vector<ld> periods;
ld period_at(ld y) {
ld m = current_display->radius;
y /= (m * vid.stretch);
y /= (m * pconf.stretch);
switch(pmodel) {
case mdBand:
@ -762,8 +762,8 @@ ld period_at(ld y) {
case mdMollweide:
return m * 2 * sqrt(1 - y*y*4);
case mdCollignon: {
if(vid.collignon_reflected && y > 0) y = -y;
y += signed_sqrt(vid.collignon_parameter);
if(pconf.collignon_reflected && y > 0) y = -y;
y += signed_sqrt(pconf.collignon_parameter);
return abs(m*y*2/1.2);
}
default:
@ -787,7 +787,7 @@ void adjust(bool tinf) {
ld cmin = -chypot/2, cmax = chypot/2, dmin = -chypot, dmax = chypot;
ld z = vid.stretch * current_display->radius;
ld z = pconf.stretch * current_display->radius;
switch(pmodel) {
case mdSinusoidal: case mdBandEquidistant: case mdMollweide:
@ -799,9 +799,9 @@ void adjust(bool tinf) {
break;
case mdCollignon:
dmin = z * (signed_sqrt(vid.collignon_parameter - 1) - signed_sqrt(vid.collignon_parameter));
if(vid.collignon_reflected) dmax = -dmin;
else dmax = z * (signed_sqrt(vid.collignon_parameter + 1) - signed_sqrt(vid.collignon_parameter));
dmin = z * (signed_sqrt(pconf.collignon_parameter - 1) - signed_sqrt(pconf.collignon_parameter));
if(pconf.collignon_reflected) dmax = -dmin;
else dmax = z * (signed_sqrt(pconf.collignon_parameter + 1) - signed_sqrt(pconf.collignon_parameter));
break;
default: ;
@ -891,7 +891,7 @@ void compute_side_by_centerin(dqi_poly *p, bool& nofill) {
else
nofill = true;
}
applymodel(h1, hscr); hscr[0] *= current_display->radius; hscr[1] *= current_display->radius * vid.stretch;
applymodel(h1, hscr); hscr[0] *= current_display->radius; hscr[1] *= current_display->radius * pconf.stretch;
for(int i=0; i<isize(glcoords)-1; i++) {
double x1 = glcoords[i][0] - hscr[0];
double y1 = glcoords[i][1] - hscr[1];
@ -916,11 +916,11 @@ void compute_side_by_centerin(dqi_poly *p, bool& nofill) {
/*
if(poly_flags & POLY_BADCENTERIN) {
glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*vid.stretch, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*vid.stretch+10, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0]-10, hscr[1]*vid.stretch, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*vid.stretch-10, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*vid.stretch, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*pconf.stretch, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*pconf.stretch+10, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0]-10, hscr[1]*pconf.stretch, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0], hscr[1]*pconf.stretch-10, hscr[2]));
glcoords.push_back(glhr::makevertex(hscr[0]+10, hscr[1]*pconf.stretch, hscr[2]));
} */
}
@ -1432,7 +1432,7 @@ void dqi_poly::draw() {
for(int j=0; j<MAX_PHASE; j++) {
twopoint_sphere_flips = j;
hyperpoint h2; applymodel(h1, h2);
glvertex h = glhr::pointtogl(h2 * current_display->radius); h[1] *= vid.stretch;
glvertex h = glhr::pointtogl(h2 * current_display->radius); h[1] *= pconf.stretch;
if(i == 0)
phases[j].push_back(h);
else {
@ -1460,7 +1460,7 @@ void dqi_poly::draw() {
for(int i=0; i<cnt; i++) {
hyperpoint h1 = V * glhr::gltopoint((*tab)[offset+i]);
hyperpoint mh1; applymodel(h1, mh1); mh1[1] *= vid.stretch;
hyperpoint mh1; applymodel(h1, mh1); mh1[1] *= pconf.stretch;
phases[cpha].push_back(glhr::pointtogl(mh1 * current_display->radius));
// check if the i-th edge intersects the boundary of the ellipse
@ -1476,7 +1476,7 @@ void dqi_poly::draw() {
if(c1 < 0) c1 = -c1, c2 = -c2;
hyperpoint h = ah1 * c1 + ah2 * c2;
h /= hypot_d(3, h);
if(h[2] < 0 && abs(h[0]) < sin(vid.twopoint_param)) cpha = 1-cpha, pha = 2;
if(h[2] < 0 && abs(h[0]) < sin(pconf.twopoint_param)) cpha = 1-cpha, pha = 2;
}
if(cpha == 1) pha = 0;
}
@ -1532,7 +1532,7 @@ void dqi_poly::draw() {
last_infront = false;
addpoly(V, *tab, offset, cnt);
if(!(sphere && vid.alpha < .9)) if(pmodel != mdJoukowsky) if(!(flags & POLY_ALWAYS_IN)) for(int i=1; i<isize(glcoords); i++) {
if(!(sphere && pconf.alpha < .9)) if(pmodel != mdJoukowsky) if(!(flags & POLY_ALWAYS_IN)) 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;
@ -1558,7 +1558,7 @@ void dqi_poly::draw() {
if(poly_flags & POLY_NIF_ERROR) return;
if(spherespecial == 1 && sphere && (poly_flags & POLY_INFRONT) && (poly_flags & POLY_NOTINFRONT) && vid.alpha <= 1) {
if(spherespecial == 1 && sphere && (poly_flags & POLY_INFRONT) && (poly_flags & POLY_NOTINFRONT) && pconf.alpha <= 1) {
bool around_center = false;
for(int i=0; i<isize(glcoords)-1; i++) {
double x1 = glcoords[i][0];
@ -1576,9 +1576,9 @@ void dqi_poly::draw() {
bool can_have_inverse = false;
if(sphere && pmodel == mdDisk && (spherespecial > 0 || equi)) can_have_inverse = true;
if(pmodel == mdJoukowsky) can_have_inverse = true;
if(pmodel == mdJoukowskyInverted && vid.skiprope) can_have_inverse = true;
if(pmodel == mdDisk && hyperbolic && vid.alpha <= -1) can_have_inverse = true;
if(pmodel == mdSpiral && vid.skiprope) can_have_inverse = true;
if(pmodel == mdJoukowskyInverted && pconf.skiprope) can_have_inverse = true;
if(pmodel == mdDisk && hyperbolic && pconf.alpha <= -1) can_have_inverse = true;
if(pmodel == mdSpiral && pconf.skiprope) can_have_inverse = true;
if(pmodel == mdCentralInversion) can_have_inverse = true;
if(can_have_inverse && !(poly_flags & POLY_ISSIDE)) {
@ -1593,7 +1593,7 @@ void dqi_poly::draw() {
}
if(poly_flags & POLY_INVERSE) {
if(curradius < vid.alpha - 1e-6) return;
if(curradius < pconf.alpha - 1e-6) return;
if(!sphere) return;
}
@ -1622,7 +1622,7 @@ void dqi_poly::draw() {
ld h = atan2(glcoords[0][0], glcoords[0][1]);
for(int i=0; i<=360; i++) {
ld a = i * degree + h;
glcoords.push_back(glhr::makevertex(current_display->radius * sin(a), current_display->radius * vid.stretch * cos(a), 0));
glcoords.push_back(glhr::makevertex(current_display->radius * sin(a), current_display->radius * pconf.stretch * cos(a), 0));
}
poly_flags ^= POLY_INVERSE;
}
@ -1855,7 +1855,7 @@ int qp[PMAX], qp0[PMAX];
color_t darken_color(color_t& color, bool outline) {
int alpha = color & 255;
if(sphere && pmodel == mdDisk && vid.alpha <= 1)
if(sphere && pmodel == mdDisk && pconf.alpha <= 1)
return 0;
else {
if(outline && alpha < 255)
@ -2360,7 +2360,7 @@ EX void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) {
hyperpoint hscr;
applymodel(h, hscr);
xc = current_display->xcenter + current_display->radius * hscr[0];
yc = current_display->ycenter + current_display->radius * vid.stretch * hscr[1];
yc = current_display->ycenter + current_display->radius * pconf.stretch * hscr[1];
sc = 0;
// EYETODO sc = vid.eye * current_display->radius * hscr[2];
}

View File

@ -1066,10 +1066,10 @@ void draw_shape_for_texture(floorshape* sh) {
hyperpoint inmodel;
applymodel(center, inmodel);
glvertex tmap;
tmap[0] = (1 + inmodel[0] * vid.scale) / 2;
tmap[1] = (1 - inmodel[1] * vid.scale) / 2;
tmap[0] = (1 + inmodel[0] * pconf.scale) / 2;
tmap[1] = (1 - inmodel[1] * pconf.scale) / 2;
applymodel(center + v1, inmodel);
tmap[2] = (1 + inmodel[0] * vid.scale) / 2 - tmap[0];
tmap[2] = (1 + inmodel[0] * pconf.scale) / 2 - tmap[0];
floor_texture_map[sh->id] = tmap;
}
@ -1078,8 +1078,8 @@ void draw_shape_for_texture(floorshape* sh) {
hyperpoint inmodel;
applymodel(h, inmodel);
glvec2 v;
v[0] = (1 + inmodel[0] * vid.scale) / 2;
v[1] = (1 - inmodel[1] * vid.scale) / 2;
v[0] = (1 + inmodel[0] * pconf.scale) / 2;
v[1] = (1 - inmodel[1] * pconf.scale) / 2;
return v;
};
@ -1121,9 +1121,9 @@ void geometry_information::make_floor_textures_here() {
dynamicval<videopar> vi(vid, vid);
vid.xres = FLOORTEXTURESIZE;
vid.yres = FLOORTEXTURESIZE;
vid.scale = 0.125;
vid.camera_angle = 0;
vid.alpha = 1;
pconf.scale = 0.125;
pconf.camera_angle = 0;
pconf.alpha = 1;
dynamicval<ld> lw(vid.linewidth, 2);
floor_textures = new renderbuffer(vid.xres, vid.yres, vid.usingGL);
@ -1138,7 +1138,7 @@ void geometry_information::make_floor_textures_here() {
cd->xsize = cd->ysize = FLOORTEXTURESIZE;
cd->xcenter = cd->ycenter = cd->scrsize = FLOORTEXTURESIZE/2;
cd->radius = cd->scrsize * vid.scale;
cd->radius = cd->scrsize * pconf.scale;
floor_textures->enable();
floor_textures->clear(0); // 0xE8E8E8 = 1

View File

@ -381,21 +381,21 @@ void ge_select_tiling() {
EX string current_proj_name() {
bool h = hyperbolic || sn::in();
if(pmodel != mdDisk)
return models::get_model_name(pmodel);
else if(h && vid.alpha == 1)
if(vpconf.model != mdDisk)
return models::get_model_name(vpconf.model);
else if(h && vpconf.alpha == 1)
return XLAT("Poincaré model");
else if(h && vid.alpha == 0)
else if(h && vpconf.alpha == 0)
return XLAT("Klein-Beltrami model");
else if(h && vid.alpha == -1)
else if(h && vpconf.alpha == -1)
return XLAT("inverted Poincaré model");
else if(sphere && vid.alpha == 1)
else if(sphere && vpconf.alpha == 1)
return XLAT("stereographic projection");
else if(sphere && vid.alpha == 0)
else if(sphere && vpconf.alpha == 0)
return XLAT("gnomonic projection");
else if(sphere && vid.alpha >= 999)
else if(sphere && vpconf.alpha >= 999)
return XLAT("orthographic projection");
else if(h && vid.alpha >= 999)
else if(h && vpconf.alpha >= 999)
return XLAT("Gans model");
else
return XLAT("general perspective");

View File

@ -710,24 +710,24 @@ EX namespace geom3 {
void geometry_information::prepare_compute3() {
using namespace geom3;
DEBBI(DF_INIT | DF_POLY | DF_GEOM, ("geom3::compute"));
// tanh(depth) / tanh(camera) == vid.alpha
// tanh(depth) / tanh(camera) == pconf.alpha
invalid = "";
if(GDIM == 3) ;
else if(vid.tc_alpha < vid.tc_depth && vid.tc_alpha < vid.tc_camera)
vid.alpha = tan_auto(vid.depth) / tan_auto(vid.camera);
pconf.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);
ld v = pconf.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);
}
else {
ld v = tan_auto(vid.depth) / vid.alpha;
ld v = tan_auto(vid.depth) / pconf.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);
}
if(fabs(vid.alpha) < 1e-6) invalid = "does not work with perfect Klein";
if(fabs(pconf.alpha) < 1e-6) invalid = "does not work with perfect Klein";
if(invalid != "") {
INFDEEP = .7;
@ -851,20 +851,20 @@ EX void switch_always3() {
EX void switch_tpp() {
if(dual::split(switch_fpp)) return;
if(pmodel == mdDisk && vid.camera_angle) {
if(pmodel == mdDisk && pconf.camera_angle) {
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
pconf.camera_angle = 0;
pconf.xposition = 0;
pconf.yposition = 0;
pconf.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;
pconf.camera_angle = -45;
pconf.scale = 18/16. * vid.xres / vid.yres / multi::players;
pconf.xposition = 0;
pconf.yposition = -0.9;
vid.fixed_facing = true;
vid.fixed_facing_dir = 90;
}

View File

@ -2858,10 +2858,10 @@ int haveaura_cached;
EX int haveaura() {
if(!(vid.aurastr>0 && !svg::in && (auraNOGL || vid.usingGL))) return 0;
if(sphere && mdAzimuthalEqui()) return 0;
if(among(pmodel, mdJoukowsky, mdJoukowskyInverted) && hyperbolic && models::model_transition < 1)
if(among(pmodel, mdJoukowsky, mdJoukowskyInverted) && hyperbolic && pconf.model_transition < 1)
return 2;
if(pmodel == mdFisheye) return 1;
return pmodel == mdDisk && (!sphere || vid.alpha > 10) && !euclid;
return pmodel == mdDisk && (!sphere || pconf.alpha > 10) && !euclid;
}
vector<pair<int, int> > auraspecials;
@ -2930,10 +2930,10 @@ void drawaura() {
if(!haveaura()) return;
if(vid.stereo_mode) return;
double rad = current_display->radius;
if(sphere && !mdAzimuthalEqui()) rad /= sqrt(vid.alpha*vid.alpha - 1);
if(sphere && !mdAzimuthalEqui()) rad /= sqrt(pconf.alpha*pconf.alpha - 1);
if(hyperbolic && pmodel == mdFisheye) {
ld h = 1;
h /= vid.fisheye_param;
h /= pconf.fisheye_param;
ld nrad = h / sqrt(2 + h*h);
rad *= nrad;
}
@ -2959,9 +2959,9 @@ void drawaura() {
for(int x=0; x<vid.xres; x++) {
ld hx = (x * 1. - current_display->xcenter) / rad;
ld hy = (y * 1. - current_display->ycenter) / rad / vid.stretch;
ld hy = (y * 1. - current_display->ycenter) / rad / pconf.stretch;
if(vid.camera_angle) camrotate(hx, hy);
if(pconf.camera_angle) camrotate(hx, hy);
ld fac = sqrt(hx*hx+hy*hy);
if(fac < 1) continue;
@ -3007,8 +3007,8 @@ void drawaura() {
facs[10] = 10;
cmul[1] = cmul[0];
bool inversion = vid.alpha <= -1 || pmodel == mdJoukowsky;
bool joukowsky = among(pmodel, mdJoukowskyInverted, mdJoukowsky) && hyperbolic && models::model_transition < 1;
bool inversion = pconf.alpha <= -1 || pmodel == mdJoukowsky;
bool joukowsky = among(pmodel, mdJoukowskyInverted, mdJoukowsky) && hyperbolic && pconf.model_transition < 1;
for(int r=0; r<=AURA; r++) for(int z=0; z<11; z++) {
float rr = (M_PI * 2 * r) / AURA;
@ -3024,7 +3024,7 @@ void drawaura() {
else
models::apply_orientation(c1, s1);
ld& mt = models::model_transition;
ld& mt = pconf.model_transition;
ld mt2 = 1 - mt;
ld m = sqrt(c1*c1 + s1*s1 / mt2 / mt2);
@ -3034,7 +3034,7 @@ void drawaura() {
}
cx[r][z][0] = rad0 * c;
cx[r][z][1] = rad0 * s * vid.stretch;
cx[r][z][1] = rad0 * s * pconf.stretch;
for(int u=0; u<3; u++)
cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z];
@ -4560,7 +4560,7 @@ EX void drawthemap() {
#endif
if(non_spatial_model())
spatial_graphics = false;
if(pmodel == mdDisk && abs(vid.alpha) < 1e-6) spatial_graphics = false;
if(pmodel == mdDisk && abs(pconf.alpha) < 1e-6) spatial_graphics = false;
if(!spatial_graphics) wmspatial = mmspatial = false;
if(GDIM == 3) wmspatial = mmspatial = true;
@ -4763,7 +4763,7 @@ EX void calcparam() {
cd->xcenter = cd->xtop + cd->xsize / 2;
cd->ycenter = cd->ytop + cd->ysize / 2;
if(vid.scale > -1e-2 && vid.scale < 1e-2) vid.scale = 1;
if(pconf.scale > -1e-2 && pconf.scale < 1e-2) pconf.scale = 1;
ld realradius = min(cd->xsize / 2, cd->ysize / 2);
@ -4785,11 +4785,11 @@ EX void calcparam() {
if(current_display->sidescreen) cd->xcenter = vid.yres/2;
}
cd->radius = vid.scale * cd->scrsize;
cd->radius = pconf.scale * cd->scrsize;
if(GDIM == 3 && in_perspective()) cd->radius = cd->scrsize;
realradius = min(realradius, cd->radius);
ld aradius = sphere ? cd->radius / (vid.alpha - 1) : cd->radius;
ld aradius = sphere ? cd->radius / (pconf.alpha - 1) : cd->radius;
if(dronemode) { cd->ycenter -= cd->radius; cd->ycenter += vid.fsize/2; cd->ycenter += vid.fsize/2; cd->radius *= 2; }
@ -4801,8 +4801,8 @@ EX void calcparam() {
cd->xcenter = cd->xtop + cd->xsize - vid.fsize - aradius;
}
cd->xcenter += cd->scrsize * vid.xposition;
cd->ycenter += cd->scrsize * vid.yposition;
cd->xcenter += cd->scrsize * pconf.xposition;
cd->ycenter += cd->scrsize * pconf.yposition;
cd->tanfov = tan(vid.fov * degree / 2);

View File

@ -362,7 +362,7 @@ EX namespace history {
}
ld measureLength() {
ld r = bandhalf * vid.scale;
ld r = bandhalf * pconf.scale;
ld tpixels = 0;
int siz = isize(v);
@ -526,7 +526,7 @@ EX namespace history {
dialog::addBoolItem(XLAT("include history"), (includeHistory), 'i');
// bool notconformal0 = (pmodel >= 5 && pmodel <= 6) && !euclid;
// bool notconformal = notconformal0 || abs(vid.alpha-1) > 1e-3;
// bool notconformal = notconformal0 || abs(pconf.alpha-1) > 1e-3;
dialog::addSelItem(XLAT("projection"), current_proj_name(), 'm');

14
hud.cpp
View File

@ -404,11 +404,11 @@ EX void drawStats() {
dynamicval<eModel> pm(pmodel, flat_model());
glClear(GL_DEPTH_BUFFER_BIT);
// dynamicval<videopar> v(vid, vid);
// vid.alpha = vid.scale = 1;
dynamicval<ld> va(vid.alpha, 1);
dynamicval<ld> vs(vid.scale, 1);
dynamicval<ld> vc(vid.camera_angle, 0);
if(prod) vid.alpha = 30, vid.scale = 30;
// pconf.alpha = vid.scale = 1;
dynamicval<ld> va(pconf.alpha, 1);
dynamicval<ld> vs(pconf.scale, 1);
dynamicval<ld> vc(pconf.camera_angle, 0);
if(prod) pconf.alpha = 30, pconf.scale = 30;
auto& cd = current_display;
auto xc = cd->xcenter;
@ -469,7 +469,7 @@ EX void drawStats() {
int spots = 0;
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
for(int v=vid.fsize; v<vid.yres/2-s; v += s)
if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / vid.stretch) > rad) {
if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / pconf.stretch) > rad) {
spots++;
}
if(spots >= bycorner[cor] && spots >= 3) {
@ -482,7 +482,7 @@ EX void drawStats() {
}
for(int u=vid.fsize; u<vid.xres/2-s; u += s)
for(int v=vid.fsize; v<vid.yres/2-s; v += s)
if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / vid.stretch) > rad) {
if(hypot(vid.xres/2-u-s, (vid.yres/2-v-s) / pconf.stretch) > rad) {
if(next >= isize(glyphstoshow)) break;
int cx = u;

51
hyper.h
View File

@ -228,9 +228,46 @@ enum eStereo { sOFF, sAnaglyph, sLR, sODS };
enum eModel : int;
/** configuration of the projection */
struct projection_configuration {
eModel model; /**< which projection, see classes.cpp */
ld xposition, yposition; /**< move the center to another position */
ld scale, alpha, camera_angle, fisheye_param, twopoint_param, stretch, ballangle, ballproj, euclid_to_sphere;
ld clip_min, clip_max;
ld model_orientation, halfplane_scale, model_orientation_yz;
ld collignon_parameter;
bool collignon_reflected;
string formula;
eModel basic_model;
ld top_z;
ld model_transition;
ld spiral_angle;
ld spiral_x;
ld spiral_y;
bool use_atan;
ld right_spiral_multiplier;
ld any_spiral_multiplier;
ld sphere_spiral_multiplier;
ld spiral_cone;
ld skiprope;
ld product_z_scale;
projection_configuration() {
formula = "z^2"; top_z = 5; model_transition = 1; spiral_angle = 70; spiral_x = 10; spiral_y = 7;
right_spiral_multiplier = 1;
any_spiral_multiplier = 1;
sphere_spiral_multiplier = 2;
spiral_cone = 360;
use_atan = false;
product_z_scale = 1;
}
};
struct videopar {
ld scale, alpha, sspeed, mspeed, yshift, camera_angle;
ld ballangle, ballproj, euclid_to_sphere, twopoint_param, fisheye_param, stretch, binary_width, fixed_facing_dir;
projection_configuration projection_config, rug_config;
ld yshift;
ld sspeed, mspeed;
ld binary_width, fixed_facing_dir;
int mobilecompasssize;
int radarsize; // radar for 3D geometries
ld radarrange;
@ -251,8 +288,6 @@ struct videopar {
int xscr, yscr;
ld xposition, yposition;
bool grid;
bool particles;
@ -304,8 +339,6 @@ struct videopar {
int cells_drawn_limit;
int cells_generated_limit; // limit on cells generated per frame
ld skiprope;
eStereo stereo_mode;
ld ipd;
ld lr_eyewidth, anaglyph_eyewidth;
@ -319,7 +352,6 @@ struct videopar {
ld depth; // world level below the plane
ld camera; // camera level above the plane
ld wall_height, creature_scale, height_width;
eModel vpmodel;
ld lake_top, lake_bottom;
ld rock_wall_ratio;
ld human_wall_ratio;
@ -331,7 +363,6 @@ struct videopar {
ld eye;
bool auto_eye;
ld collignon_parameter; bool collignon_reflected;
ld plevel_factor;
bool bubbles_special, bubbles_threshold, bubbles_all;
int joysmooth;
@ -627,7 +658,9 @@ enum orbAction { roMouse, roKeyboard, roCheck, roMouseForce, roMultiCheck, roMul
#define MODELCOUNT ((int) mdGUARD)
#define pmodel (vid.vpmodel)
#define pconf vid.projection_config
#define vpconf (rug::rugged ? vid.rug_config : vid.projection_config)
#define pmodel (pconf.model)
color_t darkena(color_t c, int lev, int a);

View File

@ -12,7 +12,7 @@ ld ghx, ghy, ghgx, ghgy;
hyperpoint ghpm = C0;
#if HDR
inline bool sphereflipped() { return sphere && vid.alpha > 1.1 && GDIM == 3; }
inline bool sphereflipped() { return sphere && pconf.alpha > 1.1 && GDIM == 3; }
#endif
void ghcheck(hyperpoint &ret, const hyperpoint &H) {
@ -22,7 +22,7 @@ void ghcheck(hyperpoint &ret, const hyperpoint &H) {
}
EX void camrotate(ld& hx, ld& hy) {
ld cam = vid.camera_angle * degree;
ld cam = pconf.camera_angle * degree;
GLfloat cc = cos(cam);
GLfloat ss = sin(cam);
ld ux = hx, uy = hy * cc + ss, uz = cc - ss * hy;
@ -37,7 +37,7 @@ EX bool non_spatial_model() {
return pmodel && vid.consider_shader_projection && (get_shader_flags() & SF_DIRECT);
}
EX hyperpoint perspective_to_space(hyperpoint h, ld alpha IS(vid.alpha), eGeometryClass gc IS(ginf[geometry].cclass)) {
EX hyperpoint perspective_to_space(hyperpoint h, ld alpha IS(pconf.alpha), eGeometryClass gc IS(ginf[geometry].cclass)) {
ld hx = h[0], hy = h[1];
if(gc == gcEuclid)
@ -59,7 +59,7 @@ EX hyperpoint perspective_to_space(hyperpoint h, ld alpha IS(vid.alpha), eGeomet
B /= A; C /= A;
ld rootsign = 1;
// if(gc == gcSphere && vid.alpha > 1) rootsign = -1;
// if(gc == gcSphere && pconf.alpha > 1) rootsign = -1;
ld hz = B / 2 + rootsign * sqrt(C + B*B/4);
@ -72,7 +72,7 @@ EX hyperpoint perspective_to_space(hyperpoint h, ld alpha IS(vid.alpha), eGeomet
return H;
}
EX hyperpoint space_to_perspective(hyperpoint z, ld alpha IS(vid.alpha)) {
EX hyperpoint space_to_perspective(hyperpoint z, ld alpha IS(pconf.alpha)) {
ld s = 1 / (alpha + z[LDIM]);
z[0] *= s;
z[1] *= s;
@ -88,21 +88,21 @@ EX hyperpoint space_to_perspective(hyperpoint z, ld alpha IS(vid.alpha)) {
EX hyperpoint gethyper(ld x, ld y) {
ld hx = (x - current_display->xcenter) / current_display->radius;
ld hy = (y - current_display->ycenter) / current_display->radius / vid.stretch;
ld hy = (y - current_display->ycenter) / current_display->radius / pconf.stretch;
if(pmodel) {
ghx = hx, ghy = hy;
return ghpm;
}
if(vid.camera_angle) camrotate(hx, hy);
if(pconf.camera_angle) camrotate(hx, hy);
return perspective_to_space(hpxyz(hx, hy, 0));
}
void ballmodel(hyperpoint& ret, double alpha, double d, double zl) {
hyperpoint H = ypush(vid.camera) * xpush(d) * ypush(zl) * C0;
ld tzh = vid.ballproj + H[LDIM];
ld tzh = pconf.ballproj + H[LDIM];
ld ax = H[0] / tzh;
ld ay = H[1] / tzh;
@ -165,7 +165,7 @@ ld find_zlev(hyperpoint& H) {
}
ld get_tz(hyperpoint H) {
ld tz = vid.alpha+H[LDIM];
ld tz = pconf.alpha+H[LDIM];
if(tz < BEHIND_LIMIT && tz > -BEHIND_LIMIT) tz = BEHIND_LIMIT;
return tz;
}
@ -237,7 +237,7 @@ void band_conformal(ld& x, ld& y) {
}
void make_twopoint(ld& x, ld& y) {
auto p = vid.twopoint_param;
auto p = pconf.twopoint_param;
ld dleft = hypot_auto(x-p, y);
ld dright = hypot_auto(x+p, y);
if(sphere) {
@ -264,7 +264,7 @@ hyperpoint mobius(hyperpoint h, ld angle, ld scale = 1) {
}
hyperpoint compute_hybrid(hyperpoint H, int rootid) {
auto& t = vid.twopoint_param;
auto& t = pconf.twopoint_param;
hyperpoint Hl = xpush(+t) * H;
hyperpoint Hr = xpush(-t) * H;
ld g = (Hl[0] + 1e-7) / (Hl[1] + 1e-8);
@ -315,11 +315,11 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
hyperpoint H_orig = H;
if(models::product_model()) {
if(models::product_model(pmodel)) {
ld zlev = zlevel(H);
H /= exp(zlev);
hybrid::in_underlying_geometry([&] { applymodel(H, ret); });
ret[2] = zlev * models::product_z_scale;
ret[2] = zlev * pconf.product_z_scale;
ret = NLP * ret;
return;
}
@ -364,19 +364,19 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ld w;
if(sn::in()) {
// w = 1 / sqrt(1 - sqhypot_d(3, ret));
// w = w / (vid.alpha + w);
w = 1 / (sqrt(1 - sqhypot_d(3, ret)) * vid.alpha + 1);
// w = w / (pconf.alpha + w);
w = 1 / (sqrt(1 - sqhypot_d(3, ret)) * pconf.alpha + 1);
}
else {
w = hypot_d(3, ret);
w = sinh(w) / ((vid.alpha + cosh(w)) * w);
w = sinh(w) / ((pconf.alpha + cosh(w)) * w);
}
for(int i=0; i<3; i++) ret[i] *= w;
ret[3] = 1;
break;
}
ld tz = get_tz(H);
if(!vid.camera_angle) {
if(!pconf.camera_angle) {
ret[0] = H[0] / tz;
ret[1] = H[1] / tz;
if(GDIM == 3) ret[2] = H[2] / tz;
@ -386,7 +386,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
else {
ld tx = H[0];
ld ty = H[1];
ld cam = vid.camera_angle * degree;
ld cam = pconf.camera_angle * degree;
GLfloat cc = cos(cam);
GLfloat ss = sin(cam);
ld ux = tx, uy = ty * cc - ss * tz, uz = tz * cc + ss * ty;
@ -422,7 +422,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
if(GDIM == 3) {
// a bit simpler when we do not care about 3D
H *= models::halfplane_scale;
H *= pconf.halfplane_scale;
ret[0] = -H[0];
ret[1] = 1 + H[1];
ret[2] = H[2];
@ -434,7 +434,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
models::apply_orientation(H[0], H[1]);
H *= models::halfplane_scale;
H *= pconf.halfplane_scale;
ret[0] = -models::osin - H[0];
if(zlev != 1) {
@ -485,14 +485,14 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
case gcEuclid: default: {
// stereographic projection to a sphere
auto hd = hdist0(H) / vid.euclid_to_sphere;
auto hd = hdist0(H) / pconf.euclid_to_sphere;
if(hd == 0) ret = hpxyz(0, 0, -1);
else {
ld x = 2 * hd / (1 + hd * hd);
ld y = x / hd;
ret = H * x / hd / vid.euclid_to_sphere;
ret = H * x / hd / pconf.euclid_to_sphere;
ret[2] = (1 - y);
ret = ret * (1 + (H[2]-1) * y / vid.euclid_to_sphere);
ret = ret * (1 + (H[2]-1) * y / pconf.euclid_to_sphere);
}
break;
}
@ -523,7 +523,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
break;
}
if(pmodel == mdHyperboloid) {
ld& topz = models::top_z;
ld& topz = pconf.top_z;
if(H[2] > topz) {
ld scale = sqrt(topz*topz-1) / hypot_d(2, H);
H *= scale;
@ -531,8 +531,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
}
}
else {
H = space_to_perspective(H, vid.alpha);
H[2] = 1 - vid.alpha;
H = space_to_perspective(H, pconf.alpha);
H[2] = 1 - pconf.alpha;
}
ret[0] = H[0] / 3;
@ -553,7 +553,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
zlev = find_zlev(H);
H = space_to_perspective(H);
}
H /= vid.fisheye_param;
H /= pconf.fisheye_param;
H[LDIM] = zlev;
ret = H / sqrt(1 + sqhypot_d(GDIM+1, H));
if(GDIM == 3) ret[LDIM] = zlev;
@ -564,8 +564,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
models::apply_orientation_yz(H[1], H[2]);
models::apply_orientation(H[0], H[1]);
auto yz = move_z_to_y(H);
hyperpoint Hl = xpush(-vid.twopoint_param) * H;
hyperpoint Hr = xpush(+vid.twopoint_param) * H;
hyperpoint Hl = xpush(-pconf.twopoint_param) * H;
hyperpoint Hr = xpush(+pconf.twopoint_param) * H;
ld lyx = (Hl[1] + 1e-7) / (Hl[0] + 1e-8);
ld ryx = (Hr[1] + 1e-7) / (Hr[0] + 1e-8);
// (r.x + t) * lyx = (r.x - t) * ryx = r.y
@ -574,8 +574,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
// r.x = -t * (ryx+lyx) / (lyx-ryx)
// r.x = - 2 * t * lyx * ryx / lyx / ryx
ret[0] = -vid.twopoint_param * (ryx + lyx) / (lyx - ryx);
ret[1] = (ret[0] + vid.twopoint_param) * lyx;
ret[0] = -pconf.twopoint_param * (ryx + lyx) / (lyx - ryx);
ret[1] = (ret[0] + pconf.twopoint_param) * lyx;
ret[2] = 0;
move_y_to_z(ret, yz);
@ -603,11 +603,11 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
models::apply_orientation(H[0], H[1]);
// with equal speed skiprope: models::apply_orientation(H[1], H[0]);
if(vid.skiprope) {
if(pconf.skiprope) {
static ld last_skiprope = 0;
static transmatrix lastmatrix;
if(vid.skiprope != last_skiprope) {
ret = mobius(C0, -vid.skiprope, 2);
if(pconf.skiprope != last_skiprope) {
ret = mobius(C0, -pconf.skiprope, 2);
const cld c1(1, 0);
const cld c2(2, 0);
const cld c4(4, 0);
@ -617,7 +617,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
hyperpoint zr = hpxyz(real(z), imag(z), 0);
hyperpoint inhyp = perspective_to_space(zr, 1, gcHyperbolic);
last_skiprope = vid.skiprope;
last_skiprope = pconf.skiprope;
lastmatrix = rgpushxto0(inhyp);
}
H = lastmatrix * H;
@ -628,7 +628,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ld r = hypot_d(2, H);
ld c = H[0] / r;
ld s = H[1] / r;
ld& mt = models::model_transition;
ld& mt = pconf.model_transition;
ld a = 1 - .5 * mt, b = .5 * mt;
swap(a, b);
@ -636,8 +636,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ret[1] = (a * r - b/r) * s / 2;
ret[2] = 0;
if(vid.skiprope)
ret = mobius(ret, vid.skiprope, 2);
if(pconf.skiprope)
ret = mobius(ret, pconf.skiprope, 2);
if(pmodel == mdJoukowskyInverted) {
ld r2 = sqhypot_d(2, ret);
@ -681,8 +681,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
}
case mdBand:
if(models::model_transition != 1) {
ld& mt = models::model_transition;
if(pconf.model_transition != 1) {
ld& mt = pconf.model_transition;
H = space_to_perspective(H);
@ -745,10 +745,10 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
find_zlev(H);
makeband(H, ret, [] (ld& x, ld& y) {
ld sgn = 1;
if(vid.collignon_reflected && y > 0) y = -y, sgn = -1;
y = signed_sqrt(sin_auto(y) + vid.collignon_parameter);
if(pconf.collignon_reflected && y > 0) y = -y, sgn = -1;
y = signed_sqrt(sin_auto(y) + pconf.collignon_parameter);
x *= y / 1.2;
y -= signed_sqrt(vid.collignon_parameter);
y -= signed_sqrt(pconf.collignon_parameter);
y *= sgn;
y *= M_PI;
});
@ -813,7 +813,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ret[1] = cosh(x) * factor;
ret[2] = 0;
if(models::use_atan) {
if(pconf.use_atan) {
ret[0] = atan(ret[0]);
ret[1] = atan(ret[1]);
}
@ -822,7 +822,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
}
case mdFormula: {
dynamicval<eModel> m(pmodel, models::basic_model);
dynamicval<eModel> m(pmodel, pconf.basic_model);
applymodel(H, ret);
exp_parser ep;
ep.extra_params["z"] = cld(ret[0], ret[1]);
@ -832,7 +832,7 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ep.extra_params["ux"] = H[0];
ep.extra_params["uy"] = H[1];
ep.extra_params["uz"] = H[2];
ep.s = models::formula;
ep.s = pconf.formula;
cld res;
try {
res = ep.parse();
@ -852,15 +852,15 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
else ret = H;
z = cld(ret[0], ret[1]) * models::spiral_multiplier;
if(models::spiral_cone < 360) {
ld alpha = imag(z) * 360 / models::spiral_cone;
if(pconf.spiral_cone < 360) {
ld alpha = imag(z) * 360 / pconf.spiral_cone;
ld r = real(z);
r = exp(r);
ret[0] = -sin(alpha) * r;
ret[1] = cos(alpha) * r;
if(euclid) ret = models::euclidean_spin * ret;
ret[2] = (r-1) * sqrt( pow(360/models::spiral_cone, 2) - 1);
ret[2] = (r-1) * sqrt( pow(360/pconf.spiral_cone, 2) - 1);
models::apply_ball(ret[2], ret[1]);
}
@ -870,8 +870,8 @@ EX void applymodel(hyperpoint H, hyperpoint& ret) {
ret[1] = imag(z);
if(euclid) ret = models::euclidean_spin * ret;
if(vid.skiprope)
ret = mobius(ret, vid.skiprope, 1);
if(pconf.skiprope)
ret = mobius(ret, pconf.skiprope, 1);
}
}
@ -929,12 +929,12 @@ EX bool behindsphere(const hyperpoint& h) {
if(mdBandAny()) return false;
if(vid.alpha > 1) {
if(h[LDIM] > -1/vid.alpha) return true;
if(pconf.alpha > 1) {
if(h[LDIM] > -1/pconf.alpha) return true;
}
if(vid.alpha <= 1) {
if(h[LDIM] < .2-vid.alpha) return true;
if(pconf.alpha <= 1) {
if(h[LDIM] < .2-pconf.alpha) return true;
}
return false;
@ -949,11 +949,11 @@ ld to01(ld a0, ld a1, ld x) {
EX ld spherity(const hyperpoint& h) {
if(!sphere) return 1;
if(vid.alpha > 1) {
return to01(1/vid.alpha, 1, abs(h[2]));
if(pconf.alpha > 1) {
return to01(1/pconf.alpha, 1, abs(h[2]));
}
if(vid.alpha <= 1) {
if(pconf.alpha <= 1) {
return to01(-1.5, 1, h[2]);
}
@ -1039,15 +1039,15 @@ EX bool in_smart_range(const transmatrix& T) {
applymodel(h, h1);
if(invalid_point(h1)) return false;
ld x = current_display->xcenter + current_display->radius * h1[0];
ld y = current_display->ycenter + current_display->radius * h1[1] * vid.stretch;
ld y = current_display->ycenter + current_display->radius * h1[1] * pconf.stretch;
if(x > current_display->xtop + current_display->xsize * 2) return false;
if(x < current_display->xtop - current_display->xsize * 1) return false;
if(y > current_display->ytop + current_display->ysize * 2) return false;
if(y < current_display->ytop - current_display->ysize * 1) return false;
if(GDIM == 3) {
if(-h1[2] < models::clip_min * 2 - models::clip_max) return false;
if(-h1[2] > models::clip_max * 2 - models::clip_min) return false;
if(-h1[2] < pconf.clip_min * 2 - pconf.clip_max) return false;
if(-h1[2] > pconf.clip_max * 2 - pconf.clip_min) return false;
}
ld epsilon = 0.01;
@ -1057,14 +1057,14 @@ EX bool in_smart_range(const transmatrix& T) {
hyperpoint h2;
applymodel(T * cpush0(i, epsilon), h2);
ld x1 = current_display->radius * abs(h2[0] - h1[0]) / epsilon;
ld y1 = current_display->radius * abs(h2[1] - h1[1]) * vid.stretch / epsilon;
ld y1 = current_display->radius * abs(h2[1] - h1[1]) * pconf.stretch / epsilon;
dx = max(dx, x1); dy = max(dy, y1);
if(GDIM == 3) dz = max(dz, abs(h2[2] - h1[2]));
dh[i] = hypot(x1, y1);
}
if(GDIM == 3) {
if(-h1[2] + 2 * dz < models::clip_min || -h1[2] - 2 * dz > models::clip_max) return false;
if(-h1[2] + 2 * dz < pconf.clip_min || -h1[2] - 2 * dz > pconf.clip_max) return false;
sort(dh, dh+GDIM);
ld scale = sqrt(dh[1] * dh[2]) * cgi.scalefactor * hcrossf7;
if(scale <= (WDIM == 2 ? vid.smart_range_detail : vid.smart_range_detail_3)) return false;
@ -1191,7 +1191,7 @@ void hrmap_standard::draw() {
if(sphere && pmodel == mdSpiral && !in_multi) {
in_multi = true;
if(models::ring_not_spiral) {
int qty = ceil(1. / models::sphere_spiral_multiplier);
int qty = ceil(1. / pconf.sphere_spiral_multiplier);
if(qty > 100) qty = 100;
for(int i=-qty; i < qty; i++) {
band_shift = 2 * M_PI * i;
@ -1505,8 +1505,8 @@ EX void fullcenter() {
transmatrix screenpos(ld x, ld y) {
transmatrix V = Id;
V[0][2] += (x - current_display->xcenter) / current_display->radius * (1+vid.alpha);
V[1][2] += (y - current_display->ycenter) / current_display->radius * (1+vid.alpha);
V[0][2] += (x - current_display->xcenter) / current_display->radius * (1+pconf.alpha);
V[1][2] += (y - current_display->ycenter) / current_display->radius * (1+pconf.alpha);
return V;
}
@ -1541,7 +1541,7 @@ EX transmatrix atscreenpos(ld x, ld y, ld size) {
void circle_around_center(ld radius, color_t linecol, color_t fillcol, PPR prio) {
#if CAP_QUEUE
if(among(pmodel, mdDisk, mdEquiarea, mdEquidistant, mdFisheye) && !(pmodel == mdDisk && hyperbolic && vid.alpha <= -1) && vid.camera_angle == 0) {
if(among(pmodel, mdDisk, mdEquiarea, mdEquidistant, mdFisheye) && !(pmodel == mdDisk && hyperbolic && pconf.alpha <= -1) && pconf.camera_angle == 0) {
hyperpoint ret;
applymodel(xpush0(radius), ret);
ld r = hypot_d(2, ret);
@ -1552,7 +1552,7 @@ void circle_around_center(ld radius, color_t linecol, color_t fillcol, PPR prio)
#if CAP_QUEUE
for(int i=0; i<=360; i++) curvepoint(xspinpush0(i * degree, 10));
auto& c = queuecurve(linecol, fillcol, prio);
if(pmodel == mdDisk && hyperbolic && vid.alpha <= -1)
if(pmodel == mdDisk && hyperbolic && pconf.alpha <= -1)
c.flags |= POLY_FORCE_INVERTED;
if(pmodel == mdJoukowsky)
c.flags |= POLY_FORCE_INVERTED;
@ -1571,7 +1571,7 @@ EX void draw_model_elements() {
switch(pmodel) {
case mdRotatedHyperboles: {
queuestr(current_display->xcenter, current_display->ycenter + current_display->radius * vid.alpha, 0, vid.fsize, "X", ringcolor, 1, 8);
queuestr(current_display->xcenter, current_display->ycenter + current_display->radius * pconf.alpha, 0, vid.fsize, "X", ringcolor, 1, 8);
return;
}
@ -1581,11 +1581,11 @@ EX void draw_model_elements() {
for(int mode=0; mode<4; mode++) {
for(int s=-200; s<=200; s ++) {
ld p = tanh(s / 40.);
ld a = vid.twopoint_param * (1+p);
ld b = vid.twopoint_param * (1-p);
ld a = pconf.twopoint_param * (1+p);
ld b = pconf.twopoint_param * (1-p);
ld h = ((mode & 2) ? -1 : 1) * sqrt(asin_auto(tan_auto(a) * tan_auto(b)));
hyperpoint H = xpush(p * vid.twopoint_param) * ypush0(h);
hyperpoint H = xpush(p * pconf.twopoint_param) * ypush0(h);
hyperpoint res = compute_hybrid(H, 2 | mode);
models::apply_orientation(res[0], res[1]);
@ -1600,9 +1600,9 @@ EX void draw_model_elements() {
}
case mdTwoPoint: case mdSimulatedPerspective: {
ld a = -models::model_orientation * degree;
queuestr(xspinpush0(a, +vid.twopoint_param), vid.xres / 100, "X", ringcolor >> 8);
queuestr(xspinpush0(a, -vid.twopoint_param), vid.xres / 100, "X", ringcolor >> 8);
ld a = -pconf.model_orientation * degree;
queuestr(xspinpush0(a, +pconf.twopoint_param), vid.xres / 100, "X", ringcolor >> 8);
queuestr(xspinpush0(a, -pconf.twopoint_param), vid.xres / 100, "X", ringcolor >> 8);
return;
}
@ -1616,10 +1616,10 @@ EX void draw_model_elements() {
if(hyperbolic) {
#if CAP_QUEUE
curvepoint(point3(0,0,1));
curvepoint(point3(0,0,-vid.alpha));
curvepoint(point3(0,0,-pconf.alpha));
queuecurve(ringcolor, 0, PPR::CIRCLE);
ld& tz = models::top_z;
ld& tz = pconf.top_z;
ld z = acosh(tz);
hyperpoint a = xpush0(z);
@ -1629,12 +1629,12 @@ EX void draw_model_elements() {
a[1] = sb * a[2] / -cb;
a[0] = sqrt(-1 + a[2] * a[2] - a[1] * a[1]);
curvepoint(point3(0,0,-vid.alpha));
curvepoint(point3(0,0,-pconf.alpha));
curvepoint(a);
curvepoint(point3(0,0,0));
a[0] = -a[0];
curvepoint(a);
curvepoint(point3(0,0,-vid.alpha));
curvepoint(point3(0,0,-pconf.alpha));
queuecurve(ringcolor, 0, PPR::CIRCLE);
curvepoint(point3(-1,0,0));
@ -1643,10 +1643,10 @@ EX void draw_model_elements() {
a[1] = sb * tz / -cb;
a[0] = sqrt(tz * tz - a[1] * a[1]);
a[2] = tz - vid.alpha;
a[2] = tz - pconf.alpha;
curvepoint(a);
curvepoint(point3(0,0,-vid.alpha));
curvepoint(point3(0,0,-pconf.alpha));
a[0] = -a[0];
curvepoint(a);
queuecurve(ringcolor, 0, PPR::CIRCLE);
@ -1727,7 +1727,7 @@ EX void draw_boundary(int w) {
for(int b=-1; b<=1; b+=2)
for(ld a=-90; a<=90+1e-6; a+=pow(.5, vid.linequality)) {
ld x = sin(a * vid.twopoint_param * b / 90);
ld x = sin(a * pconf.twopoint_param * b / 90);
ld y = 0;
ld z = -sqrt(1 - x*x);
models::apply_orientation(y, x);
@ -1747,9 +1747,9 @@ EX void draw_boundary(int w) {
case mdBand: case mdBandEquidistant: case mdBandEquiarea: case mdSinusoidal: case mdMollweide: case mdCentralCyl: case mdCollignon: {
if(GDIM == 3) return;
if(pmodel == mdBand && models::model_transition != 1) return;
if(pmodel == mdBand && pconf.model_transition != 1) return;
bool bndband = (among(pmodel, mdBand, mdCentralCyl) ? hyperbolic : sphere);
transmatrix T = spin(-models::model_orientation * degree);
transmatrix T = spin(-pconf.model_orientation * degree);
ld right = M_PI/2 - 1e-5;
if(bndband)
queuestraight(T * ypush0(hyperbolic ? 10 : right), 2, lc, fc, p);
@ -1773,7 +1773,7 @@ EX void draw_boundary(int w) {
case mdHalfplane:
if(hyperbolic && GDIM == 2) {
queuestraight(xspinpush0(-models::model_orientation * degree - M_PI/2, fakeinf), 1, lc, fc, p);
queuestraight(xspinpush0(-pconf.model_orientation * degree - M_PI/2, fakeinf), 1, lc, fc, p);
return;
}
break;
@ -1810,7 +1810,7 @@ EX void draw_boundary(int w) {
case mdHyperboloid: {
if(hyperbolic) {
ld& tz = models::top_z;
ld& tz = pconf.top_z;
ld mz = acosh(tz);
ld cb = models::cos_ball;
ld sb = models::sin_ball;
@ -1871,7 +1871,7 @@ EX void draw_boundary(int w) {
for(ld a=-10; a<=10; a+=0.01 / (1 << vid.linequality) / u) {
cld z = exp(cld(a, a * imag(sm) / real(sm) + M_PI));
hyperpoint ret = point2(real(z), imag(z));
ret = mobius(ret, vid.skiprope, 1);
ret = mobius(ret, pconf.skiprope, 1);
ret *= current_display->radius;
curvepoint(ret);
}
@ -1884,8 +1884,8 @@ EX void draw_boundary(int w) {
default: break;
}
if(sphere && pmodel == mdDisk && vid.alpha > 1) {
double rad = current_display->radius / sqrt(vid.alpha*vid.alpha - 1);
if(sphere && pmodel == mdDisk && pconf.alpha > 1) {
double rad = current_display->radius / sqrt(pconf.alpha*pconf.alpha - 1);
queuecircle(current_display->xcenter, current_display->ycenter, rad, lc, p, fc);
return;
}
@ -1898,7 +1898,7 @@ EX void draw_boundary(int w) {
EX ld band_shift = 0;
EX void fix_the_band(transmatrix& T) {
if(((mdinf[pmodel].flags & mf::uses_bandshift) && T[LDIM][LDIM] > 1e6) || (sphere && pmodel == mdSpiral)) {
T = spin(models::model_orientation * degree) * T;
T = spin(pconf.model_orientation * degree) * T;
hyperpoint H = tC0(T);
find_zlev(H);
@ -1911,7 +1911,7 @@ EX void fix_the_band(transmatrix& T) {
band_shift += x;
T = xpush(-x) * T;
fixmatrix(T);
T = spin(-models::model_orientation * degree) * T;
T = spin(-pconf.model_orientation * degree) * T;
}
}
@ -2056,7 +2056,7 @@ EX int cone_side(const hyperpoint H) {
cld z = cld(ret[0], ret[1]) * models::spiral_multiplier;
auto zth = [&] (cld z) {
ld alpha = imag(z) * 360 / models::spiral_cone;
ld alpha = imag(z) * 360 / pconf.spiral_cone;
ld r = real(z);
r = exp(r);
@ -2064,7 +2064,7 @@ EX int cone_side(const hyperpoint H) {
ret[0] = -sin(alpha) * r;
ret[1] = cos(alpha) * r;
ret[2] = (r-1) * sqrt( pow(360/models::spiral_cone, 2) - 1);
ret[2] = (r-1) * sqrt( pow(360/pconf.spiral_cone, 2) - 1);
models::apply_ball(ret[2], ret[1]);
return ret;

View File

@ -516,10 +516,10 @@ EX namespace inv {
dynamicval<eModel> pm(pmodel, flat_model());
glClear(GL_DEPTH_BUFFER_BIT);
// dynamicval<videopar> v(vid, vid);
// vid.alpha = vid.scale = 1;
dynamicval<ld> va(vid.alpha, 1);
dynamicval<ld> vs(vid.scale, 1);
dynamicval<ld> vc(vid.camera_angle, 0);
// pconf.alpha = vid.scale = 1;
dynamicval<ld> va(pconf.alpha, 1);
dynamicval<ld> vs(pconf.scale, 1);
dynamicval<ld> vc(pconf.camera_angle, 0);
calcparam();
for(int i=0; i<ittypes; i++) {

View File

@ -49,7 +49,7 @@ void loadOldConfig(FILE *f) {
float a, b, c, d;
err=fscanf(f, "%f%f%f%f\n", &a, &b, &c, &d);
if(err == 4) {
vid.scale = a; vid.alpha = c; vid.sspeed = d;
vid.scale = a; pconf.alpha = c; vid.sspeed = d;
}
err=fscanf(f, "%d%d%d%d%d%d%d", &vid.wallmode, &vid.monmode, &vid.axes, &musicvolume, &vid.framelimit, &gl, &vid.antialias);
vid.usingGL = gl;

View File

@ -43,16 +43,16 @@ EX namespace mapeditor {
// mx = xb + ssiz*xpos + mrx * scale
// mx = xb + ssiz*xpos' + mrx * scale'
ld mrx = (.0 + mousex - current_display->xcenter) / vid.scale;
ld mry = (.0 + mousey - current_display->ycenter) / vid.scale;
ld mrx = (.0 + mousex - current_display->xcenter) / vpconf.scale;
ld mry = (.0 + mousey - current_display->ycenter) / vpconf.scale;
if(vid.xres > vid.yres) {
vid.xposition += (vid.scale - vid.scale*z) * mrx / current_display->scrsize;
vid.yposition += (vid.scale - vid.scale*z) * mry / current_display->scrsize;
vpconf.xposition += (vpconf.scale - vpconf.scale*z) * mrx / current_display->scrsize;
vpconf.yposition += (vpconf.scale - vpconf.scale*z) * mry / current_display->scrsize;
}
vid.scale *= z;
// printf("scale = " LDF "\n", vid.scale);
vpconf.scale *= z;
// printf("scale = " LDF "\n", vpconf.scale);
#if CAP_TEXTURE
// display(texture::itt);
texture::config.itt = xyscale(texture::config.itt, 1/z);

View File

@ -323,7 +323,7 @@ EX void showMainMenu() {
// -- display modes --
EX void editScale() {
dialog::editNumber(vid.scale, .001, 1000, .1, 1, XLAT("scale factor"),
dialog::editNumber(vpconf.scale, .001, 1000, .1, 1, XLAT("scale factor"),
XLAT("Scale the displayed model."));
dialog::scaleSinh();
}
@ -335,10 +335,10 @@ EX void showGraphQuickKeys() {
dialog::init(XLAT("quick options"));
if(GDIM == 2) {
dialog::addBoolItem(XLAT("orthogonal projection"), vid.alpha >= 500, '1');
dialog::addBoolItem(XLAT(sphere ? "stereographic projection" : euclid ? "zoomed out" : "small Poincaré model"), vid.alpha == 1 && vid.scale < 1, '2');
dialog::addBoolItem(XLAT(sphere ? "zoomed stereographic projection" : euclid ? "zoomed in" : "big Poincaré model"), vid.alpha == 1 && vid.scale >= 1, '3');
dialog::addBoolItem(XLAT((sphere || euclid) ? "gnomonic projection" : "Klein-Beltrami model"), vid.alpha == 0, '4');
dialog::addBoolItem(XLAT("orthogonal projection"), vpconf.alpha >= 500, '1');
dialog::addBoolItem(XLAT(sphere ? "stereographic projection" : euclid ? "zoomed out" : "small Poincaré model"), vpconf.alpha == 1 && vpconf.scale < 1, '2');
dialog::addBoolItem(XLAT(sphere ? "zoomed stereographic projection" : euclid ? "zoomed in" : "big Poincaré model"), vpconf.alpha == 1 && vpconf.scale >= 1, '3');
dialog::addBoolItem(XLAT((sphere || euclid) ? "gnomonic projection" : "Klein-Beltrami model"), vpconf.alpha == 0, '4');
}
else {
dialog::addBoolItem(XLAT("first person perspective"), vid.yshift == 0 && vid.sspeed > -5, '1');
@ -875,8 +875,8 @@ EX void showStartMenu() {
specialland = laHalloween;
set_geometry(gSphere);
start_game();
vid.alpha = 999;
vid.scale = 998;
pconf.alpha = 999;
pconf.scale = 998;
}
}
#if CAP_RACING
@ -889,13 +889,13 @@ EX void showStartMenu() {
specialland = racing::race_lands[rand() % isize(racing::race_lands)];
start_game();
pmodel = mdBand;
models::model_orientation = racing::race_angle;
pconf.model_orientation = racing::race_angle;
racing::race_advance = 1;
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
pconf.camera_angle = 0;
pconf.xposition = 0;
pconf.yposition = 0;
pconf.scale = 1;
vid.use_smart_range = 1;
vid.smart_range_detail = 3;
}

View File

@ -115,20 +115,13 @@ inline bool mdPseudocylindrical() { return mdBandAny() && !(mdinf[pmodel].flags
EX namespace models {
EX string formula = "z^2";
EX eModel basic_model;
EX ld rotation = 0;
EX ld rotation_xz = 90;
EX ld rotation_xy2 = 90;
EX int do_rotate = 1;
EX ld model_orientation, halfplane_scale, model_orientation_yz;
EX ld clip_min, clip_max;
EX ld ocos, osin, ocos_yz, osin_yz;
EX ld cos_ball, sin_ball;
EX bool model_straight, model_straight_yz;
EX ld top_z = 5;
EX ld model_transition = 1;
#if HDR
// screen coordinates to logical coordinates: apply_orientation(x,y)
@ -146,53 +139,43 @@ EX namespace models {
return spin(rotation_xy2 * degree) * cspin(0, 2, -rotation_xz * degree) * spin(rotation * degree);
}
EX ld spiral_angle = 70;
EX ld spiral_x = 10;
EX ld spiral_y = 7;
int spiral_id = 7;
EX bool use_atan = false;
EX cld spiral_multiplier;
EX ld right_spiral_multiplier = 1;
EX ld any_spiral_multiplier = 1;
EX ld sphere_spiral_multiplier = 2;
EX ld spiral_cone = 360;
EX ld spiral_cone_rad;
EX bool ring_not_spiral;
/** the matrix to rotate the Euclidean view from the standard coordinates to the screen coordinates */
EX transmatrix euclidean_spin;
EX ld product_z_scale = 1;
EX void configure() {
ld ball = -vid.ballangle * degree;
ld ball = -pconf.ballangle * degree;
cos_ball = cos(ball), sin_ball = sin(ball);
ocos = cos(model_orientation * degree);
osin = sin(model_orientation * degree);
ocos_yz = cos(model_orientation_yz * degree);
osin_yz = sin(model_orientation_yz * degree);
ocos = cos(pconf.model_orientation * degree);
osin = sin(pconf.model_orientation * degree);
ocos_yz = cos(pconf.model_orientation_yz * degree);
osin_yz = sin(pconf.model_orientation_yz * degree);
model_straight = (ocos > 1 - 1e-9);
model_straight_yz = GDIM == 2 || (ocos_yz > 1-1e-9);
if(history::on) history::apply();
if(!euclid) {
ld b = spiral_angle * degree;
ld b = pconf.spiral_angle * degree;
ld cos_spiral = cos(b);
ld sin_spiral = sin(b);
spiral_cone_rad = spiral_cone * degree;
spiral_cone_rad = pconf.spiral_cone * degree;
ring_not_spiral = abs(cos_spiral) < 1e-3;
ld mul = 1;
if(sphere) mul = .5 * sphere_spiral_multiplier;
else if(ring_not_spiral) mul = right_spiral_multiplier;
else mul = any_spiral_multiplier * cos_spiral;
if(sphere) mul = .5 * pconf.sphere_spiral_multiplier;
else if(ring_not_spiral) mul = pconf.right_spiral_multiplier;
else mul = pconf.any_spiral_multiplier * cos_spiral;
spiral_multiplier = cld(cos_spiral, sin_spiral) * cld(spiral_cone_rad * mul / 2., 0);
}
if(euclid) {
euclidean_spin = pispin * inverse(cview() * master_relative(centerover, true));
euclidean_spin = gpushxto0(euclidean_spin * C0) * euclidean_spin;
hyperpoint h = inverse(euclidean_spin) * (C0 + (euc::eumove(gp::loc{1,0})*C0 - C0) * spiral_x + (euc::eumove(gp::loc{0,1})*C0 - C0) * spiral_y);
hyperpoint h = inverse(euclidean_spin) * (C0 + (euc::eumove(gp::loc{1,0})*C0 - C0) * vpconf.spiral_x + (euc::eumove(gp::loc{0,1})*C0 - C0) * vpconf.spiral_y);
spiral_multiplier = cld(0, 2 * M_PI) / cld(h[0], h[1]);
}
@ -222,27 +205,27 @@ EX namespace models {
return true;
}
EX bool model_has_orientation() {
EX bool has_orientation(eModel m) {
return
among(pmodel, mdHalfplane, mdPolynomial, mdPolygonal, mdTwoPoint, mdJoukowsky, mdJoukowskyInverted, mdSpiral, mdSimulatedPerspective, mdTwoHybrid, mdHorocyclic) || mdBandAny();
among(m, mdHalfplane, mdPolynomial, mdPolygonal, mdTwoPoint, mdJoukowsky, mdJoukowskyInverted, mdSpiral, mdSimulatedPerspective, mdTwoHybrid, mdHorocyclic) || mdBandAny();
}
EX bool model_is_perspective(eModel m IS(pmodel)) {
EX bool is_perspective(eModel m) {
return among(m, mdPerspective, mdGeodesic);
}
EX bool model_is_3d() {
EX bool is_3d(const projection_configuration& p) {
if(GDIM == 3) return true;
return pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere || (pmodel == mdSpiral && spiral_cone != 360);
return among(p.model, mdBall, mdHyperboloid, mdHemisphere) || (p.model == mdSpiral && p.spiral_cone != 360);
}
EX bool model_has_transition() {
return among(pmodel, mdJoukowsky, mdJoukowskyInverted, mdBand) && GDIM == 2;
EX bool has_transition(eModel m) {
return among(m, mdJoukowsky, mdJoukowskyInverted, mdBand) && GDIM == 2;
}
EX bool product_model() {
EX bool product_model(eModel m) {
if(!prod) return false;
if(among(pmodel, mdPerspective, mdHyperboloid, mdEquidistant)) return false;
if(among(m, mdPerspective, mdHyperboloid, mdEquidistant)) return false;
return true;
}
@ -295,16 +278,16 @@ EX namespace models {
dialog::editNumber(spiral_id, 0, isize(torus_zeros)-1, 1, 10, XLAT("match the period of the torus"), "");
dialog::reaction = [] () {
auto& co = torus_zeros[spiral_id];
spiral_x = co.first;
spiral_y = co.second;
vpconf.spiral_x = co.first;
vpconf.spiral_y = co.second;
};
dialog::bound_low(0);
dialog::bound_up(isize(torus_zeros)-1);
}
EX void edit_formula() {
if(pmodel != mdFormula) basic_model = pmodel;
dialog::edit_string(formula, "formula",
if(vpconf.model != mdFormula) vpconf.basic_model = vpconf.model;
dialog::edit_string(vpconf.formula, "formula",
XLAT(
"This lets you specify the projection as a formula f. "
"The formula has access to the value 'z', which is a complex number corresponding to the (x,y) coordinates in the currently selected model; "
@ -323,12 +306,12 @@ EX namespace models {
curvepoint(point2(a*current_display->radius, +M_PI/2*current_display->radius));
queuecurve(forecolor, 0, PPR::LINE);
}
queuereset(pmodel, PPR::LINE);
queuereset(vpconf.model, PPR::LINE);
quickqueue();
};
#endif
dialog::reaction_final = [] () {
pmodel = mdFormula;
vpconf.model = mdFormula;
};
}
@ -373,11 +356,11 @@ EX namespace models {
}
pmodel = m;
polygonal::solve();
vid.alpha = 1; vid.scale = 1;
vpconf.alpha = 1; vpconf.scale = 1;
if(pmodel == mdBand && sphere)
vid.scale = .3;
vpconf.scale = .3;
if(pmodel == mdDisk && sphere)
vid.scale = .4;
vpconf.scale = .4;
popScreen();
});
}
@ -387,24 +370,24 @@ EX namespace models {
}
void edit_stretch() {
dialog::editNumber(vid.stretch, 0, 10, .1, 1, XLAT("vertical stretch"),
dialog::editNumber(vpconf.stretch, 0, 10, .1, 1, XLAT("vertical stretch"),
"Vertical stretch factor."
);
dialog::extra_options = [] () {
dialog::addBreak(100);
if(sphere && pmodel == mdBandEquiarea) {
dialog::addBoolItem("Gall-Peters", vid.stretch == 2, 'O');
dialog::add_action([] { vid.stretch = 2; dialog::ne.s = "2"; });
dialog::addBoolItem("Gall-Peters", vpconf.stretch == 2, 'O');
dialog::add_action([] { vpconf.stretch = 2; dialog::ne.s = "2"; });
}
if(pmodel == mdBandEquiarea) {
// y = K * sin(phi)
// cos(phi) * cos(phi) = 1/K
if(sphere && vid.stretch >= 1) {
ld phi = acos(sqrt(1/vid.stretch));
if(sphere && vpconf.stretch >= 1) {
ld phi = acos(sqrt(1/vpconf.stretch));
dialog::addInfo(XLAT("The current value makes the map conformal at the latitude of %1 (%2°).", fts(phi), fts(phi / degree)));
}
else if(hyperbolic && abs(vid.stretch) <= 1 && abs(vid.stretch) >= 1e-9) {
ld phi = acosh(abs(sqrt(1/vid.stretch)));
else if(hyperbolic && abs(vpconf.stretch) <= 1 && abs(vpconf.stretch) >= 1e-9) {
ld phi = acosh(abs(sqrt(1/vpconf.stretch)));
dialog::addInfo(XLAT("The current value makes the map conformal %1 units from the main line.", fts(phi)));
}
else dialog::addInfo("");
@ -415,6 +398,7 @@ EX namespace models {
EX void model_menu() {
cmode = sm::SIDE | sm::MAYDARK | sm::CENTER;
gamescreen(0);
USING_NATIVE_GEOMETRY_IN_RUG;
dialog::init(XLAT("models & projections"));
dialog::addSelItem(XLAT("projection type"), get_model_name(pmodel), 'm');
@ -429,34 +413,34 @@ EX namespace models {
dialog::lastItem().value += " " + its(rotation) + "°";
else
dialog::lastItem().value += " " + its(rotation) + "°" + its(rotation_xz) + "°" + its(rotation_xy2) + "°";
dialog::add_action([] { edit_rotation(models::rotation); });
dialog::add_action([] { edit_rotation(rotation); });
// if(pmodel == mdBand && sphere)
if(!in_perspective()) {
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
dialog::addSelItem(XLAT("scale factor"), fts(vpconf.scale), 'z');
dialog::add_action(editScale);
}
if(abs(vid.alpha-1) > 1e-3 && pmodel != mdBall && pmodel != mdHyperboloid && pmodel != mdHemisphere && pmodel != mdDisk) {
if(abs(pconf.alpha-1) > 1e-3 && pmodel != mdBall && pmodel != mdHyperboloid && pmodel != mdHemisphere && pmodel != mdDisk) {
dialog::addBreak(50);
dialog::addInfo("NOTE: this works 'correctly' only if the Poincaré model/stereographic projection is used.");
dialog::addBreak(50);
}
if(among(pmodel, mdDisk, mdBall, mdHyperboloid, mdRotatedHyperboles)) {
dialog::addSelItem(XLAT("projection distance"), fts(vid.alpha) + " (" + current_proj_name() + ")", 'p');
dialog::addSelItem(XLAT("projection distance"), fts(vpconf.alpha) + " (" + current_proj_name() + ")", 'p');
dialog::add_action(projectionDialog);
}
if(model_has_orientation()) {
dialog::addSelItem(XLAT("model orientation"), fts(model_orientation) + "°", 'l');
if(has_orientation(vpconf.model)) {
dialog::addSelItem(XLAT("model orientation"), fts(vpconf.model_orientation) + "°", 'l');
dialog::add_action([] () {
dialog::editNumber(model_orientation, 0, 360, 90, 0, XLAT("model orientation"), "");
dialog::editNumber(vpconf.model_orientation, 0, 360, 90, 0, XLAT("model orientation"), "");
});
if(GDIM == 3) {
dialog::addSelItem(XLAT("model orientation (y/z plane)"), fts(model_orientation_yz) + "°", 'L');
dialog::addSelItem(XLAT("model orientation (y/z plane)"), fts(vpconf.model_orientation_yz) + "°", 'L');
dialog::add_action([] () {
dialog::editNumber(model_orientation_yz, 0, 360, 90, 0, XLAT("model orientation (y/z plane)"), "");
dialog::editNumber(vpconf.model_orientation_yz, 0, 360, 90, 0, XLAT("model orientation (y/z plane)"), "");
});
}
}
@ -466,17 +450,17 @@ EX namespace models {
"Your view of the 3D model is naturally bounded from four directions by your window. "
"Here, you can also set up similar bounds in the Z direction. Radius of the ball/band "
"models, and the distance from the center to the plane in the halfspace model, are 1.\n\n");
dialog::addSelItem(XLAT("near clipping plane"), fts(clip_max), 'c');
dialog::addSelItem(XLAT("near clipping plane"), fts(vpconf.clip_max), 'c');
dialog::add_action([cliphelp] () {
dialog::editNumber(clip_max, -10, 10, 0.2, 1, XLAT("near clipping plane"),
dialog::editNumber(vpconf.clip_max, -10, 10, 0.2, 1, XLAT("near clipping plane"),
cliphelp + XLAT("Objects with Z coordinate "
"bigger than this parameter are not shown. This is useful with the models which "
"extend infinitely in the Z direction, or if you want things close to your character "
"to be not obscured by things closer to the camera."));
});
dialog::addSelItem(XLAT("far clipping plane"), fts(clip_min), 'C');
dialog::addSelItem(XLAT("far clipping plane"), fts(vpconf.clip_min), 'C');
dialog::add_action([cliphelp] () {
dialog::editNumber(clip_min, -10, 10, 0.2, -1, XLAT("far clipping plane"),
dialog::editNumber(vpconf.clip_min, -10, 10, 0.2, -1, XLAT("far clipping plane"),
cliphelp + XLAT("Objects with Z coordinate "
"smaller than this parameter are not shown; it also affects the fog effect"
" (near clipping plane = 0% fog, far clipping plane = 100% fog)."));
@ -506,20 +490,20 @@ EX namespace models {
}
if(pmodel == mdHalfplane) {
dialog::addSelItem(XLAT("half-plane scale"), fts(halfplane_scale), 'b');
dialog::addSelItem(XLAT("half-plane scale"), fts(vpconf.halfplane_scale), 'b');
dialog::add_action([] () {
dialog::editNumber(halfplane_scale, 0, 2, 0.25, 1, XLAT("half-plane scale"), "");
dialog::editNumber(vpconf.halfplane_scale, 0, 2, 0.25, 1, XLAT("half-plane scale"), "");
});
}
if(pmodel == mdRotatedHyperboles) {
dialog::addBoolItem_action(XLAT("use atan to make it finite"), use_atan, 'x');
dialog::addBoolItem_action(XLAT("use atan to make it finite"), vpconf.use_atan, 'x');
}
if(pmodel == mdBall) {
dialog::addSelItem(XLAT("projection in ball model"), fts(vid.ballproj), 'x');
dialog::addSelItem(XLAT("projection in ball model"), fts(vpconf.ballproj), 'x');
dialog::add_action([] () {
dialog::editNumber(vid.ballproj, 0, 100, .1, 0, XLAT("projection in ball model"),
dialog::editNumber(vpconf.ballproj, 0, 100, .1, 0, XLAT("projection in ball model"),
"This parameter affects the ball model the same way as the projection parameter affects the disk model.");
});
}
@ -543,38 +527,38 @@ EX namespace models {
});
}
if(model_is_3d()) {
dialog::addSelItem(XLAT("camera rotation in 3D models"), fts(vid.ballangle) + "°", 'b');
if(is_3d(vpconf)) {
dialog::addSelItem(XLAT("camera rotation in 3D models"), fts(vpconf.ballangle) + "°", 'b');
dialog::add_action(config_camera_rotation);
}
if(pmodel == mdHyperboloid) {
dialog::addSelItem(XLAT("maximum z coordinate to show"), fts(top_z), 'l');
dialog::addSelItem(XLAT("maximum z coordinate to show"), fts(vpconf.top_z), 'l');
dialog::add_action([](){
dialog::editNumber(top_z, 1, 20, 0.25, 4, XLAT("maximum z coordinate to show"), "");
dialog::editNumber(vpconf.top_z, 1, 20, 0.25, 4, XLAT("maximum z coordinate to show"), "");
});
}
if(model_has_transition()) {
dialog::addSelItem(XLAT("model transition"), fts(model_transition), 't');
if(has_transition(vpconf.model)) {
dialog::addSelItem(XLAT("model transition"), fts(vpconf.model_transition), 't');
dialog::add_action([]() {
dialog::editNumber(model_transition, 0, 1, 0.1, 1, XLAT("model transition"),
dialog::editNumber(vpconf.model_transition, 0, 1, 0.1, 1, XLAT("model transition"),
"You can change this parameter for a transition from another model to this one."
);
});
}
if(among(pmodel, mdJoukowsky, mdJoukowskyInverted, mdSpiral) && GDIM == 2) {
dialog::addSelItem(XLAT("Möbius transformations"), fts(vid.skiprope) + "°", 'S');
dialog::addSelItem(XLAT("Möbius transformations"), fts(vpconf.skiprope) + "°", 'S');
dialog::add_action([](){
dialog::editNumber(vid.skiprope, 0, 360, 15, 0, XLAT("Möbius transformations"), "");
dialog::editNumber(vpconf.skiprope, 0, 360, 15, 0, XLAT("Möbius transformations"), "");
});
}
if(pmodel == mdHemisphere && euclid) {
dialog::addSelItem(XLAT("parameter"), fts(vid.euclid_to_sphere), 'l');
dialog::addSelItem(XLAT("parameter"), fts(vpconf.euclid_to_sphere), 'l');
dialog::add_action([] () {
dialog::editNumber(vid.euclid_to_sphere, 0, 10, .1, 1, XLAT("parameter"),
dialog::editNumber(vpconf.euclid_to_sphere, 0, 10, .1, 1, XLAT("parameter"),
"Stereographic projection to a sphere. Choose the radius of the sphere."
);
dialog::scaleLog();
@ -582,9 +566,9 @@ EX namespace models {
}
if(among(pmodel, mdTwoPoint, mdSimulatedPerspective, mdTwoHybrid)) {
dialog::addSelItem(XLAT("parameter"), fts(vid.twopoint_param), 'b');
dialog::addSelItem(XLAT("parameter"), fts(vpconf.twopoint_param), 'b');
dialog::add_action([](){
dialog::editNumber(vid.twopoint_param, 1e-3, 10, .1, 1, XLAT("parameter"),
dialog::editNumber(vpconf.twopoint_param, 1e-3, 10, .1, 1, XLAT("parameter"),
"This model maps the world so that the distances from two points "
"are kept. This parameter gives the distance from the two points to "
"the center."
@ -594,9 +578,9 @@ EX namespace models {
}
if(pmodel == mdFisheye) {
dialog::addSelItem(XLAT("parameter"), fts(vid.fisheye_param), 'b');
dialog::addSelItem(XLAT("parameter"), fts(vpconf.fisheye_param), 'b');
dialog::add_action([](){
dialog::editNumber(vid.fisheye_param, 1e-3, 10, .1, 1, XLAT("parameter"),
dialog::editNumber(vpconf.fisheye_param, 1e-3, 10, .1, 1, XLAT("parameter"),
"Size of the fish eye."
);
dialog::scaleLog();
@ -604,29 +588,29 @@ EX namespace models {
}
if(pmodel == mdCollignon) {
dialog::addSelItem(XLAT("parameter"), fts(vid.collignon_parameter) + (vid.collignon_reflected ? " (r)" : ""), 'b');
dialog::addSelItem(XLAT("parameter"), fts(vpconf.collignon_parameter) + (vpconf.collignon_reflected ? " (r)" : ""), 'b');
dialog::add_action([](){
dialog::editNumber(vid.collignon_parameter, -1, 1, .1, 1, XLAT("parameter"),
dialog::editNumber(vpconf.collignon_parameter, -1, 1, .1, 1, XLAT("parameter"),
""
);
dialog::extra_options = [] {
dialog::addBoolItem_action(XLAT("reflect"), vid.collignon_reflected, 'R');
dialog::addBoolItem_action(XLAT("reflect"), vpconf.collignon_reflected, 'R');
};
});
}
if(pmodel == mdSpiral && !euclid) {
dialog::addSelItem(XLAT("spiral angle"), fts(spiral_angle) + "°", 'x');
dialog::addSelItem(XLAT("spiral angle"), fts(vpconf.spiral_angle) + "°", 'x');
dialog::add_action([](){
dialog::editNumber(spiral_angle, 0, 360, 15, 0, XLAT("spiral angle"),
dialog::editNumber(vpconf.spiral_angle, 0, 360, 15, 0, XLAT("spiral angle"),
XLAT("set to 90° for the ring projection")
);
});
ld& which =
sphere ? sphere_spiral_multiplier :
ring_not_spiral ? right_spiral_multiplier :
any_spiral_multiplier;
sphere ? vpconf.sphere_spiral_multiplier :
ring_not_spiral ? vpconf.right_spiral_multiplier :
vpconf.any_spiral_multiplier;
dialog::addSelItem(XLAT("spiral multiplier"), fts(which) + "°", 'M');
dialog::add_action([&which](){
@ -640,20 +624,20 @@ EX namespace models {
);
});
dialog::addSelItem(XLAT("spiral cone"), fts(spiral_cone) + "°", 'C');
dialog::addSelItem(XLAT("spiral cone"), fts(vpconf.spiral_cone) + "°", 'C');
dialog::add_action([](){
dialog::editNumber(spiral_cone, 0, 360, -45, 360, XLAT("spiral cone"), "");
dialog::editNumber(vpconf.spiral_cone, 0, 360, -45, 360, XLAT("spiral cone"), "");
});
}
if(pmodel == mdSpiral && euclid) {
dialog::addSelItem(XLAT("spiral period: x"), fts(spiral_x), 'x');
dialog::addSelItem(XLAT("spiral period: x"), fts(vpconf.spiral_x), 'x');
dialog::add_action([](){
dialog::editNumber(spiral_x, -20, 20, 1, 10, XLAT("spiral period: x"), "");
dialog::editNumber(vpconf.spiral_x, -20, 20, 1, 10, XLAT("spiral period: x"), "");
});
dialog::addSelItem(XLAT("spiral period: y"), fts(spiral_y), 'y');
dialog::addSelItem(XLAT("spiral period: y"), fts(vpconf.spiral_y), 'y');
dialog::add_action([](){
dialog::editNumber(spiral_y, -20, 20, 1, 10, XLAT("spiral period: y"), "");
dialog::editNumber(vpconf.spiral_y, -20, 20, 1, 10, XLAT("spiral period: y"), "");
});
if(euclid && quotient) {
dialog::addSelItem(XLAT("match the period"), its(spiral_id), 'n');
@ -661,13 +645,13 @@ EX namespace models {
}
}
dialog::addSelItem(XLAT("vertical stretch"), fts(vid.stretch), 's');
dialog::addSelItem(XLAT("vertical stretch"), fts(vpconf.stretch), 's');
dialog::add_action(edit_stretch);
if(product_model()) {
dialog::addSelItem(XLAT("product Z stretch"), fts(product_z_scale), 'Z');
if(product_model(vpconf.model)) {
dialog::addSelItem(XLAT("product Z stretch"), fts(vpconf.product_z_scale), 'Z');
dialog::add_action([] {
dialog::editNumber(product_z_scale, 0.1, 10, 0.1, 1, XLAT("product Z stretch"), "");
dialog::editNumber(vpconf.product_z_scale, 0.1, 10, 0.1, 1, XLAT("product Z stretch"), "");
dialog::scaleLog();
});
}
@ -716,39 +700,39 @@ EX namespace models {
shift_arg_formula(history::extra_line_steps);
}
else if(argis("-stretch")) {
PHASEFROM(2); shift_arg_formula(vid.stretch);
PHASEFROM(2); shift_arg_formula(vpconf.stretch);
}
else if(argis("-PM")) {
PHASEFROM(2); shift(); pmodel = read_model(args());
PHASEFROM(2); shift(); vpconf.model = read_model(args());
if(pmodel == mdFormula) {
shift(); basic_model = eModel(argi());
shift(); formula = args();
shift(); vpconf.basic_model = eModel(argi());
shift(); vpconf.formula = args();
}
}
else if(argis("-ballangle")) {
PHASEFROM(2);
shift_arg_formula(vid.ballangle);
shift_arg_formula(vpconf.ballangle);
}
else if(argis("-topz")) {
PHASEFROM(2);
shift_arg_formula(models::top_z);
shift_arg_formula(vpconf.top_z);
}
else if(argis("-twopoint")) {
PHASEFROM(2);
shift_arg_formula(vid.twopoint_param);
shift_arg_formula(vpconf.twopoint_param);
}
else if(argis("-hp")) {
PHASEFROM(2);
shift_arg_formula(models::halfplane_scale);
shift_arg_formula(vpconf.halfplane_scale);
}
else if(argis("-mori")) {
PHASEFROM(2);
shift_arg_formula(models::model_orientation);
shift_arg_formula(vpconf.model_orientation);
}
else if(argis("-mori2")) {
PHASEFROM(2);
shift_arg_formula(models::model_orientation);
shift_arg_formula(models::model_orientation_yz);
shift_arg_formula(vpconf.model_orientation);
shift_arg_formula(vpconf.model_orientation_yz);
}
else if(argis("-crot")) {
PHASEFROM(2);
@ -758,43 +742,43 @@ EX namespace models {
}
else if(argis("-clip")) {
PHASEFROM(2);
shift_arg_formula(models::clip_min);
shift_arg_formula(models::clip_max);
shift_arg_formula(vpconf.clip_min);
shift_arg_formula(vpconf.clip_max);
}
else if(argis("-mtrans")) {
PHASEFROM(2);
shift_arg_formula(models::model_transition);
shift_arg_formula(vpconf.model_transition);
}
else if(argis("-sang")) {
PHASEFROM(2);
shift_arg_formula(models::spiral_angle);
shift_arg_formula(vpconf.spiral_angle);
if(sphere)
shift_arg_formula(models::sphere_spiral_multiplier);
else if(models::spiral_angle == 90)
shift_arg_formula(models::right_spiral_multiplier);
shift_arg_formula(vpconf.sphere_spiral_multiplier);
else if(vpconf.spiral_angle == 90)
shift_arg_formula(vpconf.right_spiral_multiplier);
}
else if(argis("-ssm")) {
PHASEFROM(2);
shift_arg_formula(models::any_spiral_multiplier);
shift_arg_formula(vpconf.any_spiral_multiplier);
}
else if(argis("-scone")) {
PHASEFROM(2);
shift_arg_formula(models::spiral_cone);
shift_arg_formula(vpconf.spiral_cone);
}
else if(argis("-sxy")) {
PHASEFROM(2);
shift_arg_formula(models::spiral_x);
shift_arg_formula(models::spiral_y);
shift_arg_formula(vpconf.spiral_x);
shift_arg_formula(vpconf.spiral_y);
}
else if(argis("-mob")) {
PHASEFROM(2);
shift_arg_formula(vid.skiprope);
shift_arg_formula(vpconf.skiprope);
}
else if(argis("-zoom")) {
PHASEFROM(2); shift_arg_formula(vid.scale);
PHASEFROM(2); shift_arg_formula(vpconf.scale);
}
else if(argis("-alpha")) {
PHASEFROM(2); shift_arg_formula(vid.alpha);
PHASEFROM(2); shift_arg_formula(vpconf.alpha);
}
else if(argis("-d:model"))
launch_dialog(model_menu);

View File

@ -307,7 +307,7 @@ EX namespace netgen {
renderbuffer rbuf(2000, 2000, vid.usingGL);
dynamicval<videopar> dv(vid, vid);
vid.xres = vid.yres = 2000; vid.scale = 0.99;
vid.xres = vid.yres = 2000; pconf.scale = 0.99;
if(1) {
resetbuffer rb;

View File

@ -1933,8 +1933,8 @@ EX namespace rots {
dynamicval<transmatrix> m3(playerV, Id);
dynamicval<transmatrix> m4(actual_view_transform, Id);
dynamicval<eModel> pm(pmodel, mdDisk);
dynamicval<ld> pss(vid.scale, (sphere ? 10 : 1) * underlying_scale);
dynamicval<ld> psa(vid.alpha, sphere ? 10 : 1);
dynamicval<ld> pss(pconf.scale, (sphere ? 10 : 1) * underlying_scale);
dynamicval<ld> psa(pconf.alpha, sphere ? 10 : 1);
dynamicval<hrmap*> p(hybrid::pmap, NULL);
dynamicval<int> psr(sightrange_bonus, 0);
calcparam();

View File

@ -274,13 +274,13 @@ EX hint hints[] = {
specialland = laHalloween;
set_geometry(gSphere);
start_game();
vid.alpha = 999;
vid.scale = 998;
pconf.alpha = 999;
pconf.scale = 998;
}
else {
resetModes();
vid.alpha = 1;
vid.scale = 1;
pconf.alpha = 1;
pconf.scale = 1;
}
}
},
@ -415,7 +415,7 @@ EX void showMission() {
if(canmove) {
if(sphere) {
dialog::addItem(XLAT("return to your game"), '1');
dialog::addItem(XLAT(vid.alpha < 2 ? "orthogonal projection" : "stereographic projection"), '3');
dialog::addItem(XLAT(pconf.alpha < 2 ? "orthogonal projection" : "stereographic projection"), '3');
}
else if(euclid) {
dialog::addItem(XLAT("return to your game"), '2');

View File

@ -939,15 +939,15 @@ void race_projection() {
dialog::init(XLAT("racing projections"));
dialog::addBoolItem(XLAT("Poincaré disk model"), pmodel == mdDisk && !vid.camera_angle, '1');
dialog::addBoolItem(XLAT("Poincaré disk model"), pmodel == mdDisk && !pconf.camera_angle, '1');
dialog::add_action([] () {
pmodel = mdDisk;
race_advance = 0;
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
pconf.camera_angle = 0;
pconf.xposition = 0;
pconf.yposition = 0;
pconf.scale = 1;
vid.use_smart_range = 0;
vid.smart_range_detail = 3;
});
@ -955,13 +955,13 @@ void race_projection() {
dialog::addBoolItem(XLAT("band"), pmodel == mdBand, '2');
dialog::add_action([] () {
pmodel = mdBand;
models::model_orientation = race_angle;
pconf.model_orientation = race_angle;
race_advance = 1;
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
pconf.camera_angle = 0;
pconf.xposition = 0;
pconf.yposition = 0;
pconf.scale = 1;
vid.use_smart_range = 1;
vid.smart_range_detail = 3;
});
@ -969,26 +969,26 @@ void race_projection() {
dialog::addBoolItem(XLAT("half-plane"), pmodel == mdHalfplane, '3');
dialog::add_action([] () {
pmodel = mdHalfplane;
models::model_orientation = race_angle + 90;
pconf.model_orientation = race_angle + 90;
race_advance = 0.5;
vid.yshift = 0;
vid.camera_angle = 0;
vid.xposition = 0;
vid.yposition = 0;
vid.scale = 1;
pconf.camera_angle = 0;
pconf.xposition = 0;
pconf.yposition = 0;
pconf.scale = 1;
vid.use_smart_range = 1;
vid.smart_range_detail = 3;
});
dialog::addBoolItem(XLAT("third-person perspective"), pmodel == mdDisk && vid.camera_angle, '4');
dialog::addBoolItem(XLAT("third-person perspective"), pmodel == mdDisk && pconf.camera_angle, '4');
dialog::add_action([] () {
pmodel = mdDisk;
race_advance = 0;
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;
pconf.camera_angle = -45;
pconf.scale = 18/16. * vid.xres / vid.yres / multi::players;
pconf.xposition = 0;
pconf.yposition = -0.9;
vid.use_smart_range = 1;
vid.smart_range_detail = 3;
});
@ -1011,8 +1011,8 @@ void race_projection() {
dialog::addSelItem(XLAT("race angle"), fts(race_angle), 'a');
dialog::add_action([] () {
dialog::editNumber(race_angle, 0, 360, 15, 90, XLAT("race angle"), "");
int q = models::model_orientation - race_angle;
dialog::reaction = [q] () { models::model_orientation = race_angle + q; };
int q = pconf.model_orientation - race_angle;
dialog::reaction = [q] () { pconf.model_orientation = race_angle + q; };
});
}

37
rug.cpp
View File

@ -103,7 +103,10 @@ constexpr eGeometry rgElliptic = gECell120;
EX eGeometry gwhere = rgEuclid;
#if HDR
#define USING_NATIVE_GEOMETRY_IN_RUG dynamicval<eGeometry> gw(geometry, rug::rugged ? hr::rug::gwhere : geometry)
#define USING_NATIVE_GEOMETRY dynamicval<eGeometry> gw(geometry, hr::rug::gwhere)
#endif
// hypersian rug datatypes and globals
//-------------------------------------
@ -131,9 +134,9 @@ EX rugpoint *finger_center;
EX ld finger_range = .1;
EX ld finger_force = 1;
EX eModel rug_projection = mdEquidistant;
#define rconf (vid.rug_config)
EX bool perspective() { return models::model_is_perspective(rug_projection); }
EX bool perspective() { return models::is_perspective(rconf.model); }
void push_point(hyperpoint& h, int coord, ld val) {
USING_NATIVE_GEOMETRY;
@ -166,15 +169,15 @@ EX rugpoint *addRugpoint(hyperpoint h, double dist) {
m->h = h;
/*
ld tz = vid.alpha+h[2];
ld tz = pconf.alpha+h[2];
m->x1 = (1 + h[0] / tz) / 2;
m->y1 = (1 + h[1] / tz) / 2;
*/
hyperpoint onscreen;
applymodel(m->h, onscreen);
m->x1 = (1 + onscreen[0] * vid.scale) / 2;
m->y1 = (1 - onscreen[1] * vid.scale) / 2;
m->x1 = (1 + onscreen[0] * pconf.scale) / 2;
m->y1 = (1 - onscreen[1] * pconf.scale) / 2;
m->valid = false;
if(euclid && quotient && !bounded) {
@ -347,7 +350,7 @@ EX void calcparam_rug() {
cd->xsize = cd->ysize = TEXTURESIZE;
cd->xcenter = cd->ycenter = cd->scrsize = HTEXTURESIZE;
cd->radius = cd->scrsize * vid.scale;
cd->radius = cd->scrsize * pconf.scale;
}
EX void buildTorusRug() {
@ -467,11 +470,11 @@ EX void buildTorusRug() {
for(auto p: points)
maxz = max(maxz, max(abs(p->x1), abs(p->y1)));
if(1) vid.scale = 1 / maxz;
if(1) pconf.scale = 1 / maxz;
if(1) for(auto p: points)
p->x1 = (1 + vid.scale * p->x1)/2,
p->y1 = (1 - vid.scale * p->y1)/2;
p->x1 = (1 + pconf.scale * p->x1)/2,
p->y1 = (1 - pconf.scale * p->y1)/2;
qvalid = 0;
for(auto p: points) if(!p->glue) qvalid++;
@ -1080,7 +1083,7 @@ EX void drawRugScene() {
rug.tinf = &tinf;
rug.flags = POLY_TRIANGLES | POLY_FAT | POLY_PRINTABLE;
dynamicval<eModel> p(pmodel, rug_projection);
dynamicval<projection_configuration> p(pconf, rconf);
drawqueue();
}
@ -1147,7 +1150,7 @@ EX void init_model() {
if(r->x1<0 || r->x1>1 || r->y1<0 || r->y1 > 1)
valid = false;
if(sphere && pmodel == mdDisk && vid.alpha > 1)
if(sphere && pmodel == mdDisk && pconf.alpha > 1)
valid = false;
if(display_warning && !valid)
@ -1453,8 +1456,10 @@ EX void show() {
dialog::lastItem().value += " (" + its(qvalid) + ")";
dialog::addSelItem(XLAT("model distance"), fts(model_distance), 'd');
{ USING_NATIVE_GEOMETRY;
dialog::addSelItem(XLAT("projection"), models::get_model_name(rug_projection), 'p'); }
if(rug::rugged) {
dialog::addSelItem(XLAT("projection"), models::get_model_name(rconf.model), 'p');
}
else dialog::addBreak(100);
if(!rug::rugged)
dialog::addSelItem(XLAT("native geometry"), geometry_name(gwhere), 'n');
else
@ -1570,7 +1575,7 @@ EX void show() {
}
}
else if(uni == 'p') {
rug_projection = rug_projection == mdEquidistant ? mdPerspective : mdEquidistant;
pushScreen(models::model_menu);
}
else if(uni == 'd') {
dialog::editNumber(model_distance, -10, 10, .1, 1, XLAT("model distance"),
@ -1718,7 +1723,7 @@ int rugArgs() {
}
else if(argis("-rugpers")) {
rug_projection = mdPerspective;
rconf.model = mdPerspective;
}
else if(argis("-rugonce")) {
@ -1759,7 +1764,7 @@ int rugArgs() {
}
else if(argis("-rugorth")) {
rug_projection = mdEquidistant;
rconf.model = mdEquidistant;
}
else if(argis("-rugerr")) {

View File

@ -86,10 +86,10 @@ EX always_false in;
EX void circle(int x, int y, int size, color_t col, color_t fillcol, double linewidth) {
if(!invisible(col) || !invisible(fillcol)) {
if(vid.stretch == 1)
if(pconf.stretch == 1)
println(f, "<circle cx='", coord(x), "' cy='", coord(y), "' r='", coord(size), "' ", stylestr(fillcol, col, linewidth), "/>");
else
println(f, "<ellipse cx='", coord(x), "' cy='", coord(y), "' rx='", coord(size), "' ry='", coord(size*vid.stretch), "' ", stylestr(fillcol, col), "/>");
println(f, "<ellipse cx='", coord(x), "' cy='", coord(y), "' rx='", coord(size), "' ry='", coord(size*pconf.stretch), "' ", stylestr(fillcol, col), "/>");
}
}
@ -879,7 +879,7 @@ EX void menu() {
dialog::add_action([] { divby *= 10; if(divby > 1000000) divby = 1; });
#endif
if(models::model_is_3d() || rug::rugged) {
if(models::is_3d(vpconf) || rug::rugged) {
dialog::addInfo("SVG screenshots do not work in this 3D mode", 0xFF0000);
if(GDIM == 2 && !rug::rugged) {
dialog::addSelItem(XLAT("projection"), current_proj_name(), '1');
@ -910,14 +910,14 @@ EX void menu() {
case screenshot_format::wrl: {
#if CAP_WRL
if(!models::model_is_3d() && !rug::rugged) {
if(!models::is_3d(vpconf) && !rug::rugged) {
dialog::addInfo("this format is for 3D projections", 0xFF0000);
if(GDIM == 2) {
dialog::addItem(XLAT("hypersian rug mode"), 'u');
dialog::add_action_push(rug::show);
}
}
else if(rug::rugged ? rug::perspective() : models::model_is_perspective()) {
else if(rug::rugged ? rug::perspective() : models::is_perspective(vpconf.model)) {
dialog::addInfo("this does not work well in perspective projections", 0xFF8000);
dialog::addSelItem(XLAT("projection"), current_proj_name(), '1');
dialog::add_action_push(models::model_menu);
@ -1212,23 +1212,23 @@ EX void apply() {
}
}
#endif
vid.skiprope += skiprope_rotation * t * 2 * M_PI / period;
pconf.skiprope += skiprope_rotation * t * 2 * M_PI / period;
if(ballangle_rotation) {
if(models::model_has_orientation())
models::model_orientation += ballangle_rotation * 360 * t / period;
if(models::has_orientation(vpconf.model))
vpconf.model_orientation += ballangle_rotation * 360 * t / period;
else
vid.ballangle += ballangle_rotation * 360 * t / period;
vpconf.ballangle += ballangle_rotation * 360 * t / period;
}
if(joukowsky_anim) {
ld t = ticks / period;
t = t - floor(t);
if(pmodel == mdBand) {
models::model_transition = t * 4 - 1;
vpconf.model_transition = t * 4 - 1;
}
else {
models::model_transition = t / 1.1;
vid.scale = (1 - models::model_transition) / 2.;
vpconf.model_transition = t / 1.1;
vpconf.scale = (1 - vpconf.model_transition) / 2.;
}
}
apply_animated_parameters();
@ -1487,7 +1487,7 @@ EX void show() {
});
}
#endif
if(models::model_has_orientation())
if(models::has_orientation(vpconf.model))
animator(XLAT("model rotation"), ballangle_rotation, 'I');
else if(among(pmodel, mdHyperboloid, mdHemisphere, mdBall))
animator(XLAT("3D rotation"), ballangle_rotation, '3');
@ -1666,9 +1666,9 @@ startanim null_animation { "", no_init, [] { gamescreen(2); }};
startanim joukowsky { "Joukowsky transform", no_init, [] {
dynamicval<eModel> dm(pmodel, mdJoukowskyInverted);
dynamicval<ld> dt(models::model_orientation, ticks / 25.);
dynamicval<ld> dt(pconf.model_orientation, ticks / 25.);
dynamicval<int> dv(vid.use_smart_range, 2);
dynamicval<ld> ds(vid.scale, 1/4.);
dynamicval<ld> ds(pconf.scale, 1/4.);
models::configure();
dynamicval<color_t> dc(ringcolor, 0);
gamescreen(2);
@ -1677,7 +1677,7 @@ startanim joukowsky { "Joukowsky transform", no_init, [] {
startanim bandspin { "spinning in the band model", no_init, [] {
dynamicval<eModel> dm(pmodel, mdBand);
dynamicval<ld> dt(models::model_orientation, ticks / 25.);
dynamicval<ld> dt(pconf.model_orientation, ticks / 25.);
dynamicval<int> dv(vid.use_smart_range, 2);
models::configure();
gamescreen(2);
@ -1690,8 +1690,8 @@ startanim perspective { "projection distance", no_init, [] {
x /= 2;
x *= 1.5;
x = tan(x);
dynamicval<ld> da(vid.alpha, x);
dynamicval<ld> ds(vid.scale, (1+x)/2);
dynamicval<ld> da(pconf.alpha, x);
dynamicval<ld> ds(pconf.scale, (1+x)/2);
calcparam();
gamescreen(2);
explorable(projectionDialog);
@ -1709,8 +1709,8 @@ startanim rug { "Hypersian Rug", [] {
}};
startanim spin_around { "spinning around", no_init, [] {
dynamicval<ld> da(vid.alpha, 999);
dynamicval<ld> ds(vid.scale, 500);
dynamicval<ld> da(pconf.alpha, 999);
dynamicval<ld> ds(pconf.scale, 500);
ld alpha = 2 * M_PI * ticks / 10000.;
ld circle_radius = acosh(2.);
dynamicval<transmatrix> dv(View, spin(-cos_auto(circle_radius)*alpha) * xpush(circle_radius) * spin(alpha) * View);

View File

@ -359,7 +359,7 @@ void display_data::set_projection(int ed) {
if(pmodel == mdManual) return;
if(vid.stretch != 1 && (shader_flags & SF_DIRECT)) glhr::projection_multiply(glhr::scale(vid.stretch, 1, 1));
if(pconf.stretch != 1 && (shader_flags & SF_DIRECT)) glhr::projection_multiply(glhr::scale(pconf.stretch, 1, 1));
if(vid.stereo_mode != sODS)
eyewidth_translate(ed);
@ -367,10 +367,8 @@ void display_data::set_projection(int ed) {
auto ortho = [&] (ld x, ld y) {
glhr::glmatrix M = glhr::ortho(x, y, 1);
if(shader_flags & SF_ZFOG) {
using models::clip_max;
using models::clip_min;
M[2][2] = 2 / (clip_max - clip_min);
M[3][2] = (clip_min + clip_max) / (clip_max - clip_min);
M[2][2] = 2 / (pconf.clip_max - pconf.clip_min);
M[3][2] = (pconf.clip_min + pconf.clip_max) / (pconf.clip_max - pconf.clip_min);
auto cols = glhr::acolor(darkena(backcolor, 0, 0xFF));
glUniform4f(selected->uFogColor, cols[0], cols[1], cols[2], cols[3]);
}
@ -409,7 +407,7 @@ void display_data::set_projection(int ed) {
glhr::fog_max(1/sightranges[geometry], darkena(backcolor, 0, 0xFF));
}
else {
if(vid.alpha > -1) {
if(pconf.alpha > -1) {
// Because of the transformation from H3 to the Minkowski hyperboloid,
// points with negative Z can be generated in some 3D settings.
// This happens for points below the camera, but above the plane.
@ -420,14 +418,14 @@ void display_data::set_projection(int ed) {
GLfloat sc = current_display->radius / (cd->ysize/2.);
glhr::projection_multiply(glhr::frustum(cd->xsize / cd->ysize, 1));
glhr::projection_multiply(glhr::scale(sc, -sc, -1));
glhr::projection_multiply(glhr::translate(0, 0, vid.alpha));
glhr::projection_multiply(glhr::translate(0, 0, pconf.alpha));
if(ed) glhr::projection_multiply(glhr::translate(vid.ipd * ed/2, 0, 0));
}
if(selected->uPP != -1) {
glhr::glmatrix pp = glhr::id;
if(get_shader_flags() & SF_USE_ALPHA)
pp[3][2] = GLfloat(vid.alpha);
pp[3][2] = GLfloat(pconf.alpha);
if(get_shader_flags() & SF_ORIENT) {
if(GDIM == 3) for(int a=0; a<4; a++)
@ -440,7 +438,7 @@ void display_data::set_projection(int ed) {
}
if(selected->uAlpha != -1)
glhr::set_ualpha(vid.alpha);
glhr::set_ualpha(pconf.alpha);
if(selected->uLevelLines != -1) {
glUniform1f(selected->uLevelLines, levellines);
@ -458,12 +456,12 @@ void display_data::set_projection(int ed) {
if(selected->shader_flags & SF_HALFPLANE) {
glhr::projection_multiply(glhr::translate(0, 1, 0));
glhr::projection_multiply(glhr::scale(-1, 1, 1));
glhr::projection_multiply(glhr::scale(models::halfplane_scale, models::halfplane_scale, GDIM == 3 ? models::halfplane_scale : 1));
glhr::projection_multiply(glhr::scale(pconf.halfplane_scale, pconf.halfplane_scale, GDIM == 3 ? pconf.halfplane_scale : 1));
glhr::projection_multiply(glhr::translate(0, 0.5, 0));
}
if(vid.camera_angle && pmodel != mdPixel) {
ld cam = vid.camera_angle * degree;
if(pconf.camera_angle && pmodel != mdPixel) {
ld cam = pconf.camera_angle * degree;
GLfloat cc = cos(cam);
GLfloat ss = sin(cam);

View File

@ -815,7 +815,7 @@ void movePlayer(monster *m, int delta) {
hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
hyperpoint ctr = m->pat * C0;
if(sphere && vid.alpha > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
if(sphere && pconf.alpha > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
hyperpoint h = inverse(m->pat) * rgpushxto0(ctr) * jh;

View File

@ -11,8 +11,6 @@
#if CAP_SURFACE
namespace hr {
#define USING_NATIVE_GEOMETRY dynamicval<eGeometry> gw(geometry, hr::rug::gwhere)
EX namespace surface {
ld sech(ld d) { return 1 / cosh(d); }

View File

@ -355,7 +355,7 @@ hyperpoint texture_config::texture_coordinates(hyperpoint h) {
hyperpoint inmodel;
applymodel(h, inmodel);
inmodel[0] *= current_display->radius * 1. / current_display->scrsize;
inmodel[1] *= current_display->radius * vid.stretch / current_display->scrsize;
inmodel[1] *= current_display->radius * pconf.stretch / current_display->scrsize;
inmodel[2] = 1;
inmodel = itt * inmodel;
inmodel[0] = (inmodel[0] + 1) / 2;
@ -531,7 +531,7 @@ void texture_config::mark_triangles() {
}
}
static const auto current_texture_parameters = tie(geometry, variation, patterns::whichPattern, patterns::subpattern_flags, pmodel, vid.scale, vid.alpha);
static const auto current_texture_parameters = tie(geometry, variation, patterns::whichPattern, patterns::subpattern_flags, pmodel, pconf.scale, pconf.alpha);
void texture_config::clear_texture_map() {
texture_map.clear();
@ -624,9 +624,9 @@ void texture_config::saveFullTexture(string tn) {
addMessage(XLAT("Saving full texture to %1...", tn));
dynamicval<color_t> dd(grid_color, 0);
dynamicval<color_t> dm(mesh_color, 0);
dynamicval<ld> dx(vid.xposition, 0);
dynamicval<ld> dy(vid.yposition, 0);
dynamicval<ld> dvs(vid.scale, (pmodel == mdDisk && !euclid) ? 1 : vid.scale);
dynamicval<ld> dx(pconf.xposition, 0);
dynamicval<ld> dy(pconf.yposition, 0);
dynamicval<ld> dvs(pconf.scale, (pmodel == mdDisk && !euclid) ? 1 : pconf.scale);
dynamicval<bool> dro(rug::rugged, false);
dynamicval<bool> dnh(nohud, true);
texture::saving = true;
@ -741,9 +741,9 @@ struct magic_param {
void apply(ld delta) {
if(have_mp(mpProjection))
vid.alpha *= exp(delta * proj);
pconf.alpha *= exp(delta * proj);
if(have_mp(mpScale))
vid.scale *= exp(delta * scale);
pconf.scale *= exp(delta * scale);
if(do_spin) {
if(have_mp(mpRotate))
@ -853,7 +853,7 @@ void mousemovement() {
// do not zoom in portrait!
if(nonzero && !newmove) {
View = inverse(spintox(mouseeu)) * spintox(lastmouse) * View;
vid.scale = vid.scale * sqhypot_d(2, mouseeu) / sqhypot_d(2, lastmouse);
pconf.scale = pconf.scale * sqhypot_d(2, mouseeu) / sqhypot_d(2, lastmouse);
config.perform_mapping();
}
if(nonzero) lastmouse = mouseeu;
@ -863,7 +863,7 @@ void mousemovement() {
case tpsProjection: {
if(nonzero && !newmove) {
vid.alpha = vid.alpha * sqhypot_d(2, mouseeu) / sqhypot_d(2, lastmouse);
pconf.alpha = pconf.alpha * sqhypot_d(2, mouseeu) / sqhypot_d(2, lastmouse);
}
if(nonzero) lastmouse = mouseeu;
newmove = false;
@ -958,9 +958,9 @@ void init_textureconfig() {
addsaverenum(targetgeometry, "geometry", gNormal);
addsaverenum(pmodel, "used model", mdDisk);
addsaver(vid.yshift, "Y shift", 0);
addsaver(vid.yposition, "Y position", 0);
addsaver(vid.xposition, "X position", 0);
addsaver(vid.camera_angle, "camera angle", 0);
addsaver(pconf.yposition, "Y position", 0);
addsaver(pconf.xposition, "X position", 0);
addsaver(pconf.camera_angle, "camera angle", 0);
addsaverenum(targetvariation, "bitruncated", eVariation::bitruncated);
// ... geometry parameters
@ -977,9 +977,9 @@ void init_textureconfig() {
addsaver(config.color_alpha, "alpha color", 0);
addsaver(config.mesh_color, "mesh color", 0);
addsaver(vid.alpha, "projection", 1);
addsaver(vid.scale, "scale", 1);
addsaver(vid.stretch, "stretch", 1);
addsaver(pconf.alpha, "projection", 1);
addsaver(pconf.scale, "scale", 1);
addsaver(pconf.stretch, "stretch", 1);
addsaver(vid.binary_width, "binary-tiling-width", 1);
addsaver(config.texturename, "texture filename", "");

View File

@ -175,7 +175,7 @@ EX void slidehelp() {
/** \brief return from a subgame launched while in presentation */
void return_geometry() {
gamestack::pop();
vid.scale = 1; vid.alpha = 1;
pconf.scale = 1; pconf.alpha = 1;
presentation(pmGeometryReset);
addMessage(XLAT("Returned to your game."));
}
@ -262,11 +262,11 @@ bool handleKeyTour(int sym, int uni) {
break;
case '1':
set_geometry(gSphere);
vid.alpha = 1, vid.scale = .5;
pconf.alpha = 1, pconf.scale = .5;
break;
case '2':
set_geometry(gEuclid);
vid.alpha = 1, vid.scale = .5;
pconf.alpha = 1, pconf.scale = .5;
break;
}
start_game();
@ -288,7 +288,7 @@ bool handleKeyTour(int sym, int uni) {
return true;
}
if(NUMBERKEY == '3' && sphere) {
if(vid.alpha < 2) vid.scale = 400, vid.alpha = 400; else vid.scale = .5, vid.alpha = 1;
if(pconf.alpha < 2) pconf.scale = 400, pconf.alpha = 400; else pconf.scale = .5, pconf.alpha = 1;
addMessage(XLAT("Changed the projection."));
return true;
}
@ -450,8 +450,8 @@ EX namespace ss {
EX void start() {
currentslide = 0;
vid.scale = 1;
vid.alpha = 1;
pconf.scale = 1;
pconf.alpha = 1;
pmodel = mdDisk;
if(!tour::on) presentation(pmStartAll);
else {
@ -839,8 +839,8 @@ EX slide default_slides[] = {
{models+"Beltrami-Klein model", 43, LEGAL::ANY | USE_SLIDE_NAME,
"This model renders straight lines as straight, but it distorts angles.",
[] (presmode mode) {
if(mode == 1 || mode == pmGeometryReset || mode == pmGeometry) vid.alpha = 0;
if(mode == 3) vid.alpha = 1;
if(mode == 1 || mode == pmGeometryReset || mode == pmGeometry) pconf.alpha = 0;
if(mode == 3) pconf.alpha = 1;
}
},
{models+"Gans model", 44, LEGAL::ANY | USE_SLIDE_NAME,
@ -849,8 +849,8 @@ EX slide default_slides[] = {
"model are all obtained by looking at either the hyperboloid model or an "
"equidistant surface from various distances.",
[] (presmode mode) {
if(mode == 1 || mode == pmGeometryReset || mode == pmGeometry) vid.alpha = 400, vid.scale = 150;
if(mode == 3) vid.alpha = vid.scale = 1;
if(mode == 1 || mode == pmGeometryReset || mode == pmGeometry) pconf.alpha = 400, pconf.scale = 150;
if(mode == 3) pconf.alpha = pconf.scale = 1;
}
},
{models+"Band model", 45, LEGAL::NONEUC | USE_SLIDE_NAME,