diff --git a/src/xrt/auxiliary/util/u_visibility_mask.c b/src/xrt/auxiliary/util/u_visibility_mask.c index 4e77d90d5..611af20bd 100644 --- a/src/xrt/auxiliary/util/u_visibility_mask.c +++ b/src/xrt/auxiliary/util/u_visibility_mask.c @@ -7,10 +7,13 @@ * @ingroup aux_util */ +#include "math/m_mathinclude.h" + #include "u_misc.h" #include "u_visibility_mask.h" #include "u_logging.h" + #include static const struct xrt_vec2 vertices_hidden[] = { @@ -36,7 +39,9 @@ static const struct xrt_vec2 vertices_line[] = { static const uint32_t indices_line[] = {0, 1, 2, 3, 4, 5, 6, 7}; void -u_visibility_mask_get_default(enum xrt_visibility_mask_type type, struct xrt_visibility_mask **out_mask) +u_visibility_mask_get_default(enum xrt_visibility_mask_type type, + const struct xrt_fov *fov, + struct xrt_visibility_mask **out_mask) { struct xrt_visibility_mask *mask = NULL; uint32_t nvertices, nindices; @@ -87,7 +92,32 @@ u_visibility_mask_get_default(enum xrt_visibility_mask_type type, struct xrt_vis } memcpy(xrt_visibility_mask_get_indices(mask), indices, sizeof(uint32_t) * nindices); - memcpy(xrt_visibility_mask_get_vertices(mask), vertices, sizeof(struct xrt_vec2) * nvertices); + + + const struct xrt_fov copy = *fov; + + const double tan_left = tan(copy.angle_left); + const double tan_right = tan(copy.angle_right); + + const double tan_down = tan(copy.angle_down); + const double tan_up = tan(copy.angle_up); + + const double tan_half_width = (tan_right - tan_left); + const double tan_half_height = (tan_up - tan_down); + + const double tan_offset_x = ((tan_right + tan_left) - tan_half_width) / 2; + const double tan_offset_y = (-(tan_up + tan_down) - tan_half_height) / 2; + + struct xrt_vec2 *dst = xrt_visibility_mask_get_vertices(mask); + for (uint32_t i = 0; i < nvertices; i++) { + struct xrt_vec2 v = vertices[i]; + + // Yes this is really the simplest form, WolframAlpha agrees. + v.x = (v.x * 0.5 + 0.5) * tan_half_width + tan_offset_x; + v.y = (v.y * 0.5 + 0.5) * tan_half_height + tan_offset_y; + + dst[i] = v; + } out: *out_mask = mask; // Always NULL or allocated data. diff --git a/src/xrt/auxiliary/util/u_visibility_mask.h b/src/xrt/auxiliary/util/u_visibility_mask.h index e2c09c221..f024061bf 100644 --- a/src/xrt/auxiliary/util/u_visibility_mask.h +++ b/src/xrt/auxiliary/util/u_visibility_mask.h @@ -17,12 +17,17 @@ extern "C" { /*! - * Default visibility mask. The caller must take care of de-allocating the mask once done with it. + * Default visibility mask, only returns a very simple mask with four small + * triangles in each corner, scaled to the given FoV so it matches the OpenXR + * conventions. The caller must take care of de-allocating the mask once done + * with it. * * @ingroup aux_util */ void -u_visibility_mask_get_default(enum xrt_visibility_mask_type type, struct xrt_visibility_mask **out_mask); +u_visibility_mask_get_default(enum xrt_visibility_mask_type type, + const struct xrt_fov *fov, + struct xrt_visibility_mask **out_mask); #ifdef __cplusplus diff --git a/src/xrt/ipc/server/ipc_server_handler.c b/src/xrt/ipc/server/ipc_server_handler.c index 27548cf25..22714e205 100644 --- a/src/xrt/ipc/server/ipc_server_handler.c +++ b/src/xrt/ipc/server/ipc_server_handler.c @@ -1575,7 +1575,8 @@ ipc_handle_device_get_visibility_mask(volatile struct ipc_client_state *ics, if (xdev->get_visibility_mask) { xdev->get_visibility_mask(xdev, type, &mask); } else { - u_visibility_mask_get_default(type, &mask); + struct xrt_fov fov = xdev->hmd->distortion.fov[0]; + u_visibility_mask_get_default(type, &fov, &mask); } if (mask == NULL) {