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));
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,17 +22,11 @@
|
||||||
DEBUG_GET_ONCE_NUM_OPTION(mesh_size, "XRT_MESH_SIZE", 64)
|
DEBUG_GET_ONCE_NUM_OPTION(mesh_size, "XRT_MESH_SIZE", 64)
|
||||||
|
|
||||||
|
|
||||||
/*
|
typedef bool (*func_calc)(struct xrt_device *xdev,
|
||||||
*
|
int view,
|
||||||
* Func running helpers.
|
float u,
|
||||||
*
|
float v,
|
||||||
*/
|
struct xrt_vec2_triplet *result);
|
||||||
|
|
||||||
typedef void (*func_cb)(struct u_uv_generator *gen,
|
|
||||||
int view,
|
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
struct u_uv_triplet *result);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
index_for(int row, int col, int stride, int offset)
|
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
|
void
|
||||||
run_func(struct u_uv_generator *gen,
|
run_func(struct xrt_device *xdev,
|
||||||
|
func_calc calc,
|
||||||
int num_views,
|
int num_views,
|
||||||
struct xrt_hmd_parts *target,
|
struct xrt_hmd_parts *target,
|
||||||
size_t num)
|
size_t num)
|
||||||
{
|
{
|
||||||
assert(gen != NULL);
|
assert(calc != NULL);
|
||||||
assert(num_views == 2);
|
assert(num_views == 2);
|
||||||
assert(num_views <= 2);
|
assert(num_views <= 2);
|
||||||
|
|
||||||
func_cb func = gen->calc;
|
|
||||||
|
|
||||||
size_t offset_vertices[2] = {0};
|
size_t offset_vertices[2] = {0};
|
||||||
size_t offset_indices[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_per_view = vert_rows * vert_cols;
|
||||||
size_t num_vertices = num_vertices_per_view * num_views;
|
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;
|
size_t num_floats = num_vertices * stride_in_floats;
|
||||||
|
|
||||||
float *verts = U_TYPED_ARRAY_CALLOC(float, num_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]
|
// Make the position in the range of [-1, 1]
|
||||||
verts[i + 0] = u * 2.0 - 1.0;
|
verts[i + 0] = u * 2.0 - 1.0;
|
||||||
verts[i + 1] = v * 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;
|
i += stride_in_floats;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ run_func(struct u_uv_generator *gen,
|
||||||
target->distortion.mesh.vertices = verts;
|
target->distortion.mesh.vertices = verts;
|
||||||
target->distortion.mesh.stride = stride_in_floats * sizeof(float);
|
target->distortion.mesh.stride = stride_in_floats * sizeof(float);
|
||||||
target->distortion.mesh.num_vertices = num_vertices;
|
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.indices = indices;
|
||||||
target->distortion.mesh.num_indices[0] = num_indices_per_view;
|
target->distortion.mesh.num_indices[0] = num_indices_per_view;
|
||||||
target->distortion.mesh.num_indices[1] = 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;
|
target->distortion.mesh.total_num_indices = num_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
u_distortion_mesh_from_gen(struct u_uv_generator *gen,
|
u_compute_distortion_vive(float aspect_x_over_y,
|
||||||
int num_views,
|
float grow_for_undistort,
|
||||||
struct xrt_hmd_parts *target)
|
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();
|
struct xrt_vec2 factor = {0.5 / (1.0 + grow_for_undistort),
|
||||||
run_func(gen, num_views, target, num);
|
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 m_vec2_mul
|
||||||
#define mul_scalar m_vec2_mul_scalar
|
#define mul_scalar m_vec2_mul_scalar
|
||||||
#define add m_vec2_add
|
#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 div_scalar m_vec2_div_scalar
|
||||||
#define len m_vec2_len
|
#define len m_vec2_len
|
||||||
|
|
||||||
/*!
|
bool
|
||||||
* @implements u_uv_generator
|
u_compute_distortion_panotools(struct u_panotools_values *values,
|
||||||
*/
|
float u,
|
||||||
struct panotools_state
|
float v,
|
||||||
|
struct xrt_vec2_triplet *result)
|
||||||
{
|
{
|
||||||
struct u_uv_generator base;
|
const struct u_panotools_values val = *values;
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
struct xrt_vec2 r = {u, v};
|
struct xrt_vec2 r = {u, v};
|
||||||
r = mul(r, val.viewport_size);
|
r = mul(r, val.viewport_size);
|
||||||
|
@ -208,61 +232,11 @@ panotools_calc(struct u_uv_generator *generator,
|
||||||
result->r = r_uv;
|
result->r = r_uv;
|
||||||
result->g = g_uv;
|
result->g = g_uv;
|
||||||
result->b = b_uv;
|
result->b = b_uv;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
bool
|
||||||
panotools_destroy(struct u_uv_generator *generator)
|
u_compute_distortion_none(float u, float v, struct xrt_vec2_triplet *result)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
result->r.x = u;
|
result->r.x = u;
|
||||||
result->r.y = v;
|
result->r.y = v;
|
||||||
|
@ -270,13 +244,27 @@ no_distortion_calc(struct u_uv_generator *generator,
|
||||||
result->g.y = v;
|
result->g.y = v;
|
||||||
result->b.x = u;
|
result->b.x = u;
|
||||||
result->b.y = v;
|
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
|
void
|
||||||
u_distortion_mesh_none(struct xrt_hmd_parts *target)
|
u_compute_distortion_mesh(struct xrt_device *xdev)
|
||||||
{
|
{
|
||||||
struct u_uv_generator gen;
|
struct xrt_hmd_parts *target = xdev->hmd;
|
||||||
gen.calc = no_distortion_calc;
|
func_calc calc = xdev->compute_distortion;
|
||||||
|
if (calc == NULL) {
|
||||||
run_func(&gen, 2, target, 8);
|
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" {
|
extern "C" {
|
||||||
#endif
|
#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.
|
* 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
|
* @ingroup aux_util
|
||||||
*/
|
*/
|
||||||
struct u_uv_triplet
|
bool
|
||||||
{
|
u_compute_distortion_panotools(struct u_panotools_values *values,
|
||||||
struct xrt_vec2 r, g, b;
|
float u,
|
||||||
};
|
float v,
|
||||||
|
struct xrt_vec2_triplet *result);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @interface u_uv_generator
|
* Identity distortion correction sets all result coordinates to u,v.
|
||||||
*
|
|
||||||
* Generator interface for building meshes, can be implemented by drivers for
|
|
||||||
* special meshes.
|
|
||||||
*
|
*
|
||||||
* @ingroup aux_util
|
* @ingroup aux_util
|
||||||
*/
|
*/
|
||||||
struct u_uv_generator
|
bool
|
||||||
{
|
u_compute_distortion_none(float u, float v, struct xrt_vec2_triplet *result);
|
||||||
void (*calc)(struct u_uv_generator *,
|
|
||||||
int view,
|
|
||||||
float u,
|
|
||||||
float v,
|
|
||||||
struct u_uv_triplet *result);
|
|
||||||
|
|
||||||
void (*destroy)(struct u_uv_generator *);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* 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
|
* @ingroup aux_util
|
||||||
* @public @memberof u_uv_generator
|
* @relatesalso xrt_device
|
||||||
* @relatesalso xrt_hmd_parts
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
u_distortion_mesh_from_gen(struct u_uv_generator *,
|
u_compute_distortion_mesh(struct xrt_device *xdev);
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "util/u_misc.h"
|
#include "util/u_misc.h"
|
||||||
#include "util/u_time.h"
|
#include "util/u_time.h"
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
|
#include "util/u_distortion_mesh.h"
|
||||||
|
|
||||||
#include "main/comp_compositor.h"
|
#include "main/comp_compositor.h"
|
||||||
|
|
||||||
|
@ -1160,6 +1161,31 @@ xrt_gfx_provider_create_native(struct xrt_device *xdev)
|
||||||
// Init the settings to default.
|
// Init the settings to default.
|
||||||
comp_settings_init(&c->settings, xdev);
|
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->last_frame_time_ns = os_monotonic_get_ns();
|
||||||
c->frame_overhead_ns = 2000000;
|
c->frame_overhead_ns = 2000000;
|
||||||
//! @todo set this to an estimate that's better than 6ms
|
//! @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_code = shaders_none_frag;
|
||||||
fragment_shader_size = sizeof(shaders_none_frag);
|
fragment_shader_size = sizeof(shaders_none_frag);
|
||||||
break;
|
break;
|
||||||
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
case XRT_DISTORTION_MODEL_OPENHMD:
|
||||||
fragment_shader_code = shaders_panotools_frag;
|
fragment_shader_code = shaders_panotools_frag;
|
||||||
fragment_shader_size = sizeof(shaders_panotools_frag);
|
fragment_shader_size = sizeof(shaders_panotools_frag);
|
||||||
break;
|
break;
|
||||||
|
@ -702,26 +702,30 @@ comp_distortion_update_uniform_buffer_warp(struct comp_distortion *d,
|
||||||
break;
|
break;
|
||||||
case XRT_DISTORTION_MODEL_MESHUV:
|
case XRT_DISTORTION_MODEL_MESHUV:
|
||||||
break;
|
break;
|
||||||
|
case XRT_DISTORTION_MODEL_NONE:
|
||||||
|
break;
|
||||||
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
||||||
|
break;
|
||||||
|
case XRT_DISTORTION_MODEL_OPENHMD:
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
* Pano vision fragment shader
|
* 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[0] = c->xdev->hmd->distortion.openhmd.distortion_k[0];
|
||||||
d->ubo_pano.hmd_warp_param[1] = c->xdev->hmd->distortion.pano.distortion_k[1];
|
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.pano.distortion_k[2];
|
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.pano.distortion_k[3];
|
d->ubo_pano.hmd_warp_param[3] = c->xdev->hmd->distortion.openhmd.distortion_k[3];
|
||||||
d->ubo_pano.aberr[0] = c->xdev->hmd->distortion.pano.aberration_k[0];
|
d->ubo_pano.aberr[0] = c->xdev->hmd->distortion.openhmd.aberration_k[0];
|
||||||
d->ubo_pano.aberr[1] = c->xdev->hmd->distortion.pano.aberration_k[1];
|
d->ubo_pano.aberr[1] = c->xdev->hmd->distortion.openhmd.aberration_k[1];
|
||||||
d->ubo_pano.aberr[2] = c->xdev->hmd->distortion.pano.aberration_k[2];
|
d->ubo_pano.aberr[2] = c->xdev->hmd->distortion.openhmd.aberration_k[2];
|
||||||
d->ubo_pano.aberr[3] = c->xdev->hmd->distortion.pano.aberration_k[3];
|
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][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[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][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.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[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.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));
|
memcpy(d->ubo_handle.mapped, &d->ubo_pano, sizeof(d->ubo_pano));
|
||||||
break;
|
break;
|
||||||
|
@ -859,7 +863,7 @@ comp_distortion_init_buffers(struct comp_distortion *d,
|
||||||
d->has_fragment_shader_ubo = true;
|
d->has_fragment_shader_ubo = true;
|
||||||
|
|
||||||
switch (d->distortion_model) {
|
switch (d->distortion_model) {
|
||||||
case XRT_DISTORTION_MODEL_PANOTOOLS:
|
case XRT_DISTORTION_MODEL_OPENHMD:
|
||||||
ubo_size = sizeof(d->ubo_pano);
|
ubo_size = sizeof(d->ubo_pano);
|
||||||
break;
|
break;
|
||||||
case XRT_DISTORTION_MODEL_MESHUV:
|
case XRT_DISTORTION_MODEL_MESHUV:
|
||||||
|
|
|
@ -194,10 +194,10 @@ dummy_hmd_create(void)
|
||||||
u_var_add_root(dh, "Dummy HMD", true);
|
u_var_add_root(dh, "Dummy HMD", true);
|
||||||
u_var_add_pose(dh, &dh->pose, "pose");
|
u_var_add_pose(dh, &dh->pose, "pose");
|
||||||
|
|
||||||
if (dh->base.hmd->distortion.preferred == XRT_DISTORTION_MODEL_NONE) {
|
dh->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
||||||
// Setup the distortion mesh.
|
dh->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_NONE;
|
||||||
u_distortion_mesh_none(dh->base.hmd);
|
dh->base.compute_distortion = NULL;
|
||||||
}
|
|
||||||
dh->base.device_type = XRT_DEVICE_TYPE_HMD;
|
dh->base.device_type = XRT_DEVICE_TYPE_HMD;
|
||||||
|
|
||||||
return &dh->base;
|
return &dh->base;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "util/u_misc.h"
|
#include "util/u_misc.h"
|
||||||
#include "util/u_device.h"
|
#include "util/u_device.h"
|
||||||
#include "util/u_time.h"
|
#include "util/u_time.h"
|
||||||
|
#include "util/u_distortion_mesh.h"
|
||||||
|
|
||||||
#include "hdk_device.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.
|
// 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.models = XRT_DISTORTION_MODEL_NONE;
|
||||||
hd->base.hmd->distortion.preferred = 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) {
|
// if (variant == HDK_VARIANT_1_3_1_4) {
|
||||||
// hd->base.hmd->distortion.models =
|
// hd->base.hmd->distortion.models =
|
||||||
// xrt_distortion_model(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
|
static bool
|
||||||
ns_mesh_calc(struct u_uv_generator *gen,
|
ns_mesh_calc(struct xrt_device *xdev,
|
||||||
int view,
|
int view,
|
||||||
float u,
|
float u,
|
||||||
float v,
|
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 uv = {u, v};
|
||||||
struct ns_uv warped_uv = {0.0f, 0.0f};
|
struct ns_uv warped_uv = {0.0f, 0.0f};
|
||||||
ns_display_uv_to_render_uv(uv, &warped_uv,
|
ns_display_uv_to_render_uv(uv, &warped_uv, &ns->eye_configs_v1[view]);
|
||||||
&mesh->ns->eye_configs_v1[view]);
|
|
||||||
|
|
||||||
result->r.x = warped_uv.u;
|
result->r.x = warped_uv.u;
|
||||||
result->r.y = warped_uv.v;
|
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->g.y = warped_uv.v;
|
||||||
result->b.x = warped_uv.u;
|
result->b.x = warped_uv.u;
|
||||||
result->b.y = warped_uv.v;
|
result->b.y = warped_uv.v;
|
||||||
}
|
return true;
|
||||||
|
|
||||||
static void
|
|
||||||
ns_mesh_destroy(struct u_uv_generator *gen)
|
|
||||||
{
|
|
||||||
struct ns_mesh *mesh = (struct ns_mesh *)gen;
|
|
||||||
(void)mesh; // Noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -301,15 +294,14 @@ ns_v2_fov_calculate(struct ns_hmd *ns, int eye_index)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
ns_v2_mesh_calc(struct u_uv_generator *gen,
|
ns_v2_mesh_calc(struct xrt_device *xdev,
|
||||||
int view,
|
int view,
|
||||||
float u,
|
float u,
|
||||||
float v,
|
float v,
|
||||||
struct u_uv_triplet *result)
|
struct xrt_vec2_triplet *result)
|
||||||
{
|
{
|
||||||
|
struct ns_hmd *ns = ns_hmd(xdev);
|
||||||
|
|
||||||
|
|
||||||
float x = 0.0f;
|
float x = 0.0f;
|
||||||
float y = 0.0f;
|
float y = 0.0f;
|
||||||
|
@ -317,16 +309,15 @@ ns_v2_mesh_calc(struct u_uv_generator *gen,
|
||||||
u = 1.0 - u;
|
u = 1.0 - u;
|
||||||
v = 1.0 - v;
|
v = 1.0 - v;
|
||||||
|
|
||||||
struct ns_mesh *mesh = ns_mesh(gen);
|
float L = ns->eye_configs_v2[view].fov.angle_left;
|
||||||
float L = mesh->ns->eye_configs_v2[view].fov.angle_left;
|
float R = ns->eye_configs_v2[view].fov.angle_right;
|
||||||
float R = mesh->ns->eye_configs_v2[view].fov.angle_right;
|
float T = ns->eye_configs_v2[view].fov.angle_up;
|
||||||
float T = mesh->ns->eye_configs_v2[view].fov.angle_up;
|
float B = ns->eye_configs_v2[view].fov.angle_down;
|
||||||
float B = mesh->ns->eye_configs_v2[view].fov.angle_down;
|
|
||||||
|
|
||||||
float x_ray = ns_v2_polyval2d(
|
float x_ray =
|
||||||
u, v, mesh->ns->eye_configs_v2[view].x_coefficients);
|
ns_v2_polyval2d(u, v, ns->eye_configs_v2[view].x_coefficients);
|
||||||
float y_ray = ns_v2_polyval2d(
|
float y_ray =
|
||||||
u, v, mesh->ns->eye_configs_v2[view].y_coefficients);
|
ns_v2_polyval2d(u, v, ns->eye_configs_v2[view].y_coefficients);
|
||||||
|
|
||||||
x = (x_ray + L) / (L - R);
|
x = (x_ray + L) / (L - R);
|
||||||
y = (y_ray + T) / (T - B);
|
y = (y_ray + T) / (T - B);
|
||||||
|
@ -338,6 +329,7 @@ ns_v2_mesh_calc(struct u_uv_generator *gen,
|
||||||
result->g.y = y;
|
result->g.y = y;
|
||||||
result->b.x = x;
|
result->b.x = x;
|
||||||
result->b.y = y;
|
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, 0);
|
||||||
ns_v2_fov_calculate(ns, 1);
|
ns_v2_fov_calculate(ns, 1);
|
||||||
|
|
||||||
|
ns->base.hmd->distortion.models = XRT_DISTORTION_MODEL_COMPUTE;
|
||||||
|
ns->base.hmd->distortion.preferred =
|
||||||
// Setup the distortion mesh.
|
XRT_DISTORTION_MODEL_COMPUTE;
|
||||||
struct ns_mesh mesh;
|
ns->base.compute_distortion = ns_v2_mesh_calc;
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// V1
|
// V1
|
||||||
|
@ -591,17 +573,10 @@ ns_hmd_create(const char *config_path, bool print_spew, bool print_debug)
|
||||||
ns->tracker = rs_6dof_create();
|
ns->tracker = rs_6dof_create();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ns->base.hmd->distortion.models = XRT_DISTORTION_MODEL_COMPUTE;
|
||||||
|
ns->base.hmd->distortion.preferred =
|
||||||
// Setup the distortion mesh.
|
XRT_DISTORTION_MODEL_COMPUTE;
|
||||||
struct ns_mesh mesh;
|
ns->base.compute_distortion = ns_mesh_calc;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If built, try to load the realsense tracker.
|
// If built, try to load the realsense tracker.
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "math/m_api.h"
|
#include "math/m_api.h"
|
||||||
#include "util/u_distortion_mesh.h"
|
|
||||||
#include "util/u_json.h"
|
#include "util/u_json.h"
|
||||||
#include "util/u_misc.h"
|
#include "util/u_misc.h"
|
||||||
#include "xrt/xrt_defines.h"
|
#include "xrt/xrt_defines.h"
|
||||||
|
@ -150,20 +149,6 @@ struct ns_hmd
|
||||||
// be an enum or something
|
// 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
|
* Functions
|
||||||
|
@ -181,17 +166,6 @@ ns_hmd(struct xrt_device *xdev)
|
||||||
return (struct ns_hmd *)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.
|
* Convert the display UV to the render UV using the distortion mesh.
|
||||||
*
|
*
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "openhmd.h"
|
#include "openhmd.h"
|
||||||
|
|
||||||
#include "math/m_api.h"
|
#include "math/m_api.h"
|
||||||
|
#include "math/m_vec2.h"
|
||||||
#include "xrt/xrt_device.h"
|
#include "xrt/xrt_device.h"
|
||||||
#include "util/u_var.h"
|
#include "util/u_var.h"
|
||||||
#include "util/u_misc.h"
|
#include "util/u_misc.h"
|
||||||
|
@ -372,6 +373,97 @@ get_info(struct oh_device *ohd, const char *prod)
|
||||||
return info;
|
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 *
|
struct oh_device *
|
||||||
oh_device_create(ohmd_context *ctx,
|
oh_device_create(ohmd_context *ctx,
|
||||||
ohmd_device *dev,
|
ohmd_device *dev,
|
||||||
|
@ -429,19 +521,17 @@ oh_device_create(ohmd_context *ctx,
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Main display.
|
// 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].w_pixels = info.display.w_pixels;
|
||||||
ohd->base.hmd->screens[0].h_pixels = info.display.h_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->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.openhmd.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.openhmd.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.openhmd.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.openhmd.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.openhmd.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.openhmd.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.openhmd.aberration_k[2] = info.pano_aberration_k[2];
|
||||||
ohd->base.hmd->distortion.pano.warp_scale = info.pano_warp_scale;
|
ohd->base.hmd->distortion.openhmd.warp_scale = info.pano_warp_scale;
|
||||||
|
|
||||||
// Left
|
// Left
|
||||||
ohd->base.hmd->views[0].display.w_meters = info.views[0].display.w_meters;
|
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;
|
ohd->base.hmd->views[1].rot = u_device_rotation_ident;
|
||||||
// clang-format on
|
// 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.
|
// Which blend modes does the device support.
|
||||||
ohd->base.hmd->blend_mode = XRT_BLEND_MODE_OPAQUE;
|
ohd->base.hmd->blend_mode = XRT_BLEND_MODE_OPAQUE;
|
||||||
if (info.quirks.video_see_through) {
|
if (info.quirks.video_see_through) {
|
||||||
|
@ -478,11 +574,6 @@ oh_device_create(ohmd_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.quirks.video_distortion_vive) {
|
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
|
// clang-format off
|
||||||
// These need to be acquired from the vive config
|
// These need to be acquired from the vive config
|
||||||
ohd->base.hmd->distortion.vive.aspect_x_over_y = 0.8999999761581421f;
|
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][1] = -0.04517245633373419f;
|
||||||
ohd->base.hmd->distortion.vive.coefficients[1][2][2] = -0.0928909347763f;
|
ohd->base.hmd->distortion.vive.coefficients[1][2][2] = -0.0928909347763f;
|
||||||
// clang-format on
|
// 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) {
|
if (info.quirks.video_distortion_none) {
|
||||||
ohd->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
ohd->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
||||||
ohd->base.hmd->distortion.preferred = 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) {
|
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;
|
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_root(ohd, "OpenHMD Wrapper", true);
|
||||||
u_var_add_ro_text(ohd, ohd->base.str, "Card");
|
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;
|
return ohd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,7 @@ struct psvr_device
|
||||||
int last_packet;
|
int last_packet;
|
||||||
} calibration;
|
} calibration;
|
||||||
|
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool last_frame;
|
bool last_frame;
|
||||||
|
@ -137,6 +138,9 @@ struct psvr_device
|
||||||
struct xrt_quat rot;
|
struct xrt_quat rot;
|
||||||
} fusion;
|
} fusion;
|
||||||
#endif
|
#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);
|
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.update_inputs = psvr_device_update_inputs;
|
||||||
psvr->base.get_tracked_pose = psvr_device_get_tracked_pose;
|
psvr->base.get_tracked_pose = psvr_device_get_tracked_pose;
|
||||||
psvr->base.get_view_pose = psvr_device_get_view_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.destroy = psvr_device_destroy;
|
||||||
psvr->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE;
|
psvr->base.inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE;
|
||||||
psvr->base.name = XRT_DEVICE_GENERIC_HMD;
|
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.x = vals.viewport_size.x / 2.0;
|
||||||
vals.lens_center.y = vals.viewport_size.y / 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
|
#if 1
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "util/u_misc.h"
|
#include "util/u_misc.h"
|
||||||
#include "util/u_time.h"
|
#include "util/u_time.h"
|
||||||
#include "util/u_device.h"
|
#include "util/u_device.h"
|
||||||
|
#include "util/u_distortion_mesh.h"
|
||||||
|
|
||||||
#include "../auxiliary/os/os_time.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);
|
_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
|
static bool
|
||||||
_create_hmd_device(struct survive_system *sys, enum VIVE_VARIANT variant)
|
_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.models =
|
||||||
survive->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_VIVE;
|
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.orientation_tracking_supported = true;
|
||||||
survive->base.position_tracking_supported = true;
|
survive->base.position_tracking_supported = true;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "util/u_debug.h"
|
#include "util/u_debug.h"
|
||||||
#include "util/u_var.h"
|
#include "util/u_var.h"
|
||||||
#include "util/u_time.h"
|
#include "util/u_time.h"
|
||||||
|
#include "util/u_distortion_mesh.h"
|
||||||
|
|
||||||
#include "math/m_api.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;
|
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 *
|
struct vive_device *
|
||||||
vive_device_create(struct os_hid_device *mainboard_dev,
|
vive_device_create(struct os_hid_device *mainboard_dev,
|
||||||
struct os_hid_device *sensors_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->watchman_dev = watchman_dev;
|
||||||
d->variant = variant;
|
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);
|
vive_init_defaults(d);
|
||||||
|
|
||||||
switch (variant) {
|
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.
|
// Init here.
|
||||||
m_imu_3dof_init(&d->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_20MS);
|
m_imu_3dof_init(&d->fusion, M_IMU_3DOF_USE_GRAVITY_DUR_20MS);
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,11 @@ enum xrt_distortion_model
|
||||||
{
|
{
|
||||||
// clang-format off
|
// clang-format off
|
||||||
XRT_DISTORTION_MODEL_NONE = 1 << 0,
|
XRT_DISTORTION_MODEL_NONE = 1 << 0,
|
||||||
XRT_DISTORTION_MODEL_PANOTOOLS = 1 << 1,
|
XRT_DISTORTION_MODEL_COMPUTE = 1 << 1,
|
||||||
XRT_DISTORTION_MODEL_VIVE = 1 << 2,
|
XRT_DISTORTION_MODEL_PANOTOOLS = 1 << 2,
|
||||||
XRT_DISTORTION_MODEL_MESHUV = 1 << 3,
|
XRT_DISTORTION_MODEL_VIVE = 1 << 3,
|
||||||
|
XRT_DISTORTION_MODEL_MESHUV = 1 << 4,
|
||||||
|
XRT_DISTORTION_MODEL_OPENHMD = 1 << 5,
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +131,16 @@ struct xrt_vec2
|
||||||
float y;
|
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.
|
* A 3 element vector with single floats.
|
||||||
*
|
*
|
||||||
|
|
|
@ -60,13 +60,16 @@ struct xrt_view
|
||||||
} display;
|
} display;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Position in meters relative to display origin, before any rotation
|
* Position relative to display origin, before any rotation is applied
|
||||||
* is applied by xrt_view::rot.
|
* by xrt_view::rot. note: not set by most drivers, used only for
|
||||||
|
* panotools/ohmd distortion
|
||||||
*/
|
*/
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
float x_meters;
|
float x_meters;
|
||||||
float y_meters;
|
float y_meters;
|
||||||
|
int x_pixels;
|
||||||
|
int y_pixels;
|
||||||
} lens_center;
|
} lens_center;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -132,7 +135,7 @@ struct xrt_hmd_parts
|
||||||
float aberration_k[4];
|
float aberration_k[4];
|
||||||
//! Panotools warp scale.
|
//! Panotools warp scale.
|
||||||
float warp_scale;
|
float warp_scale;
|
||||||
} pano;
|
} openhmd;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -296,6 +299,12 @@ struct xrt_device
|
||||||
uint32_t view_index,
|
uint32_t view_index,
|
||||||
struct xrt_pose *out_pose);
|
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.
|
* Destroy device.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue