The open source OpenXR runtime
at main 106 lines 3.7 kB view raw
1// Copyright 2020, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Code to handle distortion parameters and fov. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup aux_distortion 8 */ 9 10#include "xrt/xrt_device.h" 11 12#include "math/m_mathinclude.h" 13 14#include "util/u_misc.h" 15#include "util/u_device.h" 16#include "util/u_distortion.h" 17 18#include <assert.h> 19 20static inline float 21vertical_offset_meters(const struct u_cardboard_distortion_arguments *args) 22{ 23 switch (args->vertical_alignment) { 24 case U_CARDBOARD_VERTICAL_ALIGNMENT_TOP: 25 return args->screen.h_meters - args->tray_to_lens_distance_meters - 0.003f; 26 case U_CARDBOARD_VERTICAL_ALIGNMENT_BOTTOM: return args->tray_to_lens_distance_meters - 0.003f; 27 case U_CARDBOARD_VERTICAL_ALIGNMENT_CENTER: 28 default: return args->screen.h_meters * 0.5f; 29 } 30} 31 32void 33u_distortion_cardboard_calculate(const struct u_cardboard_distortion_arguments *args, 34 struct xrt_hmd_parts *parts, 35 struct u_cardboard_distortion *out_dist) 36{ 37 /* 38 * HMD parts 39 */ 40 41 uint32_t view_count = parts->view_count; 42 43 // Cardboard always has two views 44 assert(view_count == 2); 45 46 uint32_t w_pixels = args->screen.w_pixels / view_count; 47 uint32_t h_pixels = args->screen.h_pixels; 48 49 // Base assumption, the driver can change afterwards. 50 if (parts->blend_mode_count == 0) { 51 size_t idx = 0; 52 parts->blend_modes[idx++] = XRT_BLEND_MODE_OPAQUE; 53 parts->blend_mode_count = idx; 54 } 55 56 // Use the full screen. 57 parts->screens[0].w_pixels = args->screen.w_pixels; 58 parts->screens[0].h_pixels = args->screen.h_pixels; 59 60 // Copy the arguments. 61 out_dist->args = *args; 62 63 // Save the results. 64 for (uint32_t i = 0; i < view_count; ++i) { 65 parts->views[i].viewport.x_pixels = 0 + i * w_pixels; 66 parts->views[i].viewport.y_pixels = 0; 67 parts->views[i].viewport.w_pixels = w_pixels; 68 parts->views[i].viewport.h_pixels = h_pixels; 69 parts->views[i].display.w_pixels = w_pixels; 70 parts->views[i].display.h_pixels = h_pixels; 71 parts->views[i].rot = u_device_rotation_ident; 72 parts->distortion.fov[i] = args->fov; 73 74 struct u_cardboard_distortion_values *values = &out_dist->values[i]; 75 values->distortion_k[0] = args->distortion_k[0]; 76 values->distortion_k[1] = args->distortion_k[1]; 77 values->distortion_k[2] = args->distortion_k[2]; 78 values->distortion_k[3] = args->distortion_k[3]; 79 values->distortion_k[4] = args->distortion_k[4]; 80 81 // Divide by view count since each view takes a part of the screen on the X axis 82 values->screen.size.x = args->screen.w_meters / args->screen_to_lens_distance_meters; 83 values->screen.size.y = args->screen.h_meters / args->screen_to_lens_distance_meters; 84 85 if (i == 0) { 86 values->screen.offset.x = ((args->screen.w_meters - args->inter_lens_distance_meters) / 2) / 87 args->screen_to_lens_distance_meters; 88 } else if (i == 1) { 89 values->screen.offset.x = ((args->screen.w_meters + args->inter_lens_distance_meters) / 2) / 90 args->screen_to_lens_distance_meters; 91 } 92 93 // Cardboard vertical alignment 94 values->screen.offset.y = vertical_offset_meters(args) / args->screen_to_lens_distance_meters; 95 96 // Tanangle to texture coordinates 97 values->texture.size.x = tanf(-args->fov.angle_left) + tanf(args->fov.angle_right); 98 values->texture.size.y = tanf(args->fov.angle_up) + tanf(-args->fov.angle_down); 99 values->texture.offset.x = tanf(-args->fov.angle_left); 100 values->texture.offset.y = tanf(-args->fov.angle_down); 101 102 // Fix up views not covering the entire screen. 103 values->screen.size.x /= view_count; 104 values->screen.offset.x -= values->screen.size.x * i; 105 } 106}