From 67d38feabd536d79e83d2763a43f6ece859fa611 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Mon, 14 Aug 2023 18:08:28 +0200 Subject: [PATCH] camera_angle now uses matrix dialog --- config.cpp | 21 ++------------------- floorshapes.cpp | 2 +- geometry.cpp | 6 +++--- graph.cpp | 17 ++++++----------- hypgraph.cpp | 33 +++++++++++++++++---------------- legacy.cpp | 6 ++++++ menus.cpp | 2 +- models.cpp | 13 ++++++++++--- racing.cpp | 12 ++++++------ shaders.cpp | 16 ++-------------- sky.cpp | 2 +- textures.cpp | 2 +- 12 files changed, 56 insertions(+), 76 deletions(-) diff --git a/config.cpp b/config.cpp index e26f9e4e..64b76545 100644 --- a/config.cpp +++ b/config.cpp @@ -2605,7 +2605,7 @@ EX geom3::eSpatialEmbedding shown_spatial_embedding() { return geom3::spatial_embedding; } -EX bool in_tpp() { return pmodel == mdDisk && pconf.camera_angle; } +EX bool in_tpp() { return pmodel == mdDisk && !models::camera_straight; } EX void display_embedded_errors() { using namespace geom3; @@ -2854,19 +2854,7 @@ EX void show3D() { dialog::editNumber(mouseaim_sensitivity, -1, 1, 0.002, 0.01, XLAT("mouse aiming sensitivity"), "set to 0 to disable"); }); } - if(true) { - dialog::addSelItem(XLAT("camera rotation"), fts(vpconf.camera_angle), 'S'); - dialog::add_action([] { - 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.") - ); - dialog::get_di().extra_options = [] { - dialog::addBoolItem(XLAT("render behind the camera"), vpconf.back_and_front, 'R'); - dialog::add_action([] { vpconf.back_and_front = !vpconf.back_and_front; }); - }; - }); - } + if(true) add_edit(vpconf.cam()); 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; @@ -3960,11 +3948,6 @@ EX int read_config_args() { else if(argis("-mrsv")) { PHASEFROM(2); shift(); reserve_limit = argi(); apply_memory_reserve(); } - else if(argis("-yca")) { - PHASEFROM(2); - shift_arg_formula(vid.yshift); - shift_arg_formula(pconf.camera_angle); - } else if(argis("-pside")) { PHASEFROM(2); permaside = true; diff --git a/floorshapes.cpp b/floorshapes.cpp index 0fffaf1c..b438e32f 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -1381,7 +1381,7 @@ void geometry_information::make_floor_textures_here() { vid.xres = FLOORTEXTURESIZE; vid.yres = FLOORTEXTURESIZE; pconf.scale = 0.125; - pconf.camera_angle = 0; + dynamicval vm(pconf.cam(), Id); pconf.alpha = 1; dynamicval lw(vid.linewidth, 2); diff --git a/geometry.cpp b/geometry.cpp index 6cf27501..bdc40de1 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -1116,9 +1116,9 @@ EX namespace geom3 { EX void switch_tpp() { if(dual::split(switch_fpp)) return; if(rug::rugged) rug::close(); - if(pmodel == mdDisk && pconf.camera_angle) { + if(pmodel == mdDisk && !models::camera_straight) { vid.yshift = 0; - pconf.camera_angle = 0; + pconf.cam() = Id; pconf.xposition = 0; pconf.yposition = 0; pconf.scale = 1; @@ -1126,7 +1126,7 @@ EX namespace geom3 { } else { vid.yshift = -0.3; - pconf.camera_angle = -45; + pconf.cam() = cspin(1, 2, -45._deg); pconf.scale = 18/16. * vid.xres / vid.yres / multi::players; pconf.xposition = 0; pconf.yposition = -0.9; diff --git a/graph.cpp b/graph.cpp index 3d682237..18329210 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3343,7 +3343,7 @@ EX void drawaura() { ld hx = (x * 1. - current_display->xcenter) / rad; ld hy = (y * 1. - current_display->ycenter) / rad / pconf.stretch; - if(pconf.camera_angle) camrotate(hx, hy); + if(!models::camera_straight) camrotate(hx, hy); ld fac = sqrt(hx*hx+hy*hy); if(fac < 1) continue; @@ -3419,16 +3419,11 @@ EX void drawaura() { ld x = rad0 * c; ld y = rad0 * s; - if(pconf.camera_angle) { - ld z = rad0; - - ld cam = pconf.camera_angle * degree; - GLfloat cc = cos(cam); - GLfloat ss = sin(cam); - - tie(y, z) = make_pair(y * cc - z * ss, z * cc + y * ss); - x *= rad0 / z; - y *= rad0 / z; + if(!models::camera_straight) { + hyperpoint p = hyperpoint(x, y, rad0, 1); + p = pconf.cam() * p; + x = p[0] * rad0 / p[2]; + y = p[1] * rad0 / p[2]; } cx[r][z][0] = x; cx[r][z][1] = y * pconf.stretch; diff --git a/hypgraph.cpp b/hypgraph.cpp index 282954f1..89e2e63f 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -24,11 +24,9 @@ void ghcheck(hyperpoint &ret, const shiftpoint &H) { } EX void camrotate(ld& hx, ld& hy) { - 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; - hx = ux / uz, hy = uy / uz; + hyperpoint p = hyperpoint(hx, hy, 1, 1); + p = pconf.cam() * p; + hx = p[0] / p[2], hy = p[1] / p[2]; } EX bool non_spatial_model() { @@ -145,7 +143,7 @@ EX shiftpoint gethyper(ld x, ld y) { return find_on_screen(hxy, rgpushxto0(ghpm)); } - if(pconf.camera_angle) camrotate(hx, hy); + if(!models::camera_straight) camrotate(hx, hy); return shiftless(perspective_to_space(hpxyz(hx, hy, 0))); } @@ -703,7 +701,7 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) { return; } ld tz = get_tz(H); - if(!pconf.camera_angle) { + if(models::camera_straight) { ret[0] = H[0] / tz; ret[1] = H[1] / tz; if(GDIM == 3) ret[2] = H[2] / tz; @@ -713,13 +711,13 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) { else { ld tx = H[0]; ld ty = H[1]; - 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; - ret[0] = ux / uz; - ret[1] = uy / uz; - ret[2] = vid.xres * current_display->eyewidth() / 2 / current_display->radius - vid.ipd / uz / 2; + + hyperpoint p = hyperpoint(tx, ty, tz, 1); + p = rot_inverse(pconf.cam()) * p; + + ret[0] = p[0] / p[2]; + ret[1] = p[1] / p[2]; + ret[2] = vid.xres * current_display->eyewidth() / 2 / current_display->radius - vid.ipd / p[2] / 2; } return; } @@ -2386,6 +2384,7 @@ eGeometry backup_geometry; eVariation backup_variation; videopar backup_vid; bool backup_lpu; +transmatrix backup_cam; /** \brief enable the 'flat' model for drawing HUD. See hr::flat_model_enabler */ EX void enable_flat_model(int val) { @@ -2395,6 +2394,7 @@ EX void enable_flat_model(int val) { #endif backup_geometry = geometry; backup_variation = variation; + backup_cam = pconf.cam(); backup_lpu = nisot::local_perspective_used; backup_vid = vid; geometry = gNormal; @@ -2404,7 +2404,7 @@ EX void enable_flat_model(int val) { pmodel = mdDisk; pconf.alpha = 1; pconf.scale = 1; - pconf.camera_angle = 0; + pconf.cam() = Id; pconf.stretch = 1; vid.always3 = false; @@ -2421,6 +2421,7 @@ EX void enable_flat_model(int val) { geometry = backup_geometry; variation = backup_variation; nisot::local_perspective_used = backup_lpu; + pconf.cam() = backup_cam; vid = backup_vid; geom3::apply_always3(); calcparam(); @@ -2466,7 +2467,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 && pconf.alpha <= -1) && pconf.camera_angle == 0) { + if(among(pmodel, mdDisk, mdEquiarea, mdEquidistant, mdFisheye) && !(pmodel == mdDisk && hyperbolic && pconf.alpha <= -1) && models::camera_straight) { hyperpoint ret; applymodel(shiftless(xpush0(radius)), ret); ld r = hypot_d(2, ret); diff --git a/legacy.cpp b/legacy.cpp index cca08f46..44b2c0ca 100644 --- a/legacy.cpp +++ b/legacy.cpp @@ -370,6 +370,12 @@ int read_legacy_args() { if(GDIM == 3) shift_arg_formula(models::rotation_xz); if(GDIM == 3) shift_arg_formula(models::rotation_xy2); */ } + else if(argis("-yca")) { + PHASEFROM(2); + shift_arg_formula(vid.yshift); + shift(); ld angle = argf(); + pconf.cam() = cspin(0, 2, angle); + } else return 1; return 0; } diff --git a/menus.cpp b/menus.cpp index 3a579b55..bab834d8 100644 --- a/menus.cpp +++ b/menus.cpp @@ -956,7 +956,7 @@ EX void showStartMenu() { pconf.mori() = racing::race_angle; racing::race_advance = 1; vid.yshift = 0; - pconf.camera_angle = 0; + pconf.cam() = Id; pconf.xposition = 0; pconf.yposition = 0; pconf.scale = 1; diff --git a/models.cpp b/models.cpp index 837f5f1b..6e11c31c 100644 --- a/models.cpp +++ b/models.cpp @@ -138,13 +138,14 @@ projection_configuration::projection_configuration() { ptr_model_orientation = new trans23; ptr_ball = new transmatrix; *ptr_ball = cspin(1, 2, 20._deg); + ptr_camera = new transmatrix; *ptr_camera = Id; } EX namespace models { EX trans23 rotation; EX int do_rotate = 1; - EX bool model_straight, model_straight_yz; + EX bool model_straight, model_straight_yz, camera_straight; /** screen coordinates to orientation logical coordinates */ EX void ori_to_scr(hyperpoint& h) { if(!model_straight) h = pconf.mori().get() * h; } @@ -171,6 +172,7 @@ EX namespace models { EX void configure() { model_straight = (pconf.mori().get()[0][0] > 1 - 1e-9); model_straight_yz = GDIM == 2 || (pconf.mori().get()[2][2] > 1-1e-9); + camera_straight = eqmatrix(pconf.cam(), Id); if(history::on) history::apply(); if(!euclid) { @@ -1057,8 +1059,13 @@ EX namespace models { param_custom(p.alpha, sp+"projection", menuitem_projection_distance, 'p') ->help_text = "projection distance|Gans Klein Poincare orthographic stereographic"; - param_f(p.camera_angle, pp+"cameraangle", sp+"camera angle", 0); - addsaver(p.ballproj, sp+"ballproj", 1); + param_matrix(p.cam(), pp+"cameraangle", 3) + -> editable(pp+"camera angle", "Rotate the camera. Can be used to obtain a first person perspective, " + "or third person perspective when combined with Y shift.", 'S') + -> set_extra([] { + dialog::addBoolItem(XLAT("render behind the camera"), vpconf.back_and_front, 'R'); + dialog::add_action([] { vpconf.back_and_front = !vpconf.back_and_front; }); + }); param_matrix(p.ball(), pp+"ballangle", 3) -> editable("camera rotation in 3D models", diff --git a/racing.cpp b/racing.cpp index f504a345..bfc65a5e 100644 --- a/racing.cpp +++ b/racing.cpp @@ -967,12 +967,12 @@ void race_projection() { dialog::init(XLAT("racing projections")); - dialog::addBoolItem(XLAT("Poincaré disk model"), pmodel == mdDisk && !pconf.camera_angle, '1'); + dialog::addBoolItem(XLAT("Poincaré disk model"), pmodel == mdDisk && models::camera_straight, '1'); dialog::add_action([] () { pmodel = mdDisk; race_advance = 0; vid.yshift = 0; - pconf.camera_angle = 0; + pconf.cam() = Id; pconf.xposition = 0; pconf.yposition = 0; pconf.scale = 1; @@ -986,7 +986,7 @@ void race_projection() { pconf.mori() = race_angle; race_advance = 1; vid.yshift = 0; - pconf.camera_angle = 0; + pconf.cam() = Id; pconf.xposition = 0; pconf.yposition = 0; pconf.scale = 1; @@ -1000,7 +1000,7 @@ void race_projection() { pconf.mori() = race_angle * spin90(); race_advance = 0.5; vid.yshift = 0; - pconf.camera_angle = 0; + pconf.cam() = Id; pconf.xposition = 0; pconf.yposition = 0; pconf.scale = 1; @@ -1008,12 +1008,12 @@ void race_projection() { vid.smart_range_detail = 3; }); - dialog::addBoolItem(XLAT("third-person perspective"), pmodel == mdDisk && pconf.camera_angle, '4'); + dialog::addBoolItem(XLAT("third-person perspective"), pmodel == mdDisk && !models::camera_straight, '4'); dialog::add_action([] () { pmodel = mdDisk; race_advance = 0; vid.yshift = -0.3; - pconf.camera_angle = -45; + pconf.cam() = cspin(1, 2, -45._deg); pconf.scale = 18/16. * vid.xres / vid.yres / multi::players; pconf.xposition = 0; pconf.yposition = -0.9; diff --git a/shaders.cpp b/shaders.cpp index daf8a60b..4b748fd0 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -836,20 +836,8 @@ void display_data::set_projection(int ed, ld shift) { glhr::projection_multiply(glhr::translate(0, 0.5, 0)); } - if(pconf.camera_angle && pmodel != mdPixel) { - ld cam = pconf.camera_angle * degree; - - GLfloat cc = cos(cam); - GLfloat ss = sin(cam); - - GLfloat yzspin[16] = { - 1, 0, 0, 0, - 0, cc, ss, 0, - 0, -ss, cc, 0, - 0, 0, 0, 1 - }; - - glhr::projection_multiply(glhr::as_glmatrix(yzspin)); + if(!models::camera_straight && pmodel != mdPixel) { + glhr::projection_multiply(glhr::tmtogl_transpose(pconf.cam())); } if(u_alpha) { diff --git a/sky.cpp b/sky.cpp index 697c5cb8..6ee73fae 100644 --- a/sky.cpp +++ b/sky.cpp @@ -645,7 +645,7 @@ EX void make_air() { pconf.alpha = 1; pconf.scale = 1; - pconf.camera_angle = 0; + dynamicval vm(pconf.cam(), Id); pconf.stretch = 1; pmodel = mdDisk; diff --git a/textures.cpp b/textures.cpp index c9a38672..4b7867d3 100644 --- a/textures.cpp +++ b/textures.cpp @@ -998,7 +998,7 @@ void init_textureconfig() { addsaver(vid.yshift, "Y shift", 0); addsaver(pconf.yposition, "Y position", 0); addsaver(pconf.xposition, "X position", 0); - addsaver(pconf.camera_angle, "camera angle", 0); + addsaver((matrix_eq&)pconf.cam(), "camera angle"); addsaverenum(targetvariation, "bitruncated", eVariation::bitruncated); // ... geometry parameters