From c20a0cb59eed860d0507d9ff893ebe5d01150e1d Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Mon, 29 Apr 2019 03:34:21 +0200 Subject: [PATCH] 3d:: wallradar --- config.cpp | 8 +++++++- graph.cpp | 36 ++++++++++++++++++++++++++++++++---- hyper.h | 4 ++++ hypgraph.cpp | 17 ++++++----------- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/config.cpp b/config.cpp index c23483e5..57e68abd 100644 --- a/config.cpp +++ b/config.cpp @@ -181,6 +181,7 @@ void initConfig() { addsaver(vid.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.camera_angle, "camera angle", 0); addsaver(vid.ballproj, "ballproj", 1); @@ -1499,10 +1500,15 @@ void show3D() { else if(uni == 'e') pushScreen(showStereo); - else if(uni == 'y') + else if(uni == 'y') { dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"), XLAT("Don't center on the player character.") ); + if(DIM == 3) dialog::extra_options = [] () { + dialog::addBoolItem(XLAT("reduce if walls on the way"), vid.use_wall_radar, 'R'); + dialog::add_action([] () { vid.use_wall_radar = !vid.use_wall_radar; }); + }; + } else if(uni == 's') dialog::editNumber(vid.camera_angle, -180, 180, 5, 0, XLAT("camera rotation"), XLAT("Rotate the camera. Can be used to obtain a first person perspective, " diff --git a/graph.cpp b/graph.cpp index f036c106..3a6fccc3 100644 --- a/graph.cpp +++ b/graph.cpp @@ -6011,12 +6011,40 @@ bool allowChangeRange() { purehookset hooks_drawmap; -transmatrix cview() { +transmatrix actual_view_transform; + +ld wall_radar(cell *c, transmatrix T) { + if(!vid.use_wall_radar) return vid.yshift; + ld fixed_yshift = 0; + ld step = vid.yshift / 20; + for(int i=0; i<20; i++) { + T = T * cpush(2, -step); + virtualRebase(c, T, false); + color_t col; + if(isWall3(c, col)) { + T = T * cpush(2, step); + step /= 2; i = 17; + if(step < 1e-3) break; + } + else fixed_yshift += step; + } + return fixed_yshift; + } + +void make_actual_view() { sphereflip = Id; - if(DIM == 3 && !shmup::on && vid.yshift) return cpush(2, vid.yshift) * View; - if(DIM == 3) return View; + if(DIM == 3 && !shmup::on && vid.yshift) { + actual_view_transform = cpush(2, wall_radar(viewctr.at->c7, inverse(View))); + return; + } + if(DIM == 3) { actual_view_transform = Id; return; } if(sphereflipped()) sphereflip[DIM][DIM] = -1; - return ypush(vid.yshift) * sphereflip * View; + actual_view_transform = ypush(vid.yshift) * sphereflip; + } + +transmatrix cview() { + make_actual_view(); + return actual_view_transform * View; } void precise_mouseover() { diff --git a/hyper.h b/hyper.h index b041376e..d961b153 100644 --- a/hyper.h +++ b/hyper.h @@ -1076,6 +1076,7 @@ struct videopar { int radarsize; // radar for 3D geometries int aurastr, aurasmoothen; bool fixed_facing; + bool use_wall_radar; int linequality; @@ -3501,6 +3502,9 @@ inline hyperpoint tC0(const transmatrix &T) { transmatrix actualV(const heptspin& hs, const transmatrix& V); transmatrix applyspin(const heptspin& hs, const transmatrix& V); transmatrix cview(); +bool isWall3(cell *c, color_t& wcol); +extern transmatrix actual_view_transform; +ld wall_radar(cell *c, transmatrix T); extern string bitruncnames[5]; extern bool need_mouseh; diff --git a/hypgraph.cpp b/hypgraph.cpp index e422ca4c..6e0119c9 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -1096,14 +1096,11 @@ void centerpc(ld aspd) { if(shmup::on && DIM == 3 && vid.sspeed > -5) { int id = subscreens::in ? subscreens::current_player : 0; - if(false) { // gmatrix.count(shmup::pc[id]->base)) { - transmatrix at = ggmatrix(shmup::pc[id]->base) * shmup::pc[id]->at * cpush(2, -vid.yshift); - View = inverse(at) * View; - } - else { - viewctr = shmup::pc[id]->base->master; - View = inverse(shmup::pc[id]->at * cpush(2, -vid.yshift)); - } + viewctr = shmup::pc[id]->base->master; + transmatrix& T = shmup::pc[id]->at; + View = inverse(T); + if(vid.yshift) View = cpush(2, wall_radar(viewctr.at->c7, T)) * View; + #if CAP_RACING if(racing::on) racing::set_view(); #endif @@ -1123,9 +1120,7 @@ void centerpc(ld aspd) { ors::unrotate(cwtV); ors::unrotate(View); - hyperpoint H = tC0(cwtV); - if(DIM == 2) H = ypush(-vid.yshift) * sphereflip * H; - if(DIM == 3 && !shmup::on && vid.yshift) H = cpush(2, -vid.yshift) * H; + hyperpoint H = inverse(actual_view_transform) * tC0(cwtV); ld R = zero_d(DIM, H) ? 0 : hdist0(H); if(R < 1e-9) { // either already centered or direction unknown