mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-16 11:55:39 +00:00
xrt: Replace mesh generator with xdev->compute_distortion()
Each HMD driver now has to implement compute_distortion() which will be called by the compositor implementation to generate a mesh (usually). u_distortion_mesh contains implementations for the defaults (panotools, OpenHMD, vive). Also adds compute_distortion function for Vive distortion There are differences between OpenHMD and Panotools values, main differences for now: * psvr has 5 pano coefficients, ohmd has 3 * psvr uses viewport size and lens center in pixels for distortion calculation, ohmd in meter * psvr uses different distortion scaling than ohmd
This commit is contained in:
parent
2aaa3acfdf
commit
fb71c71a8c
|
@ -81,6 +81,12 @@ m_vec2_len(struct xrt_vec2 l)
|
|||
return sqrtf(m_vec2_len_sqrd(l));
|
||||
}
|
||||
|
||||
static inline float
|
||||
m_vec2_dot(struct xrt_vec2 l, struct xrt_vec2 r)
|
||||
{
|
||||
return l.x * r.x + l.y * r.y;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -22,17 +22,11 @@
|
|||
DEBUG_GET_ONCE_NUM_OPTION(mesh_size, "XRT_MESH_SIZE", 64)
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Func running helpers.
|
||||
*
|
||||
*/
|
||||
|
||||
typedef void (*func_cb)(struct u_uv_generator *gen,
|
||||
int view,
|
||||
float x,
|
||||
float y,
|
||||
struct u_uv_triplet *result);
|
||||
typedef bool (*func_calc)(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result);
|
||||
|
||||
static int
|
||||
index_for(int row, int col, int stride, int offset)
|
||||
|
@ -41,17 +35,16 @@ index_for(int row, int col, int stride, int offset)
|
|||
}
|
||||
|
||||
void
|
||||
run_func(struct u_uv_generator *gen,
|
||||
run_func(struct xrt_device *xdev,
|
||||
func_calc calc,
|
||||
int num_views,
|
||||
struct xrt_hmd_parts *target,
|
||||
size_t num)
|
||||
{
|
||||
assert(gen != NULL);
|
||||
assert(calc != NULL);
|
||||
assert(num_views == 2);
|
||||
assert(num_views <= 2);
|
||||
|
||||
func_cb func = gen->calc;
|
||||
|
||||
size_t offset_vertices[2] = {0};
|
||||
size_t offset_indices[2] = {0};
|
||||
|
||||
|
@ -63,7 +56,8 @@ run_func(struct u_uv_generator *gen,
|
|||
size_t num_vertices_per_view = vert_rows * vert_cols;
|
||||
size_t num_vertices = num_vertices_per_view * num_views;
|
||||
|
||||
size_t stride_in_floats = 8;
|
||||
size_t num_uv_channels = 3;
|
||||
size_t stride_in_floats = 2 + num_uv_channels * 2;
|
||||
size_t num_floats = num_vertices * stride_in_floats;
|
||||
|
||||
float *verts = U_TYPED_ARRAY_CALLOC(float, num_floats);
|
||||
|
@ -84,8 +78,14 @@ run_func(struct u_uv_generator *gen,
|
|||
// Make the position in the range of [-1, 1]
|
||||
verts[i + 0] = u * 2.0 - 1.0;
|
||||
verts[i + 1] = v * 2.0 - 1.0;
|
||||
func(gen, view, u, v,
|
||||
(struct u_uv_triplet *)&verts[i + 2]);
|
||||
|
||||
if (!calc(xdev, view, u, v,
|
||||
(struct xrt_vec2_triplet
|
||||
*)&verts[i + 2])) {
|
||||
// bail on error, without updating
|
||||
// distortion.preferred
|
||||
return;
|
||||
}
|
||||
|
||||
i += stride_in_floats;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ run_func(struct u_uv_generator *gen,
|
|||
target->distortion.mesh.vertices = verts;
|
||||
target->distortion.mesh.stride = stride_in_floats * sizeof(float);
|
||||
target->distortion.mesh.num_vertices = num_vertices;
|
||||
target->distortion.mesh.num_uv_channels = 3;
|
||||
target->distortion.mesh.num_uv_channels = num_uv_channels;
|
||||
target->distortion.mesh.indices = indices;
|
||||
target->distortion.mesh.num_indices[0] = num_indices_per_view;
|
||||
target->distortion.mesh.num_indices[1] = num_indices_per_view;
|
||||
|
@ -134,22 +134,58 @@ run_func(struct u_uv_generator *gen,
|
|||
target->distortion.mesh.total_num_indices = num_indices;
|
||||
}
|
||||
|
||||
void
|
||||
u_distortion_mesh_from_gen(struct u_uv_generator *gen,
|
||||
int num_views,
|
||||
struct xrt_hmd_parts *target)
|
||||
bool
|
||||
u_compute_distortion_vive(float aspect_x_over_y,
|
||||
float grow_for_undistort,
|
||||
float undistort_r2_cutoff,
|
||||
float center[2],
|
||||
float coefficients[3][3],
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
size_t num = debug_get_num_option_mesh_size();
|
||||
run_func(gen, num_views, target, num);
|
||||
struct xrt_vec2 factor = {0.5 / (1.0 + grow_for_undistort),
|
||||
aspect_x_over_y * 0.5 /
|
||||
(1.0 + grow_for_undistort)};
|
||||
|
||||
struct xrt_vec2 texCoord = {2.0 * u - 1.0, 2.0 * v - 1.0};
|
||||
|
||||
texCoord.y /= aspect_x_over_y;
|
||||
texCoord.x -= center[0];
|
||||
texCoord.y -= center[1];
|
||||
|
||||
float r2 = m_vec2_dot(texCoord, texCoord);
|
||||
|
||||
|
||||
struct xrt_vec3 d_inv = {
|
||||
(r2 * coefficients[2][0] + coefficients[1][0]) * r2 +
|
||||
coefficients[0][0] * r2 + 1.0,
|
||||
(r2 * coefficients[2][1] + coefficients[1][1]) * r2 +
|
||||
coefficients[0][1] * r2 + 1.0,
|
||||
(r2 * coefficients[2][2] + coefficients[1][2]) * r2 +
|
||||
coefficients[0][2] * r2 + 1.0};
|
||||
|
||||
struct xrt_vec3 d = {1.0 / d_inv.x, 1.0 / d_inv.y, 1.0 / d_inv.z};
|
||||
|
||||
struct xrt_vec2 offset = {0.5, 0.5};
|
||||
|
||||
struct xrt_vec2 tc_r = {
|
||||
offset.x + (texCoord.x * d.x + center[0]) * factor.x,
|
||||
offset.y + (texCoord.y * d.x + center[1]) * factor.y};
|
||||
|
||||
struct xrt_vec2 tc_g = {
|
||||
offset.x + (texCoord.x * d.y + center[0]) * factor.x,
|
||||
offset.y + (texCoord.y * d.y + center[1]) * factor.y};
|
||||
struct xrt_vec2 tc_b = {
|
||||
offset.x + (texCoord.x * d.z + center[0]) * factor.x,
|
||||
offset.y + (texCoord.y * d.z + center[1]) * factor.y};
|
||||
|
||||
result->r = tc_r;
|
||||
result->g = tc_g;
|
||||
result->b = tc_b;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Panotools.
|
||||
*
|
||||
*/
|
||||
|
||||
#define mul m_vec2_mul
|
||||
#define mul_scalar m_vec2_mul_scalar
|
||||
#define add m_vec2_add
|
||||
|
@ -158,25 +194,13 @@ u_distortion_mesh_from_gen(struct u_uv_generator *gen,
|
|||
#define div_scalar m_vec2_div_scalar
|
||||
#define len m_vec2_len
|
||||
|
||||
/*!
|
||||
* @implements u_uv_generator
|
||||
*/
|
||||
struct panotools_state
|
||||
bool
|
||||
u_compute_distortion_panotools(struct u_panotools_values *values,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct u_uv_generator base;
|
||||
|
||||
const struct u_panotools_values *vals[2];
|
||||
};
|
||||
|
||||
static void
|
||||
panotools_calc(struct u_uv_generator *generator,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct u_uv_triplet *result)
|
||||
{
|
||||
struct panotools_state *state = (struct panotools_state *)generator;
|
||||
const struct u_panotools_values val = *state->vals[view];
|
||||
const struct u_panotools_values val = *values;
|
||||
|
||||
struct xrt_vec2 r = {u, v};
|
||||
r = mul(r, val.viewport_size);
|
||||
|
@ -208,61 +232,11 @@ panotools_calc(struct u_uv_generator *generator,
|
|||
result->r = r_uv;
|
||||
result->g = g_uv;
|
||||
result->b = b_uv;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
panotools_destroy(struct u_uv_generator *generator)
|
||||
{
|
||||
free(generator);
|
||||
}
|
||||
|
||||
static void
|
||||
panotools_fill_in(const struct u_panotools_values *left,
|
||||
const struct u_panotools_values *right,
|
||||
struct panotools_state *state)
|
||||
{
|
||||
state->base.calc = panotools_calc;
|
||||
state->base.destroy = panotools_destroy;
|
||||
state->vals[0] = left;
|
||||
state->vals[1] = right;
|
||||
}
|
||||
|
||||
void
|
||||
u_distortion_mesh_from_panotools(const struct u_panotools_values *left,
|
||||
const struct u_panotools_values *right,
|
||||
struct xrt_hmd_parts *target)
|
||||
{
|
||||
struct panotools_state state;
|
||||
panotools_fill_in(left, right, &state);
|
||||
|
||||
size_t num = debug_get_num_option_mesh_size();
|
||||
run_func(&state.base, 2, target, num);
|
||||
}
|
||||
|
||||
void
|
||||
u_distortion_mesh_generator_from_panotools(
|
||||
const struct u_panotools_values *left,
|
||||
const struct u_panotools_values *right,
|
||||
struct u_uv_generator **out_gen)
|
||||
{
|
||||
struct panotools_state *state = U_TYPED_CALLOC(struct panotools_state);
|
||||
panotools_fill_in(left, right, state);
|
||||
*out_gen = &state->base;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* No distortion.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
no_distortion_calc(struct u_uv_generator *generator,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct u_uv_triplet *result)
|
||||
bool
|
||||
u_compute_distortion_none(float u, float v, struct xrt_vec2_triplet *result)
|
||||
{
|
||||
result->r.x = u;
|
||||
result->r.y = v;
|
||||
|
@ -270,13 +244,27 @@ no_distortion_calc(struct u_uv_generator *generator,
|
|||
result->g.y = v;
|
||||
result->b.x = u;
|
||||
result->b.y = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
compute_distortion_none(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
return u_compute_distortion_none(u, v, result);
|
||||
}
|
||||
|
||||
void
|
||||
u_distortion_mesh_none(struct xrt_hmd_parts *target)
|
||||
u_compute_distortion_mesh(struct xrt_device *xdev)
|
||||
{
|
||||
struct u_uv_generator gen;
|
||||
gen.calc = no_distortion_calc;
|
||||
|
||||
run_func(&gen, 2, target, 8);
|
||||
struct xrt_hmd_parts *target = xdev->hmd;
|
||||
func_calc calc = xdev->compute_distortion;
|
||||
if (calc == NULL) {
|
||||
calc = compute_distortion_none;
|
||||
}
|
||||
size_t num = debug_get_num_option_mesh_size();
|
||||
run_func(xdev, calc, 2, target, num);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,21 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Distortion correction implementation for the Vive, Vive Pro, Valve Index
|
||||
* distortion values found in the HMD configuration.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
bool
|
||||
u_compute_distortion_vive(float aspect_x_over_y,
|
||||
float grow_for_undistort,
|
||||
float undistort_r2_cutoff,
|
||||
float center[2],
|
||||
float coefficients[3][3],
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result);
|
||||
|
||||
/*!
|
||||
* Values to create a distortion mesh from panotools values.
|
||||
|
@ -37,80 +52,33 @@ struct u_panotools_values
|
|||
};
|
||||
|
||||
/*!
|
||||
* Three UV pairs, one for each color channel in the source image.
|
||||
* Distortion correction implementation for Panotools distortion values.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
struct u_uv_triplet
|
||||
{
|
||||
struct xrt_vec2 r, g, b;
|
||||
};
|
||||
bool
|
||||
u_compute_distortion_panotools(struct u_panotools_values *values,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result);
|
||||
|
||||
/*!
|
||||
* @interface u_uv_generator
|
||||
*
|
||||
* Generator interface for building meshes, can be implemented by drivers for
|
||||
* special meshes.
|
||||
* Identity distortion correction sets all result coordinates to u,v.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
struct u_uv_generator
|
||||
{
|
||||
void (*calc)(struct u_uv_generator *,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct u_uv_triplet *result);
|
||||
|
||||
void (*destroy)(struct u_uv_generator *);
|
||||
};
|
||||
bool
|
||||
u_compute_distortion_none(float u, float v, struct xrt_vec2_triplet *result);
|
||||
|
||||
/*!
|
||||
* Given a @ref u_uv_generator generates num_views meshes, populates target.
|
||||
* Given a @ref xrt_device generates meshes by calling
|
||||
* xdev->compute_distortion(), populates xdev->hmd_parts.distortion.mesh
|
||||
*
|
||||
* @ingroup aux_util
|
||||
* @public @memberof u_uv_generator
|
||||
* @relatesalso xrt_hmd_parts
|
||||
* @relatesalso xrt_device
|
||||
*/
|
||||
void
|
||||
u_distortion_mesh_from_gen(struct u_uv_generator *,
|
||||
int num_views,
|
||||
struct xrt_hmd_parts *target);
|
||||
|
||||
/*!
|
||||
* Given two sets of panotools values creates a mesh generator, copies the
|
||||
* values into it. This probably isn't the function you want.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
* @see u_distortion_mesh_from_panotools
|
||||
*/
|
||||
void
|
||||
u_distortion_mesh_generator_from_panotools(
|
||||
const struct u_panotools_values *left,
|
||||
const struct u_panotools_values *right,
|
||||
struct u_uv_generator **out_gen);
|
||||
|
||||
/*!
|
||||
* Given two sets of panotools values creates the left and th right uv meshes.
|
||||
* This is probably the function you want.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
* @relates xrt_hmd_parts
|
||||
*/
|
||||
void
|
||||
u_distortion_mesh_from_panotools(const struct u_panotools_values *left,
|
||||
const struct u_panotools_values *right,
|
||||
struct xrt_hmd_parts *target);
|
||||
|
||||
/*!
|
||||
* Create two distortion meshes with no distortion.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
* @relates xrt_hmd_parts
|
||||
*/
|
||||
void
|
||||
u_distortion_mesh_none(struct xrt_hmd_parts *target);
|
||||
|
||||
u_compute_distortion_mesh(struct xrt_device *xdev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "util/u_misc.h"
|
||||
#include "util/u_time.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_distortion_mesh.h"
|
||||
|
||||
#include "main/comp_compositor.h"
|
||||
|
||||
|
@ -1160,6 +1161,31 @@ xrt_gfx_provider_create_native(struct xrt_device *xdev)
|
|||
// Init the settings to default.
|
||||
comp_settings_init(&c->settings, xdev);
|
||||
|
||||
if (c->xdev->hmd->distortion.preferred ==
|
||||
XRT_DISTORTION_MODEL_COMPUTE ||
|
||||
c->xdev->hmd->distortion.preferred == XRT_DISTORTION_MODEL_NONE) {
|
||||
COMP_DEBUG(
|
||||
c, "Computing distortion mesh on compositor startup...");
|
||||
u_compute_distortion_mesh(c->xdev);
|
||||
|
||||
if (c->xdev->hmd->distortion.preferred !=
|
||||
XRT_DISTORTION_MODEL_MESHUV) {
|
||||
COMP_ERROR(c, "Failed to create mesh distortion for %s",
|
||||
c->xdev->str);
|
||||
|
||||
//! @todo Check if compositor supports current non-mesh
|
||||
//! distortion model and bail if not.
|
||||
// Monado will likely support only mesh in the future.
|
||||
|
||||
// c->base.base.destroy(&c->base.base);
|
||||
// return NULL;
|
||||
} else {
|
||||
COMP_DEBUG(c, "Distortion mesh computed!");
|
||||
c->settings.distortion_model =
|
||||
XRT_DISTORTION_MODEL_MESHUV;
|
||||
}
|
||||
}
|
||||
|
||||
c->last_frame_time_ns = os_monotonic_get_ns();
|
||||
c->frame_overhead_ns = 2000000;
|
||||
//! @todo set this to an estimate that's better than 6ms
|
||||
|
|
|
@ -353,7 +353,7 @@ comp_distortion_init_pipeline(struct comp_distortion *d,
|
|||
fragment_shader_code = shaders_none_frag;
|
||||
fragment_shader_size = sizeof(shaders_none_frag);
|
||||
break;
|
||||
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
||||
case XRT_DISTORTION_MODEL_OPENHMD:
|
||||
fragment_shader_code = shaders_panotools_frag;
|
||||
fragment_shader_size = sizeof(shaders_panotools_frag);
|
||||
break;
|
||||
|
@ -702,26 +702,30 @@ comp_distortion_update_uniform_buffer_warp(struct comp_distortion *d,
|
|||
break;
|
||||
case XRT_DISTORTION_MODEL_MESHUV:
|
||||
break;
|
||||
case XRT_DISTORTION_MODEL_NONE:
|
||||
break;
|
||||
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
||||
break;
|
||||
case XRT_DISTORTION_MODEL_OPENHMD:
|
||||
default:
|
||||
/*
|
||||
* Pano vision fragment shader
|
||||
*/
|
||||
d->ubo_pano.hmd_warp_param[0] = c->xdev->hmd->distortion.pano.distortion_k[0];
|
||||
d->ubo_pano.hmd_warp_param[1] = c->xdev->hmd->distortion.pano.distortion_k[1];
|
||||
d->ubo_pano.hmd_warp_param[2] = c->xdev->hmd->distortion.pano.distortion_k[2];
|
||||
d->ubo_pano.hmd_warp_param[3] = c->xdev->hmd->distortion.pano.distortion_k[3];
|
||||
d->ubo_pano.aberr[0] = c->xdev->hmd->distortion.pano.aberration_k[0];
|
||||
d->ubo_pano.aberr[1] = c->xdev->hmd->distortion.pano.aberration_k[1];
|
||||
d->ubo_pano.aberr[2] = c->xdev->hmd->distortion.pano.aberration_k[2];
|
||||
d->ubo_pano.aberr[3] = c->xdev->hmd->distortion.pano.aberration_k[3];
|
||||
d->ubo_pano.hmd_warp_param[0] = c->xdev->hmd->distortion.openhmd.distortion_k[0];
|
||||
d->ubo_pano.hmd_warp_param[1] = c->xdev->hmd->distortion.openhmd.distortion_k[1];
|
||||
d->ubo_pano.hmd_warp_param[2] = c->xdev->hmd->distortion.openhmd.distortion_k[2];
|
||||
d->ubo_pano.hmd_warp_param[3] = c->xdev->hmd->distortion.openhmd.distortion_k[3];
|
||||
d->ubo_pano.aberr[0] = c->xdev->hmd->distortion.openhmd.aberration_k[0];
|
||||
d->ubo_pano.aberr[1] = c->xdev->hmd->distortion.openhmd.aberration_k[1];
|
||||
d->ubo_pano.aberr[2] = c->xdev->hmd->distortion.openhmd.aberration_k[2];
|
||||
d->ubo_pano.aberr[3] = c->xdev->hmd->distortion.openhmd.aberration_k[3];
|
||||
d->ubo_pano.lens_center[0][0] = c->xdev->hmd->views[0].lens_center.x_meters;
|
||||
d->ubo_pano.lens_center[0][1] = c->xdev->hmd->views[0].lens_center.y_meters;
|
||||
d->ubo_pano.lens_center[1][0] = c->xdev->hmd->views[1].lens_center.x_meters;
|
||||
d->ubo_pano.lens_center[1][1] = c->xdev->hmd->views[1].lens_center.y_meters;
|
||||
d->ubo_pano.viewport_scale[0] = c->xdev->hmd->views[0].display.w_meters;
|
||||
d->ubo_pano.viewport_scale[1] = c->xdev->hmd->views[0].display.h_meters;
|
||||
d->ubo_pano.warp_scale = c->xdev->hmd->distortion.pano.warp_scale;
|
||||
d->ubo_pano.warp_scale = c->xdev->hmd->distortion.openhmd.warp_scale;
|
||||
|
||||
memcpy(d->ubo_handle.mapped, &d->ubo_pano, sizeof(d->ubo_pano));
|
||||
break;
|
||||
|
@ -859,7 +863,7 @@ comp_distortion_init_buffers(struct comp_distortion *d,
|
|||
d->has_fragment_shader_ubo = true;
|
||||
|
||||
switch (d->distortion_model) {
|
||||
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
||||
case XRT_DISTORTION_MODEL_OPENHMD:
|
||||
ubo_size = sizeof(d->ubo_pano);
|
||||
break;
|
||||
case XRT_DISTORTION_MODEL_MESHUV:
|
||||
|
|
|
@ -194,10 +194,10 @@ dummy_hmd_create(void)
|
|||
u_var_add_root(dh, "Dummy HMD", true);
|
||||
u_var_add_pose(dh, &dh->pose, "pose");
|
||||
|
||||
if (dh->base.hmd->distortion.preferred == XRT_DISTORTION_MODEL_NONE) {
|
||||
// Setup the distortion mesh.
|
||||
u_distortion_mesh_none(dh->base.hmd);
|
||||
}
|
||||
dh->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
||||
dh->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_NONE;
|
||||
dh->base.compute_distortion = NULL;
|
||||
|
||||
dh->base.device_type = XRT_DEVICE_TYPE_HMD;
|
||||
|
||||
return &dh->base;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "util/u_misc.h"
|
||||
#include "util/u_device.h"
|
||||
#include "util/u_time.h"
|
||||
#include "util/u_distortion_mesh.h"
|
||||
|
||||
#include "hdk_device.h"
|
||||
|
||||
|
@ -487,6 +488,7 @@ hdk_device_create(struct os_hid_device *dev,
|
|||
// We only have a mesh for 2, so use "none" there until it's supported.
|
||||
hd->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
||||
hd->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_NONE;
|
||||
hd->base.compute_distortion = NULL;
|
||||
// if (variant == HDK_VARIANT_1_3_1_4) {
|
||||
// hd->base.hmd->distortion.models =
|
||||
// xrt_distortion_model(hd->base.hmd->distortion.models |
|
||||
|
|
|
@ -112,19 +112,18 @@ ns_hmd_get_view_pose(struct xrt_device *xdev,
|
|||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ns_mesh_calc(struct u_uv_generator *gen,
|
||||
static bool
|
||||
ns_mesh_calc(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct u_uv_triplet *result)
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct ns_mesh *mesh = ns_mesh(gen);
|
||||
struct ns_hmd *ns = ns_hmd(xdev);
|
||||
|
||||
struct ns_uv uv = {u, v};
|
||||
struct ns_uv warped_uv = {0.0f, 0.0f};
|
||||
ns_display_uv_to_render_uv(uv, &warped_uv,
|
||||
&mesh->ns->eye_configs_v1[view]);
|
||||
ns_display_uv_to_render_uv(uv, &warped_uv, &ns->eye_configs_v1[view]);
|
||||
|
||||
result->r.x = warped_uv.u;
|
||||
result->r.y = warped_uv.v;
|
||||
|
@ -132,13 +131,7 @@ ns_mesh_calc(struct u_uv_generator *gen,
|
|||
result->g.y = warped_uv.v;
|
||||
result->b.x = warped_uv.u;
|
||||
result->b.y = warped_uv.v;
|
||||
}
|
||||
|
||||
static void
|
||||
ns_mesh_destroy(struct u_uv_generator *gen)
|
||||
{
|
||||
struct ns_mesh *mesh = (struct ns_mesh *)gen;
|
||||
(void)mesh; // Noop
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -301,15 +294,14 @@ ns_v2_fov_calculate(struct ns_hmd *ns, int eye_index)
|
|||
|
||||
|
||||
|
||||
static void
|
||||
ns_v2_mesh_calc(struct u_uv_generator *gen,
|
||||
static bool
|
||||
ns_v2_mesh_calc(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct u_uv_triplet *result)
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
|
||||
|
||||
struct ns_hmd *ns = ns_hmd(xdev);
|
||||
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
|
@ -317,16 +309,15 @@ ns_v2_mesh_calc(struct u_uv_generator *gen,
|
|||
u = 1.0 - u;
|
||||
v = 1.0 - v;
|
||||
|
||||
struct ns_mesh *mesh = ns_mesh(gen);
|
||||
float L = mesh->ns->eye_configs_v2[view].fov.angle_left;
|
||||
float R = mesh->ns->eye_configs_v2[view].fov.angle_right;
|
||||
float T = mesh->ns->eye_configs_v2[view].fov.angle_up;
|
||||
float B = mesh->ns->eye_configs_v2[view].fov.angle_down;
|
||||
float L = ns->eye_configs_v2[view].fov.angle_left;
|
||||
float R = ns->eye_configs_v2[view].fov.angle_right;
|
||||
float T = ns->eye_configs_v2[view].fov.angle_up;
|
||||
float B = ns->eye_configs_v2[view].fov.angle_down;
|
||||
|
||||
float x_ray = ns_v2_polyval2d(
|
||||
u, v, mesh->ns->eye_configs_v2[view].x_coefficients);
|
||||
float y_ray = ns_v2_polyval2d(
|
||||
u, v, mesh->ns->eye_configs_v2[view].y_coefficients);
|
||||
float x_ray =
|
||||
ns_v2_polyval2d(u, v, ns->eye_configs_v2[view].x_coefficients);
|
||||
float y_ray =
|
||||
ns_v2_polyval2d(u, v, ns->eye_configs_v2[view].y_coefficients);
|
||||
|
||||
x = (x_ray + L) / (L - R);
|
||||
y = (y_ray + T) / (T - B);
|
||||
|
@ -338,6 +329,7 @@ ns_v2_mesh_calc(struct u_uv_generator *gen,
|
|||
result->g.y = y;
|
||||
result->b.x = x;
|
||||
result->b.y = y;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -551,20 +543,10 @@ ns_hmd_create(const char *config_path, bool print_spew, bool print_debug)
|
|||
ns_v2_fov_calculate(ns, 0);
|
||||
ns_v2_fov_calculate(ns, 1);
|
||||
|
||||
|
||||
|
||||
// Setup the distortion mesh.
|
||||
struct ns_mesh mesh;
|
||||
U_ZERO(&mesh);
|
||||
mesh.ns = ns;
|
||||
mesh.base.calc = ns_v2_mesh_calc;
|
||||
mesh.base.destroy = ns_mesh_destroy;
|
||||
|
||||
// Do the mesh generation.
|
||||
u_distortion_mesh_from_gen(&mesh.base, 2, ns->base.hmd);
|
||||
// u_distortion_mesh_none(ns->base.hmd);
|
||||
|
||||
|
||||
ns->base.hmd->distortion.models = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
ns->base.hmd->distortion.preferred =
|
||||
XRT_DISTORTION_MODEL_COMPUTE;
|
||||
ns->base.compute_distortion = ns_v2_mesh_calc;
|
||||
|
||||
} else {
|
||||
// V1
|
||||
|
@ -591,17 +573,10 @@ ns_hmd_create(const char *config_path, bool print_spew, bool print_debug)
|
|||
ns->tracker = rs_6dof_create();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Setup the distortion mesh.
|
||||
struct ns_mesh mesh;
|
||||
U_ZERO(&mesh);
|
||||
mesh.ns = ns;
|
||||
mesh.base.calc = ns_mesh_calc;
|
||||
mesh.base.destroy = ns_mesh_destroy;
|
||||
|
||||
// Do the mesh generation.
|
||||
u_distortion_mesh_from_gen(&mesh.base, 2, ns->base.hmd);
|
||||
ns->base.hmd->distortion.models = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
ns->base.hmd->distortion.preferred =
|
||||
XRT_DISTORTION_MODEL_COMPUTE;
|
||||
ns->base.compute_distortion = ns_mesh_calc;
|
||||
}
|
||||
|
||||
// If built, try to load the realsense tracker.
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "math/m_api.h"
|
||||
#include "util/u_distortion_mesh.h"
|
||||
#include "util/u_json.h"
|
||||
#include "util/u_misc.h"
|
||||
#include "xrt/xrt_defines.h"
|
||||
|
@ -150,20 +149,6 @@ struct ns_hmd
|
|||
// be an enum or something
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* The mesh generator for the North Star distortion.
|
||||
*
|
||||
* @ingroup drv_ns
|
||||
* @implements u_uv_generator
|
||||
*/
|
||||
struct ns_mesh
|
||||
{
|
||||
struct u_uv_generator base;
|
||||
struct ns_hmd *ns;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions
|
||||
|
@ -181,17 +166,6 @@ ns_hmd(struct xrt_device *xdev)
|
|||
return (struct ns_hmd *)xdev;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get the North Star mesh generator from a @ref u_uv_generator.
|
||||
*
|
||||
* @ingroup drv_ns
|
||||
*/
|
||||
static inline struct ns_mesh *
|
||||
ns_mesh(struct u_uv_generator *gen)
|
||||
{
|
||||
return (struct ns_mesh *)gen;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert the display UV to the render UV using the distortion mesh.
|
||||
*
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "openhmd.h"
|
||||
|
||||
#include "math/m_api.h"
|
||||
#include "math/m_vec2.h"
|
||||
#include "xrt/xrt_device.h"
|
||||
#include "util/u_var.h"
|
||||
#include "util/u_misc.h"
|
||||
|
@ -372,6 +373,97 @@ get_info(struct oh_device *ohd, const char *prod)
|
|||
return info;
|
||||
}
|
||||
|
||||
#define mul m_vec2_mul
|
||||
#define mul_scalar m_vec2_mul_scalar
|
||||
#define add m_vec2_add
|
||||
#define sub m_vec2_sub
|
||||
#define div m_vec2_div
|
||||
#define div_scalar m_vec2_div_scalar
|
||||
#define len m_vec2_len
|
||||
|
||||
// slightly different to u_compute_distortion_panotools in u_distortion_mesh
|
||||
static bool
|
||||
u_compute_distortion_openhmd(float distortion_k[5],
|
||||
float aberration_k[3],
|
||||
float scale,
|
||||
struct xrt_vec2 lens_center,
|
||||
struct xrt_vec2 viewport_size,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct xrt_vec2 r = {u, v};
|
||||
r = mul(r, viewport_size);
|
||||
r = sub(r, lens_center);
|
||||
r = div_scalar(r, scale);
|
||||
|
||||
float r_mag = len(r);
|
||||
r_mag = distortion_k[0] + // r^1
|
||||
distortion_k[1] * r_mag + // r^2
|
||||
distortion_k[2] * r_mag * r_mag + // r^3
|
||||
distortion_k[3] * r_mag * r_mag * r_mag; // r^4
|
||||
|
||||
struct xrt_vec2 r_dist = mul_scalar(r, r_mag);
|
||||
r_dist = mul_scalar(r_dist, scale);
|
||||
|
||||
struct xrt_vec2 r_uv = mul_scalar(r_dist, aberration_k[0]);
|
||||
r_uv = add(r_uv, lens_center);
|
||||
r_uv = div(r_uv, viewport_size);
|
||||
|
||||
struct xrt_vec2 g_uv = mul_scalar(r_dist, aberration_k[1]);
|
||||
g_uv = add(g_uv, lens_center);
|
||||
g_uv = div(g_uv, viewport_size);
|
||||
|
||||
struct xrt_vec2 b_uv = mul_scalar(r_dist, aberration_k[2]);
|
||||
b_uv = add(b_uv, lens_center);
|
||||
b_uv = div(b_uv, viewport_size);
|
||||
|
||||
result->r = r_uv;
|
||||
result->g = g_uv;
|
||||
result->b = b_uv;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
compute_distortion_openhmd(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct xrt_hmd_parts *hmd = xdev->hmd;
|
||||
struct xrt_vec2 lens_center = {
|
||||
.x = hmd->views[view].lens_center.x_meters,
|
||||
.y = hmd->views[view].lens_center.y_meters};
|
||||
|
||||
struct xrt_vec2 viewport_size = {.x = hmd->views[view].display.w_meters,
|
||||
.y =
|
||||
hmd->views[view].display.h_meters};
|
||||
|
||||
//! @todo: support distortion per view
|
||||
return u_compute_distortion_openhmd(
|
||||
hmd->distortion.openhmd.distortion_k,
|
||||
hmd->distortion.openhmd.aberration_k,
|
||||
hmd->distortion.openhmd.warp_scale, lens_center, viewport_size, u,
|
||||
v, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
compute_distortion_vive(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct xrt_hmd_parts *hmd = xdev->hmd;
|
||||
return u_compute_distortion_vive(
|
||||
hmd->distortion.vive.aspect_x_over_y,
|
||||
hmd->distortion.vive.grow_for_undistort,
|
||||
hmd->distortion.vive.undistort_r2_cutoff[view],
|
||||
hmd->distortion.vive.center[view],
|
||||
hmd->distortion.vive.coefficients[view], u, v, result);
|
||||
}
|
||||
|
||||
struct oh_device *
|
||||
oh_device_create(ohmd_context *ctx,
|
||||
ohmd_device *dev,
|
||||
|
@ -429,19 +521,17 @@ oh_device_create(ohmd_context *ctx,
|
|||
|
||||
// clang-format off
|
||||
// Main display.
|
||||
ohd->base.hmd->distortion.models = XRT_DISTORTION_MODEL_PANOTOOLS;
|
||||
ohd->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_PANOTOOLS;
|
||||
ohd->base.hmd->screens[0].w_pixels = info.display.w_pixels;
|
||||
ohd->base.hmd->screens[0].h_pixels = info.display.h_pixels;
|
||||
ohd->base.hmd->screens[0].nominal_frame_interval_ns = info.display.nominal_frame_interval_ns;
|
||||
ohd->base.hmd->distortion.pano.distortion_k[0] = info.pano_distortion_k[0];
|
||||
ohd->base.hmd->distortion.pano.distortion_k[1] = info.pano_distortion_k[1];
|
||||
ohd->base.hmd->distortion.pano.distortion_k[2] = info.pano_distortion_k[2];
|
||||
ohd->base.hmd->distortion.pano.distortion_k[3] = info.pano_distortion_k[3];
|
||||
ohd->base.hmd->distortion.pano.aberration_k[0] = info.pano_aberration_k[0];
|
||||
ohd->base.hmd->distortion.pano.aberration_k[1] = info.pano_aberration_k[1];
|
||||
ohd->base.hmd->distortion.pano.aberration_k[2] = info.pano_aberration_k[2];
|
||||
ohd->base.hmd->distortion.pano.warp_scale = info.pano_warp_scale;
|
||||
ohd->base.hmd->distortion.openhmd.distortion_k[0] = info.pano_distortion_k[0];
|
||||
ohd->base.hmd->distortion.openhmd.distortion_k[1] = info.pano_distortion_k[1];
|
||||
ohd->base.hmd->distortion.openhmd.distortion_k[2] = info.pano_distortion_k[2];
|
||||
ohd->base.hmd->distortion.openhmd.distortion_k[3] = info.pano_distortion_k[3];
|
||||
ohd->base.hmd->distortion.openhmd.aberration_k[0] = info.pano_aberration_k[0];
|
||||
ohd->base.hmd->distortion.openhmd.aberration_k[1] = info.pano_aberration_k[1];
|
||||
ohd->base.hmd->distortion.openhmd.aberration_k[2] = info.pano_aberration_k[2];
|
||||
ohd->base.hmd->distortion.openhmd.warp_scale = info.pano_warp_scale;
|
||||
|
||||
// Left
|
||||
ohd->base.hmd->views[0].display.w_meters = info.views[0].display.w_meters;
|
||||
|
@ -470,6 +560,12 @@ oh_device_create(ohmd_context *ctx,
|
|||
ohd->base.hmd->views[1].rot = u_device_rotation_ident;
|
||||
// clang-format on
|
||||
|
||||
ohd->base.hmd->distortion.models |=
|
||||
XRT_DISTORTION_MODEL_COMPUTE | XRT_DISTORTION_MODEL_OPENHMD;
|
||||
ohd->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
ohd->base.compute_distortion = compute_distortion_openhmd;
|
||||
;
|
||||
|
||||
// Which blend modes does the device support.
|
||||
ohd->base.hmd->blend_mode = XRT_BLEND_MODE_OPAQUE;
|
||||
if (info.quirks.video_see_through) {
|
||||
|
@ -478,11 +574,6 @@ oh_device_create(ohmd_context *ctx,
|
|||
}
|
||||
|
||||
if (info.quirks.video_distortion_vive) {
|
||||
ohd->base.hmd->distortion.models = (enum xrt_distortion_model)(
|
||||
ohd->base.hmd->distortion.models |
|
||||
XRT_DISTORTION_MODEL_VIVE);
|
||||
ohd->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_VIVE;
|
||||
|
||||
// clang-format off
|
||||
// These need to be acquired from the vive config
|
||||
ohd->base.hmd->distortion.vive.aspect_x_over_y = 0.8999999761581421f;
|
||||
|
@ -526,15 +617,21 @@ oh_device_create(ohmd_context *ctx,
|
|||
ohd->base.hmd->distortion.vive.coefficients[1][2][1] = -0.04517245633373419f;
|
||||
ohd->base.hmd->distortion.vive.coefficients[1][2][2] = -0.0928909347763f;
|
||||
// clang-format on
|
||||
|
||||
ohd->base.hmd->distortion.models |= XRT_DISTORTION_MODEL_VIVE;
|
||||
ohd->base.hmd->distortion.preferred =
|
||||
XRT_DISTORTION_MODEL_COMPUTE;
|
||||
ohd->base.compute_distortion = compute_distortion_vive;
|
||||
}
|
||||
|
||||
if (info.quirks.video_distortion_none) {
|
||||
ohd->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
||||
ohd->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_NONE;
|
||||
ohd->base.compute_distortion = NULL;
|
||||
}
|
||||
|
||||
if (info.quirks.left_center_pano_scale) {
|
||||
ohd->base.hmd->distortion.pano.warp_scale =
|
||||
ohd->base.hmd->distortion.openhmd.warp_scale =
|
||||
info.views[0].lens_center_x_meters;
|
||||
}
|
||||
|
||||
|
@ -600,10 +697,5 @@ oh_device_create(ohmd_context *ctx,
|
|||
u_var_add_root(ohd, "OpenHMD Wrapper", true);
|
||||
u_var_add_ro_text(ohd, ohd->base.str, "Card");
|
||||
|
||||
if (ohd->base.hmd->distortion.preferred == XRT_DISTORTION_MODEL_NONE) {
|
||||
// Setup the distortion mesh.
|
||||
u_distortion_mesh_none(ohd->base.hmd);
|
||||
}
|
||||
|
||||
return ohd;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ struct psvr_device
|
|||
int last_packet;
|
||||
} calibration;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
bool last_frame;
|
||||
|
@ -137,6 +138,9 @@ struct psvr_device
|
|||
struct xrt_quat rot;
|
||||
} fusion;
|
||||
#endif
|
||||
|
||||
//! For compute_distortion
|
||||
struct u_panotools_values vals;
|
||||
};
|
||||
|
||||
|
||||
|
@ -983,6 +987,18 @@ psvr_device_destroy(struct xrt_device *xdev)
|
|||
u_device_free(&psvr->base);
|
||||
}
|
||||
|
||||
static bool
|
||||
psvr_compute_distortion(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct psvr_device *psvr = psvr_device(xdev);
|
||||
|
||||
return u_compute_distortion_panotools(&psvr->vals, u, v, result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -1008,6 +1024,7 @@ psvr_device_create(struct hid_device_info *hmd_handle_info,
|
|||
psvr->base.update_inputs = psvr_device_update_inputs;
|
||||
psvr->base.get_tracked_pose = psvr_device_get_tracked_pose;
|
||||
psvr->base.get_view_pose = psvr_device_get_view_pose;
|
||||
psvr->base.compute_distortion = psvr_compute_distortion;
|
||||
psvr->base.destroy = psvr_device_destroy;
|
||||
psvr->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE;
|
||||
psvr->base.name = XRT_DEVICE_GENERIC_HMD;
|
||||
|
@ -1029,7 +1046,11 @@ psvr_device_create(struct hid_device_info *hmd_handle_info,
|
|||
vals.lens_center.x = vals.viewport_size.x / 2.0;
|
||||
vals.lens_center.y = vals.viewport_size.y / 2.0;
|
||||
|
||||
u_distortion_mesh_from_panotools(&vals, &vals, psvr->base.hmd);
|
||||
psvr->vals = vals;
|
||||
|
||||
struct xrt_hmd_parts *hmd = psvr->base.hmd;
|
||||
hmd->distortion.models = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
hmd->distortion.preferred = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "util/u_misc.h"
|
||||
#include "util/u_time.h"
|
||||
#include "util/u_device.h"
|
||||
#include "util/u_distortion_mesh.h"
|
||||
|
||||
#include "../auxiliary/os/os_time.h"
|
||||
|
||||
|
@ -903,6 +904,22 @@ get_distortion_properties(struct survive_device *d,
|
|||
_get_color_coeffs_lookup(hmd, eye_json, "distortion_blue", eye, 2);
|
||||
}
|
||||
|
||||
static bool
|
||||
compute_distortion(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct xrt_hmd_parts *hmd = xdev->hmd;
|
||||
return u_compute_distortion_vive(
|
||||
hmd->distortion.vive.aspect_x_over_y,
|
||||
hmd->distortion.vive.grow_for_undistort,
|
||||
hmd->distortion.vive.undistort_r2_cutoff[view],
|
||||
hmd->distortion.vive.center[view],
|
||||
hmd->distortion.vive.coefficients[view], u, v, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
_create_hmd_device(struct survive_system *sys, enum VIVE_VARIANT variant)
|
||||
{
|
||||
|
@ -1076,8 +1093,10 @@ _create_hmd_device(struct survive_system *sys, enum VIVE_VARIANT variant)
|
|||
}
|
||||
}
|
||||
|
||||
survive->base.hmd->distortion.models = XRT_DISTORTION_MODEL_VIVE;
|
||||
survive->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_VIVE;
|
||||
survive->base.hmd->distortion.models =
|
||||
XRT_DISTORTION_MODEL_VIVE | XRT_DISTORTION_MODEL_COMPUTE;
|
||||
survive->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
survive->base.compute_distortion = compute_distortion;
|
||||
|
||||
survive->base.orientation_tracking_supported = true;
|
||||
survive->base.position_tracking_supported = true;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "util/u_debug.h"
|
||||
#include "util/u_var.h"
|
||||
#include "util/u_time.h"
|
||||
#include "util/u_distortion_mesh.h"
|
||||
|
||||
#include "math/m_api.h"
|
||||
|
||||
|
@ -794,6 +795,23 @@ vive_init_defaults(struct vive_device *d)
|
|||
hmd->distortion.vive.undistort_r2_cutoff[1] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
compute_distortion(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result)
|
||||
{
|
||||
struct xrt_hmd_parts *hmd = xdev->hmd;
|
||||
return u_compute_distortion_vive(
|
||||
hmd->distortion.vive.aspect_x_over_y,
|
||||
hmd->distortion.vive.grow_for_undistort,
|
||||
hmd->distortion.vive.undistort_r2_cutoff[view],
|
||||
hmd->distortion.vive.center[view],
|
||||
hmd->distortion.vive.coefficients[view], u, v, result);
|
||||
}
|
||||
|
||||
struct vive_device *
|
||||
vive_device_create(struct os_hid_device *mainboard_dev,
|
||||
struct os_hid_device *sensors_dev,
|
||||
|
@ -818,6 +836,11 @@ vive_device_create(struct os_hid_device *mainboard_dev,
|
|||
d->watchman_dev = watchman_dev;
|
||||
d->variant = variant;
|
||||
|
||||
d->base.hmd->distortion.models =
|
||||
XRT_DISTORTION_MODEL_VIVE | XRT_DISTORTION_MODEL_COMPUTE;
|
||||
d->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_COMPUTE;
|
||||
d->base.compute_distortion = compute_distortion;
|
||||
|
||||
vive_init_defaults(d);
|
||||
|
||||
switch (variant) {
|
||||
|
@ -935,9 +958,6 @@ vive_device_create(struct os_hid_device *mainboard_dev,
|
|||
}
|
||||
}
|
||||
|
||||
d->base.hmd->distortion.models = XRT_DISTORTION_MODEL_VIVE;
|
||||
d->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_VIVE;
|
||||
|
||||
// Init here.
|
||||
m_imu_3dof_init(&d->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_20MS);
|
||||
|
||||
|
|
|
@ -53,9 +53,11 @@ enum xrt_distortion_model
|
|||
{
|
||||
// clang-format off
|
||||
XRT_DISTORTION_MODEL_NONE = 1 << 0,
|
||||
XRT_DISTORTION_MODEL_PANOTOOLS = 1 << 1,
|
||||
XRT_DISTORTION_MODEL_VIVE = 1 << 2,
|
||||
XRT_DISTORTION_MODEL_MESHUV = 1 << 3,
|
||||
XRT_DISTORTION_MODEL_COMPUTE = 1 << 1,
|
||||
XRT_DISTORTION_MODEL_PANOTOOLS = 1 << 2,
|
||||
XRT_DISTORTION_MODEL_VIVE = 1 << 3,
|
||||
XRT_DISTORTION_MODEL_MESHUV = 1 << 4,
|
||||
XRT_DISTORTION_MODEL_OPENHMD = 1 << 5,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -129,6 +131,16 @@ struct xrt_vec2
|
|||
float y;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Three xrt_vec2
|
||||
*
|
||||
* @ingroup xrt_iface_math
|
||||
*/
|
||||
struct xrt_vec2_triplet
|
||||
{
|
||||
struct xrt_vec2 r, g, b;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A 3 element vector with single floats.
|
||||
*
|
||||
|
|
|
@ -60,13 +60,16 @@ struct xrt_view
|
|||
} display;
|
||||
|
||||
/*!
|
||||
* Position in meters relative to display origin, before any rotation
|
||||
* is applied by xrt_view::rot.
|
||||
* Position relative to display origin, before any rotation is applied
|
||||
* by xrt_view::rot. note: not set by most drivers, used only for
|
||||
* panotools/ohmd distortion
|
||||
*/
|
||||
struct
|
||||
{
|
||||
float x_meters;
|
||||
float y_meters;
|
||||
int x_pixels;
|
||||
int y_pixels;
|
||||
} lens_center;
|
||||
|
||||
/*!
|
||||
|
@ -132,7 +135,7 @@ struct xrt_hmd_parts
|
|||
float aberration_k[4];
|
||||
//! Panotools warp scale.
|
||||
float warp_scale;
|
||||
} pano;
|
||||
} openhmd;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -296,6 +299,12 @@ struct xrt_device
|
|||
uint32_t view_index,
|
||||
struct xrt_pose *out_pose);
|
||||
|
||||
bool (*compute_distortion)(struct xrt_device *xdev,
|
||||
int view,
|
||||
float u,
|
||||
float v,
|
||||
struct xrt_vec2_triplet *result);
|
||||
|
||||
/*!
|
||||
* Destroy device.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue