From eb6d186f00f3083c63362669f981e7492afef1a0 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 27 Dec 2020 17:14:50 +0100 Subject: [PATCH] 2D models in 3D (WIP) --- drawing.cpp | 16 ++++++++++++---- hypgraph.cpp | 46 +++++++++++++++++++++++++++++++++++++--------- models.cpp | 6 +++++- 3 files changed, 54 insertions(+), 14 deletions(-) diff --git a/drawing.cpp b/drawing.cpp index e99e3fb4..3aab0149 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -299,12 +299,12 @@ vector> tofix; EX bool two_sided_model() { if(GDIM == 3) return false; - if(pmodel == mdHyperboloid) return !euclid; + if(pmodel == mdHyperboloid) return !euclid && vrhr::state != 2; // if(pmodel == mdHemisphere) return true; if(pmodel == mdDisk) return sphere; if(pmodel == mdRetroLittrow) return sphere; if(pmodel == mdRetroHammer) return sphere; - if(pmodel == mdHemisphere) return true; + if(pmodel == mdHemisphere) return vrhr::state != 2; if(pmodel == mdRotatedHyperboles) return true; if(pmodel == mdSpiral && pconf.spiral_cone < 360) return true; return false; @@ -357,7 +357,10 @@ void fixpoint(glvertex& hscr, hyperpoint H) { } hyperpoint Hscr; applymodel(shiftless(good), Hscr); - hscr = glhr::makevertex(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*pconf.stretch, Hscr[2]*current_display->radius); + if(vrhr::state == 2) + hscr = glhr::makevertex(Hscr[0], Hscr[1]*pconf.stretch, Hscr[2]); + else + hscr = glhr::makevertex(Hscr[0]*current_display->radius, Hscr[1]*current_display->radius*pconf.stretch, Hscr[2]*current_display->radius); } void addpoint(const shiftpoint& H) { @@ -365,6 +368,8 @@ void addpoint(const shiftpoint& H) { ld z = current_display->radius; // if(pconf.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND; + if(vrhr::state == 2) z = 1; + if(spherespecial) { auto H0 = H.h; if(correct_side(H0)) { @@ -405,7 +410,10 @@ void addpoint(const shiftpoint& H) { } Hlast = Hscr; } - if(GDIM == 2) { + if(vrhr::state == 2) { + for(int i=0; i<3; i++) Hscr[i] *= z; + } + else if(GDIM == 2) { for(int i=0; i<3; i++) Hscr[i] *= z; Hscr[1] *= pconf.stretch; } diff --git a/hypgraph.cpp b/hypgraph.cpp index 6889457f..c4072f9d 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -147,11 +147,15 @@ void ballmodel(hyperpoint& ret, double alpha, double d, double zl) { models::apply_ball(ret[2], ret[1]); } +bool use_z_coordinate() { + return vrhr::state == 2 || current_display->stereo_active(); + } + void apply_depth(hyperpoint &f, ld z) { if(vid.usingGL) - f[2] = z; + f[2] = z * pconf.depth_scaling; else { - z = z * current_display->radius; + z = z * current_display->radius * pconf.depth_scaling; ld mul = current_display->radius / (current_display->radius + z); f[0] = f[0] * mul; f[1] = f[1] * mul; @@ -245,7 +249,7 @@ template void makeband(shiftpoint H, hyperpoint& ret, const T& f) { move_y_to_z(ret, r); models::apply_orientation(ret[1], ret[0]); models::apply_orientation_yz(ret[2], ret[1]); - if(zlev != 1 && current_display->stereo_active()) + if(zlev != 1 && use_z_coordinate()) apply_depth(ret, yzf / M_PI); return; } @@ -488,19 +492,22 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) { H *= pconf.halfplane_scale; ret[0] = -models::osin - H[0]; + ld height = 0; if(zlev != 1) { if(abs(models::ocos) > 1e-5) - H[1] = H[1] * pow(zlev, models::ocos); + height += H[1] * (pow(zlev, models::ocos) - 1); if(abs(models::ocos) > 1e-5 && models::osin) - H[1] += H[0] * models::osin * (pow(zlev, models::ocos) - 1) / models::ocos; + height += H[0] * models::osin * (pow(zlev, models::ocos) - 1) / models::ocos; else if(models::osin) - H[1] += H[0] * models::osin * log(zlev); + height += H[0] * models::osin * log(zlev); } ret[1] = models::ocos + H[1]; ret[2] = GDIM == 3 ? H[2] : 0; if(MAXMDIM == 4) ret[3] = 1; - if(zlev != 1 && current_display->stereo_active()) - apply_depth(ret, -H[1] * geom3::factor_to_lev(zlev)); + if(zlev != 1 && use_z_coordinate()) + apply_depth(ret, height); + else + ret[1] += height * pconf.depth_scaling; break; } @@ -603,6 +610,11 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) { ld zl = zlevel(H); ret = H / H[2]; ret[2] = sqrt(1 - sqhypot_d(2, ret)); + if(vrhr::state == 2) { + ret = ret * (1 + (1 - zl) * ret[2] * pconf.depth_scaling); + models::apply_vr(ret[2], ret[1]); + return; + } ret = ret * (1 + (zl - 1) * ret[2]); break; } @@ -646,6 +658,19 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) { ret = H; break; } + + if(vrhr::state == 2) { + ret[0] = H[0] * pconf.hyperboloid_scaling; + ret[1] = H[1] * pconf.hyperboloid_scaling; + ret[2] = (pconf.alpha + H[2]); + if(pconf.depth_scaling != 1) { + ld v = intval(H, Hypc); + ret *= pow(v, (pconf.depth.scaling-1) / 2); + } + models::apply_vr(ret[2], ret[1]); + break; + } + if(pmodel == mdHyperboloid) { ld& topz = pconf.top_z; if(H[2] > topz) { @@ -991,7 +1016,7 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) { ret = H * (d * df / rad / M_PI); if(GDIM == 2) ret[2] = 0; if(MAXMDIM == 4) ret[3] = 1; - if(zlev != 1 && current_display->stereo_active()) + if(zlev != 1 && use_z_coordinate()) apply_depth(ret, d * zf / M_PI); break; @@ -1994,6 +2019,8 @@ EX color_t modelcolor = 0; #if CAP_QUEUE EX void draw_model_elements() { + if(vrhr::state && pmodel == mdHyperboloid) return; + dynamicval lw(vid.linewidth, vid.linewidth * vid.multiplier_ring); switch(pmodel) { @@ -2127,6 +2154,7 @@ EX void draw_boundary(int w) { if(w == 1) return; if(nonisotropic || euclid || prod) return; + if(vrhr::state && pmodel == mdHyperboloid) return; dynamicval lw(vid.linewidth, vid.linewidth * vid.multiplier_ring); diff --git a/models.cpp b/models.cpp index ca56dfa4..5a081e8e 100644 --- a/models.cpp +++ b/models.cpp @@ -120,7 +120,7 @@ EX namespace models { EX ld rotation_xy2 = 90; EX int do_rotate = 1; EX ld ocos, osin, ocos_yz, osin_yz; - EX ld cos_ball, sin_ball; + EX ld cos_ball, sin_ball, cos_vr, sin_vr; EX bool model_straight, model_straight_yz; #if HDR @@ -132,6 +132,8 @@ EX namespace models { void apply_orientation_yz(A& x, A& y) { if(!model_straight_yz) tie(x,y) = make_pair(x*ocos_yz + y*osin_yz, y*ocos_yz - x*osin_yz); } template void apply_ball(A& x, A& y) { tie(x,y) = make_pair(x*cos_ball + y*sin_ball, y*cos_ball - x*sin_ball); } + template + void apply_vr(A& x, A& y) { tie(x,y) = make_pair(x*cos_vr + y*sin_vr, y*cos_vr - x*sin_vr); } #endif EX transmatrix rotmatrix() { @@ -151,6 +153,8 @@ EX namespace models { EX void configure() { ld ball = -pconf.ballangle * degree; cos_ball = cos(ball), sin_ball = sin(ball); + ld vr = -pconf.vr_angle * degree; + cos_vr = cos(vr), sin_vr = sin(vr); ocos = cos(pconf.model_orientation * degree); osin = sin(pconf.model_orientation * degree); ocos_yz = cos(pconf.model_orientation_yz * degree);