The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

u/distortion: Add simple cardboard distortion code

+327 -13
+2
src/xrt/auxiliary/CMakeLists.txt
··· 95 95 util/u_debug.h 96 96 util/u_device.c 97 97 util/u_device.h 98 + util/u_distortion.c 99 + util/u_distortion.h 98 100 util/u_distortion_mesh.c 99 101 util/u_distortion_mesh.h 100 102 util/u_documentation.h
+2
src/xrt/auxiliary/meson.build
··· 18 18 'util/u_debug.h', 19 19 'util/u_device.c', 20 20 'util/u_device.h', 21 + 'util/u_distortion.c', 22 + 'util/u_distortion.h', 21 23 'util/u_distortion_mesh.c', 22 24 'util/u_distortion_mesh.h', 23 25 'util/u_documentation.h',
+136
src/xrt/auxiliary/util/u_distortion.c
··· 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 + 19 + void 20 + u_distortion_cardboard_calculate( 21 + const struct u_cardboard_distortion_arguments *args, 22 + struct xrt_hmd_parts *parts, 23 + struct u_cardboard_distortion *out_dist) 24 + { 25 + /* 26 + * HMD parts 27 + */ 28 + 29 + uint32_t w_pixels = args->screen.w_pixels / 2; 30 + uint32_t h_pixels = args->screen.h_pixels; 31 + 32 + // Use the full screen. 33 + parts->screens[0].w_pixels = args->screen.w_pixels; 34 + parts->screens[0].h_pixels = args->screen.h_pixels; 35 + 36 + parts->views[0].viewport.x_pixels = 0; 37 + parts->views[0].viewport.y_pixels = 0; 38 + parts->views[0].viewport.w_pixels = w_pixels; 39 + parts->views[0].viewport.h_pixels = h_pixels; 40 + parts->views[0].display.w_pixels = w_pixels; 41 + parts->views[0].display.h_pixels = h_pixels; 42 + parts->views[0].rot = u_device_rotation_ident; 43 + parts->views[0].fov = args->fov; 44 + 45 + parts->views[1].viewport.x_pixels = w_pixels; 46 + parts->views[1].viewport.y_pixels = 0; 47 + parts->views[1].viewport.w_pixels = w_pixels; 48 + parts->views[1].viewport.h_pixels = h_pixels; 49 + parts->views[1].display.w_pixels = w_pixels; 50 + parts->views[1].display.h_pixels = h_pixels; 51 + parts->views[1].rot = u_device_rotation_ident; 52 + parts->views[1].fov = args->fov; 53 + 54 + 55 + /* 56 + * Left values 57 + */ 58 + 59 + // clang-format off 60 + struct u_cardboard_distortion_values l_values = {0}; 61 + l_values.distortion_k[0] = args->distortion_k[0]; 62 + l_values.distortion_k[1] = args->distortion_k[1]; 63 + l_values.distortion_k[2] = args->distortion_k[2]; 64 + l_values.distortion_k[3] = args->distortion_k[3]; 65 + l_values.distortion_k[4] = args->distortion_k[4]; 66 + l_values.screen.size.x = args->screen.w_meters; 67 + l_values.screen.size.y = args->screen.h_meters; 68 + l_values.screen.offset.x = (args->screen.w_meters - args->inter_lens_distance_meters) / 2.0; 69 + l_values.screen.offset.y = args->lens_y_center_on_screen_meters; 70 + // clang-format on 71 + 72 + // Turn into tanangles 73 + l_values.screen.size.x /= args->screen_to_lens_distance_meters; 74 + l_values.screen.size.y /= args->screen_to_lens_distance_meters; 75 + l_values.screen.offset.x /= args->screen_to_lens_distance_meters; 76 + l_values.screen.offset.y /= args->screen_to_lens_distance_meters; 77 + 78 + // Tan-angle to texture coordinates 79 + // clang-format off 80 + l_values.texture.size.x = tan(-args->fov.angle_left) + tan(args->fov.angle_right); 81 + l_values.texture.size.y = tan(args->fov.angle_up) + tan(-args->fov.angle_down); 82 + l_values.texture.offset.x = tan(-args->fov.angle_left); 83 + l_values.texture.offset.y = tan(-args->fov.angle_down); 84 + // clang-format on 85 + 86 + // Fix up views not covering the entire screen. 87 + l_values.screen.size.x /= 2.0; 88 + 89 + 90 + /* 91 + * Right values 92 + */ 93 + 94 + // clang-format off 95 + struct u_cardboard_distortion_values r_values = {0}; 96 + r_values.distortion_k[0] = args->distortion_k[0]; 97 + r_values.distortion_k[1] = args->distortion_k[1]; 98 + r_values.distortion_k[2] = args->distortion_k[2]; 99 + r_values.distortion_k[3] = args->distortion_k[3]; 100 + r_values.distortion_k[4] = args->distortion_k[4]; 101 + r_values.screen.size.x = args->screen.w_meters; 102 + r_values.screen.size.y = args->screen.h_meters; 103 + r_values.screen.offset.x = (args->screen.w_meters + args->inter_lens_distance_meters) / 2.0; 104 + r_values.screen.offset.y = args->lens_y_center_on_screen_meters; 105 + // clang-format on 106 + 107 + // Turn into tanangles 108 + r_values.screen.size.x /= args->screen_to_lens_distance_meters; 109 + r_values.screen.size.y /= args->screen_to_lens_distance_meters; 110 + r_values.screen.offset.x /= args->screen_to_lens_distance_meters; 111 + r_values.screen.offset.y /= args->screen_to_lens_distance_meters; 112 + 113 + // Tanangle to texture coordinates 114 + // clang-format off 115 + r_values.texture.size.x = tan(-args->fov.angle_left) + tan(args->fov.angle_right); 116 + r_values.texture.size.y = tan(args->fov.angle_up) + tan(-args->fov.angle_down); 117 + r_values.texture.offset.x = tan(-args->fov.angle_left); 118 + r_values.texture.offset.y = tan(-args->fov.angle_down); 119 + // clang-format on 120 + 121 + // Fix up views not covering the entire screen. 122 + r_values.screen.size.x /= 2.0; 123 + r_values.screen.offset.x -= r_values.screen.size.x; 124 + 125 + 126 + /* 127 + * Write results. 128 + */ 129 + 130 + // Copy the arguments. 131 + out_dist->args = *args; 132 + 133 + // Save the results. 134 + out_dist->values[0] = l_values; 135 + out_dist->values[1] = r_values; 136 + }
+112
src/xrt/auxiliary/util/u_distortion.h
··· 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 + #pragma once 11 + 12 + #include "xrt/xrt_defines.h" 13 + 14 + 15 + #ifdef __cplusplus 16 + extern "C" { 17 + #endif 18 + 19 + 20 + struct xrt_hmd_parts; 21 + 22 + /*! 23 + * @defgroup aux_distortion Distortion utilities. 24 + * @ingroup aux_util 25 + */ 26 + 27 + /*! 28 + * These are the values that you need to supply to the distortion code to setup 29 + * a @ref u_cardboard_distortion properly. 30 + * 31 + * @ingroup aux_distortion 32 + */ 33 + struct u_cardboard_distortion_arguments 34 + { 35 + float distortion_k[5]; 36 + 37 + struct 38 + { 39 + uint32_t w_pixels, h_pixels; 40 + float w_meters, h_meters; 41 + } screen; 42 + 43 + //! Distances between the lenses in meters. 44 + float inter_lens_distance_meters; 45 + 46 + //! Where on the y axis the center of the lens is on the screen. 47 + float lens_y_center_on_screen_meters; 48 + 49 + /*! 50 + * The distance to the lens from the screen, used to calculate calculate 51 + * tanangle of various distances on the screen. 52 + */ 53 + float screen_to_lens_distance_meters; 54 + 55 + //! Fov values that the cardboard configuration has given us. 56 + struct xrt_fov fov; 57 + }; 58 + 59 + /*! 60 + * Values to create a distortion mesh from cardboard values. 61 + * 62 + * This matches the formula in the cardboard SDK, while the array is fixed size 63 + * just setting the K value to zero will make it not have a effect. 64 + * 65 + * p' = p (1 + K0 r^2 + K1 r^4 + ... + Kn r^(2n)) 66 + * 67 + * @ingroup aux_distortion 68 + */ 69 + struct u_cardboard_distortion_values 70 + { 71 + //! Cardboard distortion k values. 72 + float distortion_k[5]; 73 + 74 + struct 75 + { 76 + //! Used to transform to and from tanangle space. 77 + struct xrt_vec2 size; 78 + //! Used to transform to and from tanangle space. 79 + struct xrt_vec2 offset; 80 + } screen, texture; 81 + }; 82 + 83 + /*! 84 + * Both given and derived values needed for cardboard distortion. 85 + * 86 + * @ingroup aux_distortion 87 + */ 88 + struct u_cardboard_distortion 89 + { 90 + //! Arguments this distortion was created from. 91 + struct u_cardboard_distortion_arguments args; 92 + 93 + //! Distortion parameters, some derived from @ref args. 94 + struct u_cardboard_distortion_values values[2]; 95 + }; 96 + 97 + /*! 98 + * Take cardboard arguments to turn them into a @ref u_cardboard_distortion and 99 + * fill out a @ref xrt_hmd_parts struct. 100 + * 101 + * @ingroup aux_distortion 102 + */ 103 + void 104 + u_distortion_cardboard_calculate( 105 + const struct u_cardboard_distortion_arguments *args, 106 + struct xrt_hmd_parts *parts, 107 + struct u_cardboard_distortion *out_dist); 108 + 109 + 110 + #ifdef __cplusplus 111 + } 112 + #endif
+38 -1
src/xrt/auxiliary/util/u_distortion_mesh.c
··· 4 4 * @file 5 5 * @brief Code to generate disortion meshes. 6 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 - * @ingroup aux_util 7 + * @ingroup aux_distortion 8 8 */ 9 9 10 10 #include "util/u_misc.h" ··· 190 190 #define div m_vec2_div 191 191 #define div_scalar m_vec2_div_scalar 192 192 #define len m_vec2_len 193 + #define len_sqrd m_vec2_len_sqrd 193 194 194 195 bool 195 196 u_compute_distortion_panotools(struct u_panotools_values *values, ··· 229 230 result->r = r_uv; 230 231 result->g = g_uv; 231 232 result->b = b_uv; 233 + return true; 234 + } 235 + 236 + bool 237 + u_compute_distortion_cardboard(struct u_cardboard_distortion_values *values, 238 + float u, 239 + float v, 240 + struct xrt_uv_triplet *result) 241 + { 242 + struct xrt_vec2 uv = {u, v}; 243 + uv = sub(mul(uv, values->screen.size), values->screen.offset); 244 + 245 + float sqrd = len_sqrd(uv); 246 + float r = 1.0f; 247 + float fact = 1.0f; 248 + r *= sqrd; 249 + fact += values->distortion_k[0] * r; 250 + r *= sqrd; 251 + fact += values->distortion_k[1] * r; 252 + r *= sqrd; 253 + fact += values->distortion_k[2] * r; 254 + r *= sqrd; 255 + fact += values->distortion_k[3] * r; 256 + r *= sqrd; 257 + fact += values->distortion_k[4] * r; 258 + 259 + uv = mul_scalar(uv, fact); 260 + 261 + uv = div(add(uv, values->texture.offset), values->texture.size); 262 + 263 + result->r.x = uv.x; 264 + result->r.y = uv.y; 265 + result->g.x = uv.x; 266 + result->g.y = uv.y; 267 + result->b.x = uv.x; 268 + result->b.y = uv.y; 232 269 return true; 233 270 } 234 271
+37 -12
src/xrt/auxiliary/util/u_distortion_mesh.h
··· 4 4 * @file 5 5 * @brief Code to generate disortion meshes. 6 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 - * @ingroup aux_util 7 + * @ingroup aux_distortion 8 8 */ 9 9 10 10 #pragma once ··· 12 12 #include "xrt/xrt_device.h" 13 13 #include "xrt/xrt_defines.h" 14 14 15 + #include "util/u_distortion.h" 16 + 17 + 15 18 #ifdef __cplusplus 16 19 extern "C" { 17 20 #endif 18 21 19 22 20 - /*! 21 - * @ingroup aux_util 22 - * @{ 23 - */ 24 - 25 23 /* 26 24 * 27 25 * Panotools distortion ··· 30 28 31 29 /*! 32 30 * Values to create a distortion mesh from panotools values. 31 + * 32 + * @ingroup aux_distortion 33 33 */ 34 34 struct u_panotools_values 35 35 { ··· 47 47 48 48 /*! 49 49 * Distortion correction implementation for Panotools distortion values. 50 + * 51 + * @ingroup aux_distortion 50 52 */ 51 53 bool 52 54 u_compute_distortion_panotools(struct u_panotools_values *values, ··· 63 65 64 66 /*! 65 67 * Values to create a distortion mesh from Vive configuration values. 68 + * 69 + * @ingroup aux_distortion 66 70 */ 67 71 struct u_vive_values 68 72 { ··· 82 86 /*! 83 87 * Distortion correction implementation for the Vive, Vive Pro, Valve Index 84 88 * distortion values found in the HMD configuration. 89 + * 90 + * @ingroup aux_distortion 85 91 */ 86 92 bool 87 93 u_compute_distortion_vive(struct u_vive_values *values, ··· 92 98 93 99 /* 94 100 * 101 + * Cardboard mesh distortion parameters. 102 + * 103 + */ 104 + 105 + /*! 106 + * Distortion correction implementation for the Cardboard devices. 107 + * 108 + * @ingroup aux_distortion 109 + */ 110 + bool 111 + u_compute_distortion_cardboard(struct u_cardboard_distortion_values *values, 112 + float u, 113 + float v, 114 + struct xrt_uv_triplet *result); 115 + 116 + 117 + /* 118 + * 95 119 * None distortion 96 120 * 97 121 */ 98 122 99 123 /*! 100 124 * Identity distortion correction sets all result coordinates to u,v. 125 + * 126 + * @ingroup aux_distortion 101 127 */ 102 128 bool 103 129 u_compute_distortion_none(float u, float v, struct xrt_uv_triplet *result); 104 130 105 131 /*! 106 132 * Helper function for none distortion devices. 133 + * 134 + * @ingroup aux_distortion 107 135 */ 108 136 bool 109 137 u_distortion_mesh_none(struct xrt_device *xdev, ··· 124 152 * xdev->compute_distortion(), populates `xdev->hmd_parts.distortion.mesh` & 125 153 * `xdev->hmd_parts.distortion.models`. 126 154 * 127 - * @ingroup aux_util 128 155 * @relatesalso xrt_device 156 + * @ingroup aux_distortion 129 157 */ 130 158 void 131 159 u_distortion_mesh_fill_in_compute(struct xrt_device *xdev); ··· 135 163 * `xdev->hmd_parts.distortion.mesh` & `xdev->hmd_parts.distortion.models`. 136 164 * 137 165 * @relatesalso xrt_device 166 + * @ingroup aux_distortion 138 167 */ 139 168 void 140 169 u_distortion_mesh_fill_in_none(struct xrt_device *xdev); ··· 145 174 * & `xdev->hmd_parts.distortion.models`. 146 175 * 147 176 * @relatesalso xrt_device 177 + * @ingroup aux_distortion 148 178 */ 149 179 void 150 180 u_distortion_mesh_set_none(struct xrt_device *xdev); 151 - 152 - 153 - /*! 154 - * @} 155 - */ 156 181 157 182 158 183 #ifdef __cplusplus