From b74e7c74e26e25d773a334bf0484b3ed13568b9d Mon Sep 17 00:00:00 2001 From: Ryan Pavlik <ryan.pavlik@collabora.com> Date: Wed, 13 Mar 2019 13:20:10 -0500 Subject: [PATCH] d/hdk: Handle more models --- src/xrt/drivers/hdk/hdk_device.cpp | 135 +++++++++++++++++++++++------ src/xrt/drivers/hdk/hdk_prober.c | 6 +- 2 files changed, 112 insertions(+), 29 deletions(-) diff --git a/src/xrt/drivers/hdk/hdk_device.cpp b/src/xrt/drivers/hdk/hdk_device.cpp index 8a0226d99..8db7f31cf 100644 --- a/src/xrt/drivers/hdk/hdk_device.cpp +++ b/src/xrt/drivers/hdk/hdk_device.cpp @@ -210,18 +210,46 @@ hdk_device_create(hid_device *dev, hd->print_spew = print_spew; hd->print_debug = print_debug; - if (variant != HDK_VARIANT_2) { - HDK_ERROR(hd, - "Only recognize HDK2 for now, and this isn't it!"); + if (variant == HDK_UNKNOWN) { + HDK_ERROR(hd, "Don't know which HDK variant this is."); hdk_device_destroy(&hd->base); return NULL; } - // Treat as symmetric right now. - const double FOV = 92.0 / 180 * M_PI; + + double hFOV; + double vFOV; + double hCOP = 0.5; + double vCOP = 0.5; + + switch (variant) { + + + case HDK_VARIANT_1_2: + // Distortion optional - this is for no distortion. + hFOV = 90; + vFOV = 96.73; + break; + + case HDK_VARIANT_1_3_1_4: + // Non-mesh distortion. + hFOV = 90; + vFOV = 96.73; + hCOP = 0.529; + break; + + case HDK_VARIANT_2: + // Mesh distortion (ideally) + hFOV = vFOV = 92.0; + break; + } + + constexpr double DEGREES_TO_RADIANS = M_PI / 180.0; + { /* right eye */ - math_compute_fovs(1.0, 0.5, FOV, 1, 0.5, FOV, + math_compute_fovs(1.0, hCOP, hFOV * DEGREES_TO_RADIANS, 1, vCOP, + vFOV * DEGREES_TO_RADIANS, &hd->base.views[1].fov); } { @@ -236,35 +264,86 @@ hdk_device_create(hid_device *dev, -hd->base.views[1].fov.angle_left; } - // HDK2 is upside down :facepalm: + switch (variant) { + case HDK_VARIANT_2: { + constexpr int panel_w = 1080; + constexpr int panel_h = 1200; + // Padding needed horizontally per side. + constexpr int horiz_padding = (panel_h - panel_w) / 2; + // HDK2 is upside down :facepalm: - // clang-format off - // Main display. - hd->base.screens[0].w_pixels = 2160; - hd->base.screens[0].h_pixels = 1200; + // clang-format off + // Main display. + hd->base.screens[0].w_pixels = panel_w * 2; + hd->base.screens[0].h_pixels = panel_h; - // Left - hd->base.views[0].display.w_pixels = 1080; - hd->base.views[0].display.h_pixels = 1200; - hd->base.views[0].viewport.x_pixels = 1080; // right half of display - hd->base.views[0].viewport.y_pixels = 60; - hd->base.views[0].viewport.w_pixels = 1080; - hd->base.views[0].viewport.h_pixels = 1080; - hd->base.views[0].rot = u_device_rotation_180; + // Left + hd->base.views[0].display.w_pixels = panel_w; + hd->base.views[0].display.h_pixels = panel_h; + hd->base.views[0].viewport.x_pixels = panel_w; // right half of display + hd->base.views[0].viewport.y_pixels = horiz_padding; + hd->base.views[0].viewport.w_pixels = panel_w; + hd->base.views[0].viewport.h_pixels = panel_w; + hd->base.views[0].rot = u_device_rotation_180; - // Right - hd->base.views[1].display.w_pixels = 1080; - hd->base.views[1].display.h_pixels = 1200; - hd->base.views[1].viewport.x_pixels = 0; - hd->base.views[1].viewport.y_pixels = 60; - hd->base.views[1].viewport.w_pixels = 1080; - hd->base.views[1].viewport.h_pixels = 1080; - hd->base.views[1].rot = u_device_rotation_180; + // Right + hd->base.views[1].display.w_pixels = panel_w; + hd->base.views[1].display.h_pixels = panel_h; + hd->base.views[1].viewport.x_pixels = 0; + hd->base.views[1].viewport.y_pixels = horiz_padding; + hd->base.views[1].viewport.w_pixels = panel_w; + hd->base.views[1].viewport.h_pixels = panel_w; + hd->base.views[1].rot = u_device_rotation_180; + // clang-format on + break; + } + case HDK_VARIANT_1_3_1_4: + // fallthrough intentional + case HDK_VARIANT_1_2: { + // 1080x1920 screen, with the top at the left. + + constexpr int panel_w = 1080; + constexpr int panel_h = 1920; + constexpr int panel_half_h = panel_h / 2; + // clang-format off + // Main display. + hd->base.screens[0].w_pixels = panel_w; + hd->base.screens[0].h_pixels = panel_h; + + // Left + hd->base.views[0].display.w_pixels = panel_half_h; + hd->base.views[0].display.h_pixels = panel_w; + hd->base.views[0].viewport.x_pixels = 0; + hd->base.views[0].viewport.y_pixels = 0;// top half of display + hd->base.views[0].viewport.w_pixels = panel_w; + hd->base.views[0].viewport.h_pixels = panel_half_h; + hd->base.views[0].rot = u_device_rotation_left; + + // Right + hd->base.views[1].display.w_pixels = panel_half_h; + hd->base.views[1].display.h_pixels = panel_w; + hd->base.views[1].viewport.x_pixels = 0; + hd->base.views[1].viewport.y_pixels = panel_half_h; // bottom half of display + hd->base.views[1].viewport.w_pixels = panel_w; + hd->base.views[1].viewport.h_pixels = panel_half_h; + hd->base.views[1].rot = u_device_rotation_left; + // clang-format on + break; + } + } // Distortion + // "None" is correct or at least acceptable for 1.2. + // We have coefficients for 1.3/1.4, though the mesh is better. + // We only have a mesh for 2, so use "none" there until it's supported. hd->base.distortion.models = XRT_DISTORTION_MODEL_NONE; hd->base.distortion.preferred = XRT_DISTORTION_MODEL_NONE; - // clang-format on + // if (variant == HDK_VARIANT_1_3_1_4) { + // hd->base.distortion.models = + // xrt_distortion_model(hd->base.distortion.models | + // XRT_DISTORTION_MODEL_PANOTOOLS); + // hd->base.distortion.preferred = XRT_DISTORTION_MODEL_PANOTOOLS; + // } if (hd->print_debug) { diff --git a/src/xrt/drivers/hdk/hdk_prober.c b/src/xrt/drivers/hdk/hdk_prober.c index 5145992db..2ca54ddb5 100644 --- a/src/xrt/drivers/hdk/hdk_prober.c +++ b/src/xrt/drivers/hdk/hdk_prober.c @@ -48,7 +48,8 @@ hdk_prober_destroy(struct xrt_prober *p) HDK_MAKE_STRING(HDK2_PRODUCT_STRING, "OSVR HDK 2"); HDK_MAKE_STRING(HDK13_PRODUCT_STRING, "OSVR HDK 1.3/1.4"); - +static const wchar_t HDK1_PRODUCT_STRING_W[] = L"OSVR HDK 1.x"; +static const char HDK12_PRODUCT_STRING[] = "OSVR HDK 1.2"; static const uint16_t HDK_VID = 0x1532; static const uint16_t HDK_PID = 0x0b00; @@ -76,6 +77,9 @@ hdk_prober_autoprobe(struct xrt_prober *p) if (0 == wcscmp(HDK2_PRODUCT_STRING_W, devs->product_string)) { variant = HDK_VARIANT_2; name = HDK2_PRODUCT_STRING; + } else if (0 == wcscmp(HDK1_PRODUCT_STRING_W, devs->product_string)) { + variant = HDK_VARIANT_1_2; + name = HDK12_PRODUCT_STRING; } else { //! @todo just assuming anything else is 1.3 for now (void)HDK13_PRODUCT_STRING_W;