mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-02 12:19:18 +00:00
frustum culling in VR
This commit is contained in:
parent
26b53f0db7
commit
16143f3c9f
112
graph.cpp
112
graph.cpp
@ -3730,64 +3730,108 @@ EX ld mousedist(shiftmatrix T) {
|
|||||||
return sqhypot_d(2, h1) + (point_behind(T1) ? 1e10 : 0);
|
return sqhypot_d(2, h1) + (point_behind(T1) ? 1e10 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<hyperpoint> clipping_planes;
|
vector<vector<hyperpoint>> clipping_plane_sets;
|
||||||
EX int noclipped;
|
EX int noclipped;
|
||||||
|
|
||||||
EX bool frustum_culling = true;
|
EX bool frustum_culling = true;
|
||||||
|
|
||||||
|
EX ld threshold, xyz_threshold;
|
||||||
|
|
||||||
|
EX bool clip_checked = false;
|
||||||
|
|
||||||
void make_clipping_planes() {
|
void make_clipping_planes() {
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
clipping_planes.clear();
|
clip_checked = false;
|
||||||
if(!frustum_culling || PIU(sphere) || experimental || vid.stereo_mode == sODS || panini_alpha) return;
|
if(!frustum_culling || PIU(sphere) || experimental || vid.stereo_mode == sODS || panini_alpha) return;
|
||||||
#if CAP_VR
|
|
||||||
if(vrhr::active()) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto add_clipping_plane = [] (ld x1, ld y1, ld x2, ld y2) {
|
if(WDIM == 3 && pmodel == mdPerspective && !nonisotropic && !in_s2xe())
|
||||||
|
threshold = sin_auto(cgi.corner_bonus), xyz_threshold = 0, clip_checked = true;
|
||||||
|
else if(pmodel == mdGeodesic && sn::in())
|
||||||
|
threshold = .6, xyz_threshold = 3, clip_checked = true;
|
||||||
|
else if(pmodel == mdGeodesic && nil)
|
||||||
|
threshold = 2, xyz_threshold = 3, clip_checked = true;
|
||||||
|
else return;
|
||||||
|
|
||||||
|
clipping_plane_sets.clear();
|
||||||
|
|
||||||
|
auto add_clipping_plane_txy = [] (transmatrix T, const transmatrix& nlp, ld x1, ld y1, ld x2, ld y2) {
|
||||||
ld z1 = 1, z2 = 1;
|
ld z1 = 1, z2 = 1;
|
||||||
hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1);
|
hyperpoint sx = point3(y1 * z2 - y2 * z1, z1 * x2 - z2 * x1, x1 * y2 - x2 * y1);
|
||||||
sx /= hypot_d(3, sx);
|
sx /= hypot_d(3, sx);
|
||||||
sx[3] = 0;
|
sx[3] = 0;
|
||||||
if(nisot::local_perspective_used()) sx = ortho_inverse(NLP) * sx;
|
sx = T * sx;
|
||||||
clipping_planes.push_back(sx);
|
if(nisot::local_perspective_used()) sx = ortho_inverse(nlp) * sx;
|
||||||
|
clipping_plane_sets.back().push_back(sx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto add_clipping_plane_proj = [&] (transmatrix T, const transmatrix& nlp, const transmatrix& iproj, ld x1, ld y1, ld x2, ld y2) {
|
||||||
|
hyperpoint h1 = iproj * point31(x1, y1, .5);
|
||||||
|
hyperpoint h2 = iproj * point31(x2, y2, .5);
|
||||||
|
h1 /= h1[2]; h2 /= h2[2];
|
||||||
|
add_clipping_plane_txy(T, nlp, h1[0], h1[1], h2[0], h2[1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto clipping_planes_screen = [&] (const transmatrix& T, const transmatrix& nlp) {
|
||||||
ld tx = current_display->tanfov;
|
ld tx = current_display->tanfov;
|
||||||
ld ty = tx * current_display->ysize / current_display->xsize;
|
ld ty = tx * current_display->ysize / current_display->xsize;
|
||||||
add_clipping_plane(+tx, +ty, -tx, +ty);
|
clipping_plane_sets.push_back({});
|
||||||
add_clipping_plane(-tx, +ty, -tx, -ty);
|
add_clipping_plane_txy(T, nlp, +tx, +ty, -tx, +ty);
|
||||||
add_clipping_plane(-tx, -ty, +tx, -ty);
|
add_clipping_plane_txy(T, nlp, -tx, +ty, -tx, -ty);
|
||||||
add_clipping_plane(+tx, -ty, +tx, +ty);
|
add_clipping_plane_txy(T, nlp, -tx, -ty, +tx, -ty);
|
||||||
|
add_clipping_plane_txy(T, nlp, +tx, -ty, +tx, +ty);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool stdview = true;
|
||||||
|
|
||||||
|
#if CAP_VR
|
||||||
|
if(vrhr::active()) {
|
||||||
|
for(auto p: vrhr::frusta) {
|
||||||
|
if(p.screen)
|
||||||
|
clipping_planes_screen(inverse(p.pre), p.nlp);
|
||||||
|
else {
|
||||||
|
auto iproj = inverse(p.proj);
|
||||||
|
auto ipre = inverse(p.pre);
|
||||||
|
clipping_plane_sets.push_back({});
|
||||||
|
add_clipping_plane_proj(ipre, p.nlp, iproj, 1, 1, 0, 1);
|
||||||
|
add_clipping_plane_proj(ipre, p.nlp, iproj, 0, 1, 0, 0);
|
||||||
|
add_clipping_plane_proj(ipre, p.nlp, iproj, 0, 0, 1, 0);
|
||||||
|
add_clipping_plane_proj(ipre, p.nlp, iproj, 1, 0, 1, 1);
|
||||||
|
}
|
||||||
|
stdview = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(stdview) clipping_planes_screen(Id, NLP);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool clipped_by(const hyperpoint& H, const vector<hyperpoint>& v) {
|
||||||
|
for(auto& cpoint: v) if((H|cpoint) < -threshold) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool clipped_by(const hyperpoint& H, const vector<vector<hyperpoint>>& vv) {
|
||||||
|
for(auto& cps: vv) if(!clipped_by(H, cps)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool celldrawer::cell_clipped() {
|
bool celldrawer::cell_clipped() {
|
||||||
if(WDIM == 3 && pmodel == mdPerspective && !nonisotropic && !in_s2xe()) {
|
|
||||||
|
if(!clip_checked) return false;
|
||||||
|
|
||||||
hyperpoint H = unshift(tC0(V));
|
hyperpoint H = unshift(tC0(V));
|
||||||
if(prod) H = product::inverse_exp(H);
|
|
||||||
for(hyperpoint& cpoint: clipping_planes) if((H|cpoint) < -sin_auto(cgi.corner_bonus)) {
|
if(xyz_threshold && abs(H[0]) <= xyz_threshold && abs(H[1]) <= xyz_threshold && abs(H[2]) <= xyz_threshold) {
|
||||||
|
noclipped++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(clipped_by(H, clipping_plane_sets)) {
|
||||||
drawcell_in_radar();
|
drawcell_in_radar();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
noclipped++;
|
noclipped++;
|
||||||
}
|
|
||||||
if(pmodel == mdGeodesic && sn::in()) {
|
|
||||||
hyperpoint H = unshift(tC0(V));
|
|
||||||
if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ;
|
|
||||||
else {
|
|
||||||
hyperpoint H2 = inverse_exp(shiftless(H), pQUICK);
|
|
||||||
for(hyperpoint& cpoint: clipping_planes) if((H2|cpoint) < -.6) return true;
|
|
||||||
}
|
|
||||||
noclipped++;
|
|
||||||
}
|
|
||||||
if(pmodel == mdGeodesic && nil) {
|
|
||||||
hyperpoint H = unshift(tC0(V));
|
|
||||||
if(abs(H[0]) <= 3 && abs(H[1]) <= 3 && abs(H[2]) <= 3 ) ;
|
|
||||||
else {
|
|
||||||
hyperpoint H2 = inverse_exp(shiftless(H), pQUICK);
|
|
||||||
for(hyperpoint& cpoint: clipping_planes) if((H2|cpoint) < -2) return true;
|
|
||||||
}
|
|
||||||
noclipped++;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
vr.cpp
17
vr.cpp
@ -236,6 +236,17 @@ EX int ui_xmin, ui_ymin, ui_xmax, ui_ymax;
|
|||||||
|
|
||||||
EX reaction_t change_ui_bounds;
|
EX reaction_t change_ui_bounds;
|
||||||
|
|
||||||
|
#if HDR
|
||||||
|
struct frustum_info {
|
||||||
|
transmatrix pre;
|
||||||
|
transmatrix nlp;
|
||||||
|
bool screen;
|
||||||
|
transmatrix proj;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EX vector<frustum_info> frusta;
|
||||||
|
|
||||||
EX void set_ui_bounds() {
|
EX void set_ui_bounds() {
|
||||||
ui_xmin = 0;
|
ui_xmin = 0;
|
||||||
ui_ymin = 0;
|
ui_ymin = 0;
|
||||||
@ -1011,6 +1022,7 @@ EX void render() {
|
|||||||
track_poses();
|
track_poses();
|
||||||
resetbuffer rb;
|
resetbuffer rb;
|
||||||
state = 2;
|
state = 2;
|
||||||
|
vrhr::frusta.clear();
|
||||||
|
|
||||||
// cscr = lshiftclick ? eCompScreen::eyes : eCompScreen::single;
|
// cscr = lshiftclick ? eCompScreen::eyes : eCompScreen::single;
|
||||||
|
|
||||||
@ -1042,6 +1054,11 @@ EX void render() {
|
|||||||
hmd_pre = hmd_pre_for[i] = cview().T * inverse(master_cview.T);
|
hmd_pre = hmd_pre_for[i] = cview().T * inverse(master_cview.T);
|
||||||
radar_transform = trt.backup * inverse(hmd_pre);
|
radar_transform = trt.backup * inverse(hmd_pre);
|
||||||
|
|
||||||
|
if(i < 2)
|
||||||
|
frusta.push_back(frustum_info{hmd_pre, NLP, false, vrdata.proj[i]});
|
||||||
|
else
|
||||||
|
frusta.push_back(frustum_info{hmd_pre, NLP, true, Id});
|
||||||
|
|
||||||
if(1) {
|
if(1) {
|
||||||
gen_mv();
|
gen_mv();
|
||||||
E4;
|
E4;
|
||||||
|
Loading…
Reference in New Issue
Block a user