Monado OpenXR Runtime
oh_device.c File Reference

Adaptor to a OpenHMD device. More...

#include "xrt/xrt_config_os.h"
#include "xrt/xrt_device.h"
#include "xrt/xrt_prober.h"
#include "os/os_time.h"
#include "math/m_mathinclude.h"
#include "math/m_api.h"
#include "math/m_vec2.h"
#include "util/u_var.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "util/u_device.h"
#include "util/u_time.h"
#include "util/u_distortion_mesh.h"
#include "util/u_logging.h"
#include "oh_device.h"
#include "openhmd.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
Include dependency graph for oh_device.c:

Data Structures

struct  openhmd_values
 
struct  oh_system
 
struct  oh_device
 
struct  display_info
 
struct  device_info
 

Macros

#define SET_TOUCH_INPUT(NAME)   (ohd->base.inputs[OCULUS_TOUCH_##NAME].name = XRT_INPUT_TOUCH_##NAME)
 
#define PRESS_FLOAT_THRESHOLD   0.95
 
#define FLOAT_TO_DIGITAL_THRESHOLD   0.5
 
#define CONTROL_MAPPING_SIZE   16
 
#define CASE_VEC1(OHMD_CONTROL)
 
#define CASE_VEC1_OR_DIGITAL(OHMD_CONTROL, MAKE_DIGITAL)
 
#define CASE_DIGITAL(OHMD_CONTROL, THRESHOLD)
 
#define CASE_VEC2_X(OHMD_CONTROL)
 
#define CASE_VEC2_Y(OHMD_CONTROL)
 
#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
 

Enumerations

enum  input_indices {
  SIMPLE_SELECT_CLICK = 0 , SIMPLE_MENU_CLICK , GRIP_POSE , AIM_POSE ,
  OCULUS_TOUCH_X_CLICK , OCULUS_TOUCH_X_TOUCH , OCULUS_TOUCH_Y_CLICK , OCULUS_TOUCH_Y_TOUCH ,
  OCULUS_TOUCH_MENU_CLICK , OCULUS_TOUCH_A_CLICK , OCULUS_TOUCH_A_TOUCH , OCULUS_TOUCH_B_CLICK ,
  OCULUS_TOUCH_B_TOUCH , OCULUS_TOUCH_SYSTEM_CLICK , OCULUS_TOUCH_SQUEEZE_VALUE , OCULUS_TOUCH_TRIGGER_TOUCH ,
  OCULUS_TOUCH_TRIGGER_VALUE , OCULUS_TOUCH_THUMBSTICK_CLICK , OCULUS_TOUCH_THUMBSTICK_TOUCH , OCULUS_TOUCH_THUMBSTICK ,
  OCULUS_TOUCH_THUMBREST_TOUCH , INPUT_INDICES_LAST
}
 
enum  openhmd_device_type {
  OPENHMD_GENERIC_HMD , OPENHMD_GENERIC_CONTROLLER , OPENHMD_OCULUS_RIFT_HMD , OPENHMD_OCULUS_RIFT_CONTROLLER ,
  OPENHMD_GENERIC_TRACKER
}
 
enum  OHMD_DEVICE_INDEX { OHMD_HMD_INDEX = 0 , OHMD_LEFT_INDEX , OHMD_RIGHT_INDEX , OHMD_FIRST_TRACKER_INDEX }
 

Functions

static struct oh_deviceoh_device (struct xrt_device *xdev)
 
static void oh_device_destroy (struct xrt_device *xdev)
 
static void update_ohmd_controller (struct oh_device *ohd, int control_count, float *control_state)
 
static xrt_result_t oh_device_update_inputs (struct xrt_device *xdev)
 
static void oh_device_set_output (struct xrt_device *xdev, enum xrt_output_name name, const union xrt_output_value *value)
 
static bool check_head_pose (struct oh_device *ohd, enum xrt_input_name name)
 
static bool check_controller_pose (struct oh_device *ohd, enum xrt_input_name name)
 
static bool check_tracker_pose (struct oh_device *ohd, enum xrt_input_name name)
 
static void oh_device_get_tracked_pose (struct xrt_device *xdev, enum xrt_input_name name, int64_t at_timestamp_ns, struct xrt_space_relation *out_relation)
 
static struct device_info get_info (ohmd_device *dev, const char *prod)
 
static bool u_compute_distortion_openhmd (struct openhmd_values *values, float u, float v, struct xrt_uv_triplet *result)
 
static bool compute_distortion_openhmd (struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *result)
 
static bool compute_distortion_vive (struct xrt_device *xdev, uint32_t view, float u, float v, struct xrt_uv_triplet *result)
 
static void swap (int *a, int *b)
 
static struct oh_devicecreate_hmd (ohmd_context *ctx, int device_idx, int device_flags)
 
static struct oh_devicecreate_controller (ohmd_context *ctx, int device_idx, int device_flags, enum xrt_device_type device_type)
 
int oh_device_create (ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
 

Detailed Description

Adaptor to a OpenHMD device.

Author
Jakob Bornecrantz jakob.nosp@m.@col.nosp@m.labor.nosp@m.a.co.nosp@m.m

Macro Definition Documentation

◆ CASE_DIGITAL

#define CASE_DIGITAL (   OHMD_CONTROL,
  THRESHOLD 
)
Value:
case OHMD_CONTROL: \
if (ohd->controls_mapping[OHMD_CONTROL] == INPUT_INDICES_LAST) { \
break; \
} \
if (control_state[i] != ohd->last_control_state[i]) { \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].value.boolean = \
control_state[i] > THRESHOLD; \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].timestamp = ts; \
} \
break;

◆ CASE_VEC1

#define CASE_VEC1 (   OHMD_CONTROL)
Value:
case OHMD_CONTROL: \
if (ohd->controls_mapping[OHMD_CONTROL] == INPUT_INDICES_LAST) { \
break; \
} \
if (control_state[i] != ohd->last_control_state[i]) { \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].value.vec1.x = control_state[i]; \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].timestamp = ts; \
} \
break;

◆ CASE_VEC1_OR_DIGITAL

#define CASE_VEC1_OR_DIGITAL (   OHMD_CONTROL,
  MAKE_DIGITAL 
)
Value:
case OHMD_CONTROL: \
if (ohd->controls_mapping[OHMD_CONTROL] == INPUT_INDICES_LAST) { \
break; \
} \
if (MAKE_DIGITAL) { \
if ((control_state[i] > FLOAT_TO_DIGITAL_THRESHOLD) != \
(ohd->last_control_state[i] > FLOAT_TO_DIGITAL_THRESHOLD)) { \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].value.vec1.x = \
control_state[i] > FLOAT_TO_DIGITAL_THRESHOLD; \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].timestamp = ts; \
} \
} else { \
if (control_state[i] != ohd->last_control_state[i]) { \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].value.vec1.x = control_state[i]; \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].timestamp = ts; \
} \
} \
break;

◆ CASE_VEC2_X

#define CASE_VEC2_X (   OHMD_CONTROL)
Value:
case OHMD_CONTROL: \
if (ohd->controls_mapping[OHMD_CONTROL] == INPUT_INDICES_LAST) { \
break; \
} \
if (control_state[i] != ohd->last_control_state[i]) { \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].value.vec2.x = control_state[i]; \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].timestamp = ts; \
} \
break;

◆ CASE_VEC2_Y

#define CASE_VEC2_Y (   OHMD_CONTROL)
Value:
case OHMD_CONTROL: \
if (ohd->controls_mapping[OHMD_CONTROL] == INPUT_INDICES_LAST) { \
break; \
} \
if (control_state[i] != ohd->last_control_state[i]) { \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].value.vec2.y = control_state[i]; \
ohd->base.inputs[ohd->controls_mapping[OHMD_CONTROL]].timestamp = ts; \
} \
break;

Function Documentation

◆ create_controller()

static struct oh_device * create_controller ( ohmd_context *  ctx,
int  device_idx,
int  device_flags,
enum xrt_device_type  device_type 
)
static
Todo:
Generic tracker input profile?

References xrt_device::input_count, and xrt_device::output_count.

◆ create_hmd()

static struct oh_device * create_hmd ( ohmd_context *  ctx,
int  device_idx,
int  device_flags 
)
static
Todo:
These values are most likely wrong, needs to be transposed and correct channel.

References get_info().

◆ get_info()

static struct device_info get_info ( ohmd_device *  dev,
const char *  prod 
)
static
Todo:
This are probably all wrong!

References time_s_to_ns().

Referenced by create_hmd().

◆ oh_device_create()

int oh_device_create ( ohmd_context *  ctx,
bool  no_hmds,
struct xrt_device **  out_xdevs 
)
Todo:
: support mix of 3dof and 6dof OpenHMD devices

References xrt_tracking_origin::type, U_LOG_D, U_LOG_W, U_TYPED_CALLOC, and XRT_MAX_DEVICES_PER_PROBE.

◆ oh_device_get_tracked_pose()

static void oh_device_get_tracked_pose ( struct xrt_device xdev,
enum xrt_input_name  name,
int64_t  at_timestamp_ns,
struct xrt_space_relation out_relation 
)
static
Todo:
adjust for latency here
Todo:
assuming that orientation is actually currently tracked
Todo:
this is a hack - should really get a timestamp on the USB data and use that instead.
Todo:
possibly hoist this out of the driver level, to provide as a common service?