u/distortion: Make Vive & Index distortion center per channel

This commit is contained in:
Jakob Bornecrantz 2021-01-23 23:19:06 +00:00
parent b2569907b5
commit 0c2d07808c
5 changed files with 65 additions and 88 deletions

View file

@ -124,40 +124,38 @@ run_func(struct xrt_device *xdev, func_calc calc, int num_views, struct xrt_hmd_
bool
u_compute_distortion_vive(struct u_vive_values *values, float u, float v, struct xrt_uv_triplet *result)
{
// Reading the whole struct like this gives the compiler more opportunity to optimize, yes really.
const struct u_vive_values val = *values;
struct xrt_vec2 factor = {0.5 / (1.0 + val.grow_for_undistort),
val.aspect_x_over_y * 0.5 / (1.0 + val.grow_for_undistort)};
struct xrt_vec2 texCoord = {2.0 * u - 1.0, 2.0 * v - 1.0};
// Results r/g/b.
struct xrt_vec2 tc[3];
texCoord.y /= val.aspect_x_over_y;
texCoord.x -= val.center[0];
texCoord.y -= val.center[1];
// Dear compiler, please vectorize.
for (int i = 0; i < 3; i++) {
struct xrt_vec2 texCoord = {2.0 * u - 1.0, 2.0 * v - 1.0};
float r2 = m_vec2_dot(texCoord, texCoord);
texCoord.y /= val.aspect_x_over_y;
texCoord.x -= val.center[i].x;
texCoord.y -= val.center[i].y;
float r2 = m_vec2_dot(texCoord, texCoord);
float d_inv =
((r2 * val.coefficients[2][i] + val.coefficients[1][i]) * r2 + val.coefficients[0][i]) * r2 + 1.0;
float d = 1.0 / d_inv;
struct xrt_vec3 d_inv = {
((r2 * val.coefficients[2][0] + val.coefficients[1][0]) * r2 + val.coefficients[0][0]) * r2 + 1.0,
((r2 * val.coefficients[2][1] + val.coefficients[1][1]) * r2 + val.coefficients[0][1]) * r2 + 1.0,
((r2 * val.coefficients[2][2] + val.coefficients[1][2]) * r2 + val.coefficients[0][2]) * r2 + 1.0};
struct xrt_vec2 offset = {0.5, 0.5};
struct xrt_vec3 d = {1.0 / d_inv.x, 1.0 / d_inv.y, 1.0 / d_inv.z};
tc[i].x = offset.x + (texCoord.x * d + val.center[i].x) * factor.x;
tc[i].y = offset.y + (texCoord.y * d + val.center[i].y) * factor.y;
}
struct xrt_vec2 offset = {0.5, 0.5};
result->r = tc[0];
result->g = tc[1];
result->b = tc[2];
struct xrt_vec2 tc_r = {offset.x + (texCoord.x * d.x + val.center[0]) * factor.x,
offset.y + (texCoord.y * d.x + val.center[1]) * factor.y};
struct xrt_vec2 tc_g = {offset.x + (texCoord.x * d.y + val.center[0]) * factor.x,
offset.y + (texCoord.y * d.y + val.center[1]) * factor.y};
struct xrt_vec2 tc_b = {offset.x + (texCoord.x * d.z + val.center[0]) * factor.x,
offset.y + (texCoord.y * d.z + val.center[1]) * factor.y};
result->r = tc_r;
result->g = tc_g;
result->b = tc_b;
return true;
}

View file

@ -70,13 +70,12 @@ struct u_vive_values
float aspect_x_over_y;
float grow_for_undistort;
//! Left/right
float undistort_r2_cutoff;
//! Left/right, x/y
float center[2];
//! r/g/b
struct xrt_vec2 center[3];
//! left/right, r/g/b, a/b/c
//! r/g/b, a/b/c
float coefficients[3][3];
};

View file

@ -615,10 +615,18 @@ oh_device_create(ohmd_context *ctx, ohmd_device *dev, const char *prod)
}
ohd->distortion.vive[0].undistort_r2_cutoff = 1.11622154712677f;
ohd->distortion.vive[1].undistort_r2_cutoff = 1.101870775222778f;
ohd->distortion.vive[0].center[0] = 0.08946027017045266f;
ohd->distortion.vive[0].center[1] = -0.009002181016260827f;
ohd->distortion.vive[1].center[0] = -0.08933516629552526f;
ohd->distortion.vive[1].center[1] = -0.006014565287238661f;
ohd->distortion.vive[0].center[0].x = 0.08946027017045266f;
ohd->distortion.vive[0].center[0].y = -0.009002181016260827f;
ohd->distortion.vive[0].center[1].x = 0.08946027017045266f;
ohd->distortion.vive[0].center[1].y = -0.009002181016260827f;
ohd->distortion.vive[0].center[2].x = 0.08946027017045266f;
ohd->distortion.vive[0].center[2].y = -0.009002181016260827f;
ohd->distortion.vive[1].center[0].x = -0.08933516629552526f;
ohd->distortion.vive[1].center[0].y = -0.006014565287238661f;
ohd->distortion.vive[1].center[1].x = -0.08933516629552526f;
ohd->distortion.vive[1].center[1].y = -0.006014565287238661f;
ohd->distortion.vive[1].center[2].x = -0.08933516629552526f;
ohd->distortion.vive[1].center[2].y = -0.006014565287238661f;
// left
// green

View file

@ -910,23 +910,6 @@ _get_color_coeffs(struct u_vive_values *values, const cJSON *coeffs, uint8_t eye
}
}
static void
_get_color_coeffs_lookup(
struct u_vive_values *values, const cJSON *eye_json, const char *name, uint8_t eye, uint8_t channel)
{
const cJSON *distortion = cJSON_GetObjectItemCaseSensitive(eye_json, name);
if (distortion == NULL) {
return;
}
const cJSON *coeffs = cJSON_GetObjectItemCaseSensitive(distortion, "coeffs");
if (coeffs == NULL) {
return;
}
_get_color_coeffs(values, coeffs, eye, channel);
}
static void
get_distortion_properties(struct survive_device *d, const cJSON *eye_transform_json, uint8_t eye)
{
@ -946,23 +929,26 @@ get_distortion_properties(struct survive_device *d, const cJSON *eye_transform_j
d->distortion[eye].undistort_r2_cutoff = _json_get_float(eye_json, "undistort_r2_cutoff");
// clang-format on
const cJSON *distortion = cJSON_GetObjectItemCaseSensitive(eye_json, "distortion");
if (distortion != NULL) {
// TODO: store center per color
// clang-format off
d->distortion[eye].center[0] = _json_get_float(distortion, "center_x");
d->distortion[eye].center[1] = _json_get_float(distortion, "center_y");
// clang-format on
const char *names[3] = {
"distortion_red",
"distortion",
"distortion_blue",
};
for (int i = 0; i < 3; i++) {
const cJSON *distortion = cJSON_GetObjectItemCaseSensitive(eye_json, names[i]);
if (distortion == NULL) {
continue;
}
d->distortion[eye].center[i].x = _json_get_float(distortion, "center_x");
d->distortion[eye].center[i].y = _json_get_float(distortion, "center_y");
// green
const cJSON *coeffs = cJSON_GetObjectItemCaseSensitive(distortion, "coeffs");
if (coeffs != NULL) {
_get_color_coeffs(&d->distortion[eye], coeffs, eye, 1);
_get_color_coeffs(&d->distortion[eye], coeffs, eye, i);
}
}
_get_color_coeffs_lookup(&d->distortion[eye], eye_json, "distortion_red", eye, 0);
_get_color_coeffs_lookup(&d->distortion[eye], eye_json, "distortion_blue", eye, 2);
}
static bool

View file

@ -45,23 +45,6 @@ _get_color_coeffs(struct u_vive_values *values, const cJSON *coeffs, uint8_t eye
}
}
static void
_get_color_coeffs_lookup(
struct u_vive_values *values, const cJSON *eye_json, const char *name, uint8_t eye, uint8_t channel)
{
const cJSON *distortion = cJSON_GetObjectItemCaseSensitive(eye_json, name);
if (distortion == NULL) {
return;
}
const cJSON *coeffs = cJSON_GetObjectItemCaseSensitive(distortion, "coeffs");
if (coeffs == NULL) {
return;
}
_get_color_coeffs(values, coeffs, eye, channel);
}
static void
_get_pose_from_pos_x_z(const cJSON *obj, struct xrt_pose *pose)
{
@ -92,23 +75,26 @@ _get_distortion_properties(struct vive_device *d, const cJSON *eye_transform_jso
JSON_FLOAT(eye_json, "undistort_r2_cutoff", &d->distortion[eye].undistort_r2_cutoff);
// clang-format on
const cJSON *distortion = cJSON_GetObjectItemCaseSensitive(eye_json, "distortion");
if (distortion != NULL) {
// TODO: store center per color
// clang-format off
JSON_FLOAT(distortion, "center_x", &d->distortion[eye].center[0]);
JSON_FLOAT(distortion, "center_y", &d->distortion[eye].center[1]);
// clang-format on
const char *names[3] = {
"distortion_red",
"distortion",
"distortion_blue",
};
for (int i = 0; i < 3; i++) {
const cJSON *distortion = cJSON_GetObjectItemCaseSensitive(eye_json, names[i]);
if (distortion == NULL) {
continue;
}
JSON_FLOAT(distortion, "center_x", &d->distortion[eye].center[i].x);
JSON_FLOAT(distortion, "center_y", &d->distortion[eye].center[i].y);
// green
const cJSON *coeffs = cJSON_GetObjectItemCaseSensitive(distortion, "coeffs");
if (coeffs != NULL) {
_get_color_coeffs(&d->distortion[eye], coeffs, eye, 1);
_get_color_coeffs(&d->distortion[eye], coeffs, eye, i);
}
}
_get_color_coeffs_lookup(&d->distortion[eye], eye_json, "distortion_red", eye, 0);
_get_color_coeffs_lookup(&d->distortion[eye], eye_json, "distortion_blue", eye, 2);
}
static void