XR: View adjustments for variable viewer scale

This adjusts some calculations and visibility flags for XR viewports in
order to account for a possible scale factor in the XR view matrix.

This scale factor can be introduced via the XR session settings base
scale, which allows a viewer to begin their session at a specific
reference scale, or the XR session state navigation scale, which allows
a viewer to adjust their scale relative to the reference scale during
the session.

Reviewed by Severin as part of D11501, but requested to be committed
separately.
This commit is contained in:
Peter Kim 2021-10-26 13:33:21 +09:00
parent 3434a991ec
commit 7ae2810848
4 changed files with 22 additions and 4 deletions

View File

@ -200,6 +200,15 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
shd->grid_distance = dist / 2.0f;
ED_view3d_grid_steps(scene, v3d, rv3d, shd->grid_steps);
if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) {
/* The calculations for the grid parameters assume that the view matrix has no scale component,
* which may not be correct if the user is "shrunk" or "enlarged" by zooming in or out.
* Therefore, we need to compensate the values here. */
float viewinvscale = len_v3(
viewinv[0]); /* Assumption is uniform scaling (all column vectors are of same length). */
shd->grid_distance *= viewinvscale;
}
}
void OVERLAY_grid_cache_init(OVERLAY_Data *vedata)

View File

@ -1684,10 +1684,12 @@ static void draw_frustum_bound_sphere_calc(const BoundBox *bbox,
bsphere->center[0] = farcenter[0] * z / e;
bsphere->center[1] = farcenter[1] * z / e;
bsphere->center[2] = z;
bsphere->radius = len_v3v3(bsphere->center, farpoint);
/* Transform to world space. */
mul_m4_v3(viewinv, bsphere->center);
/* For XR, the view matrix may contain a scale factor. Then, transforming only the center
* into world space after calculating the radius will result in incorrect behavior. */
mul_m4_v3(viewinv, bsphere->center); /* Transform to world space. */
mul_m4_v3(viewinv, farpoint);
bsphere->radius = len_v3v3(bsphere->center, farpoint);
}
}

View File

@ -347,6 +347,8 @@ static void view3d_xr_mirror_setup(const wmWindowManager *wm,
(wm->xr.session_settings.draw_flags & V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS) !=
0,
V3D_XR_SHOW_CUSTOM_OVERLAYS);
/* Hide navigation gizmo since it gets distorted if the view matrix has a scale factor. */
v3d->gizmo_flag |= V3D_GIZMO_HIDE_NAVIGATE;
/* Reset overridden View3D data. */
v3d->lens = lens_old;

View File

@ -1730,7 +1730,12 @@ void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const S
if (v3d->runtime.flag & V3D_RUNTIME_XR_SESSION_ROOT) {
View3DShading *xr_shading = &wm->xr.session_settings.shading;
/* Flags that shouldn't be overridden by the 3D View shading. */
const int flag_copy = V3D_SHADING_WORLD_ORIENTATION;
int flag_copy = 0;
if (v3d->shading.type !=
OB_SOLID) { /* Don't set V3D_SHADING_WORLD_ORIENTATION for solid shading since it results
in distorted lighting when the view matrix has a scale factor. */
flag_copy |= V3D_SHADING_WORLD_ORIENTATION;
}
BLI_assert(WM_xr_session_exists(&wm->xr));