a/util: Make distortion utils compatible with view count equal to 1.

This commit is contained in:
Meng Jiao 2024-02-07 16:51:29 +08:00
parent 95331593e2
commit 105577730f
3 changed files with 58 additions and 111 deletions

View file

@ -25,7 +25,9 @@ u_distortion_cardboard_calculate(const struct u_cardboard_distortion_arguments *
* HMD parts
*/
uint32_t w_pixels = args->screen.w_pixels / 2;
uint32_t view_count = parts->view_count;
uint32_t w_pixels = args->screen.w_pixels / view_count;
uint32_t h_pixels = args->screen.h_pixels;
// Base assumption, the driver can change afterwards.
@ -39,104 +41,47 @@ u_distortion_cardboard_calculate(const struct u_cardboard_distortion_arguments *
parts->screens[0].w_pixels = args->screen.w_pixels;
parts->screens[0].h_pixels = args->screen.h_pixels;
parts->views[0].viewport.x_pixels = 0;
parts->views[0].viewport.y_pixels = 0;
parts->views[0].viewport.w_pixels = w_pixels;
parts->views[0].viewport.h_pixels = h_pixels;
parts->views[0].display.w_pixels = w_pixels;
parts->views[0].display.h_pixels = h_pixels;
parts->views[0].rot = u_device_rotation_ident;
parts->distortion.fov[0] = args->fov;
parts->views[1].viewport.x_pixels = w_pixels;
parts->views[1].viewport.y_pixels = 0;
parts->views[1].viewport.w_pixels = w_pixels;
parts->views[1].viewport.h_pixels = h_pixels;
parts->views[1].display.w_pixels = w_pixels;
parts->views[1].display.h_pixels = h_pixels;
parts->views[1].rot = u_device_rotation_ident;
parts->distortion.fov[1] = args->fov;
/*
* Left values
*/
// clang-format off
struct u_cardboard_distortion_values l_values = {0};
l_values.distortion_k[0] = args->distortion_k[0];
l_values.distortion_k[1] = args->distortion_k[1];
l_values.distortion_k[2] = args->distortion_k[2];
l_values.distortion_k[3] = args->distortion_k[3];
l_values.distortion_k[4] = args->distortion_k[4];
l_values.screen.size.x = args->screen.w_meters;
l_values.screen.size.y = args->screen.h_meters;
l_values.screen.offset.x = (args->screen.w_meters - args->inter_lens_distance_meters) / 2.0f;
l_values.screen.offset.y = args->lens_y_center_on_screen_meters;
// clang-format on
// Turn into tanangles
l_values.screen.size.x /= args->screen_to_lens_distance_meters;
l_values.screen.size.y /= args->screen_to_lens_distance_meters;
l_values.screen.offset.x /= args->screen_to_lens_distance_meters;
l_values.screen.offset.y /= args->screen_to_lens_distance_meters;
// Tan-angle to texture coordinates
// clang-format off
l_values.texture.size.x = tanf(-args->fov.angle_left) + tanf(args->fov.angle_right);
l_values.texture.size.y = tanf(args->fov.angle_up) + tanf(-args->fov.angle_down);
l_values.texture.offset.x = tanf(-args->fov.angle_left);
l_values.texture.offset.y = tanf(-args->fov.angle_down);
// clang-format on
// Fix up views not covering the entire screen.
l_values.screen.size.x /= 2.0;
/*
* Right values
*/
// clang-format off
struct u_cardboard_distortion_values r_values = {0};
r_values.distortion_k[0] = args->distortion_k[0];
r_values.distortion_k[1] = args->distortion_k[1];
r_values.distortion_k[2] = args->distortion_k[2];
r_values.distortion_k[3] = args->distortion_k[3];
r_values.distortion_k[4] = args->distortion_k[4];
r_values.screen.size.x = args->screen.w_meters;
r_values.screen.size.y = args->screen.h_meters;
r_values.screen.offset.x = (args->screen.w_meters + args->inter_lens_distance_meters) / 2.0f;
r_values.screen.offset.y = args->lens_y_center_on_screen_meters;
// clang-format on
// Turn into tanangles
r_values.screen.size.x /= args->screen_to_lens_distance_meters;
r_values.screen.size.y /= args->screen_to_lens_distance_meters;
r_values.screen.offset.x /= args->screen_to_lens_distance_meters;
r_values.screen.offset.y /= args->screen_to_lens_distance_meters;
// Tanangle to texture coordinates
// clang-format off
r_values.texture.size.x = tanf(-args->fov.angle_left) + tanf(args->fov.angle_right);
r_values.texture.size.y = tanf(args->fov.angle_up) + tanf(-args->fov.angle_down);
r_values.texture.offset.x = tanf(-args->fov.angle_left);
r_values.texture.offset.y = tanf(-args->fov.angle_down);
// clang-format on
// Fix up views not covering the entire screen.
r_values.screen.size.x /= 2.0;
r_values.screen.offset.x -= r_values.screen.size.x;
/*
* Write results.
*/
// Copy the arguments.
out_dist->args = *args;
// Save the results.
out_dist->values[0] = l_values;
out_dist->values[1] = r_values;
for (uint32_t i = 0; i < view_count; ++i) {
parts->views[i].viewport.x_pixels = 0 + i * w_pixels;
parts->views[i].viewport.y_pixels = 0;
parts->views[i].viewport.w_pixels = w_pixels;
parts->views[i].viewport.h_pixels = h_pixels;
parts->views[i].display.w_pixels = w_pixels;
parts->views[i].display.h_pixels = h_pixels;
parts->views[i].rot = u_device_rotation_ident;
parts->distortion.fov[i] = args->fov;
struct u_cardboard_distortion_values *values = &out_dist->values[i];
values->distortion_k[0] = args->distortion_k[0];
values->distortion_k[1] = args->distortion_k[1];
values->distortion_k[2] = args->distortion_k[2];
values->distortion_k[3] = args->distortion_k[3];
values->distortion_k[4] = args->distortion_k[4];
values->screen.size.x = args->screen.w_meters;
values->screen.size.y = args->screen.h_meters;
values->screen.offset.x =
(args->screen.w_meters + pow(-1, i + 1) * args->inter_lens_distance_meters) / view_count;
values->screen.offset.y = args->lens_y_center_on_screen_meters;
// clang-format on
// Turn into tanangles
values->screen.size.x /= args->screen_to_lens_distance_meters;
values->screen.size.y /= args->screen_to_lens_distance_meters;
values->screen.offset.x /= args->screen_to_lens_distance_meters;
values->screen.offset.y /= args->screen_to_lens_distance_meters;
// Tanangle to texture coordinates
values->texture.size.x = tanf(-args->fov.angle_left) + tanf(args->fov.angle_right);
values->texture.size.y = tanf(args->fov.angle_up) + tanf(-args->fov.angle_down);
values->texture.offset.x = tanf(-args->fov.angle_left);
values->texture.offset.y = tanf(-args->fov.angle_down);
// Fix up views not covering the entire screen.
values->screen.size.x /= view_count;
values->screen.offset.x -= values->screen.size.x * i;
}
}

View file

@ -91,7 +91,7 @@ struct u_cardboard_distortion
struct u_cardboard_distortion_arguments args;
//! Distortion parameters, some derived from @ref args.
struct u_cardboard_distortion_values values[2];
struct u_cardboard_distortion_values values[XRT_MAX_VIEWS];
};
/*!

View file

@ -17,6 +17,7 @@
#include "math/m_vec2.h"
#include "math/m_api.h"
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
@ -33,14 +34,14 @@ index_for(int row, int col, uint32_t stride, uint32_t offset)
}
static void
run_func(struct xrt_device *xdev, func_calc calc, int view_count, struct xrt_hmd_parts *target, uint32_t num)
run_func(struct xrt_device *xdev, func_calc calc, struct xrt_hmd_parts *target, uint32_t num)
{
assert(calc != NULL);
assert(view_count == 2);
assert(view_count <= 2);
uint32_t vertex_offsets[2] = {0};
uint32_t index_offsets[2] = {0};
uint32_t view_count = target->view_count;
uint32_t vertex_offsets[XRT_MAX_VIEWS] = {0};
uint32_t index_offsets[XRT_MAX_VIEWS] = {0};
uint32_t cells_cols = num;
uint32_t cells_rows = num;
@ -58,7 +59,7 @@ run_func(struct xrt_device *xdev, func_calc calc, int view_count, struct xrt_hmd
// Setup the vertices for all views.
uint32_t i = 0;
for (int view = 0; view < view_count; view++) {
for (uint32_t view = 0; view < view_count; view++) {
vertex_offsets[view] = i / stride_in_floats;
for (uint32_t r = 0; r < vert_rows; r++) {
@ -90,7 +91,7 @@ run_func(struct xrt_device *xdev, func_calc calc, int view_count, struct xrt_hmd
// Set up indices for all views.
i = 0;
for (int view = 0; view < view_count; view++) {
for (uint32_t view = 0; view < view_count; view++) {
index_offsets[view] = i;
uint32_t off = vertex_offsets[view];
@ -116,11 +117,11 @@ run_func(struct xrt_device *xdev, func_calc calc, int view_count, struct xrt_hmd
target->distortion.mesh.vertex_count = vertex_count;
target->distortion.mesh.uv_channels_count = uv_channels_count;
target->distortion.mesh.indices = indices;
target->distortion.mesh.index_counts[0] = index_count_per_view;
target->distortion.mesh.index_counts[1] = index_count_per_view;
target->distortion.mesh.index_offsets[0] = index_offsets[0];
target->distortion.mesh.index_offsets[1] = index_offsets[1];
target->distortion.mesh.index_count_total = index_count_total;
for (uint32_t view = 0; view < view_count; ++view) {
target->distortion.mesh.index_counts[view] = index_count_per_view;
target->distortion.mesh.index_offsets[view] = index_offsets[view];
}
}
bool
@ -437,7 +438,7 @@ u_distortion_mesh_fill_in_none(struct xrt_device *xdev)
struct xrt_hmd_parts *target = xdev->hmd;
// Do the generation.
run_func(xdev, u_distortion_mesh_none, 2, target, 1);
run_func(xdev, u_distortion_mesh_none, target, 1);
// Make the target mostly usable.
target->distortion.models |= XRT_DISTORTION_MODEL_NONE;
@ -481,5 +482,6 @@ u_distortion_mesh_fill_in_compute(struct xrt_device *xdev)
struct xrt_hmd_parts *target = xdev->hmd;
uint32_t num = (uint32_t)debug_get_num_option_mesh_size();
run_func(xdev, calc, 2, target, num);
run_func(xdev, calc, target, num);
}