mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-04 21:43:34 +00:00
commit
cce7fa8581
|
@ -35,6 +35,16 @@ const char* Devices[] = {
|
||||||
[DEVICE_HAND_RIGHT] = "hand/right",
|
[DEVICE_HAND_RIGHT] = "hand/right",
|
||||||
[DEVICE_EYE_LEFT] = "eye/left",
|
[DEVICE_EYE_LEFT] = "eye/left",
|
||||||
[DEVICE_EYE_RIGHT] = "eye/right",
|
[DEVICE_EYE_RIGHT] = "eye/right",
|
||||||
|
[DEVICE_HAND_LEFT_FINGER_THUMB] = "hand/left/finger/thumb",
|
||||||
|
[DEVICE_HAND_LEFT_FINGER_INDEX] = "hand/left/finger/index",
|
||||||
|
[DEVICE_HAND_LEFT_FINGER_MIDDLE] = "hand/left/finger/middle",
|
||||||
|
[DEVICE_HAND_LEFT_FINGER_RING] = "hand/left/finger/ring",
|
||||||
|
[DEVICE_HAND_LEFT_FINGER_PINKY] = "hand/left/finger/pinky",
|
||||||
|
[DEVICE_HAND_RIGHT_FINGER_THUMB] = "hand/right/finger/thumb",
|
||||||
|
[DEVICE_HAND_RIGHT_FINGER_INDEX] = "hand/right/finger/index",
|
||||||
|
[DEVICE_HAND_RIGHT_FINGER_MIDDLE] = "hand/right/finger/middle",
|
||||||
|
[DEVICE_HAND_RIGHT_FINGER_RING] = "hand/right/finger/ring",
|
||||||
|
[DEVICE_HAND_RIGHT_FINGER_PINKY] = "hand/right/finger/pinky",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,6 +67,9 @@ const char* DeviceAxes[] = {
|
||||||
[AXIS_THUMBSTICK] = "thumbstick",
|
[AXIS_THUMBSTICK] = "thumbstick",
|
||||||
[AXIS_TOUCHPAD] = "touchpad",
|
[AXIS_TOUCHPAD] = "touchpad",
|
||||||
[AXIS_GRIP] = "grip",
|
[AXIS_GRIP] = "grip",
|
||||||
|
[AXIS_CURL] = "curl",
|
||||||
|
[AXIS_SPLAY] = "splay",
|
||||||
|
[AXIS_PINCH] = "pinch",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -454,7 +467,10 @@ static const int axisCounts[MAX_AXES] = {
|
||||||
[AXIS_TRIGGER] = 1,
|
[AXIS_TRIGGER] = 1,
|
||||||
[AXIS_THUMBSTICK] = 2,
|
[AXIS_THUMBSTICK] = 2,
|
||||||
[AXIS_TOUCHPAD] = 2,
|
[AXIS_TOUCHPAD] = 2,
|
||||||
[AXIS_GRIP] = 1
|
[AXIS_GRIP] = 1,
|
||||||
|
[AXIS_CURL] = 1,
|
||||||
|
[AXIS_SPLAY] = 1,
|
||||||
|
[AXIS_PINCH] = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
static int l_lovrHeadsetGetAxis(lua_State* L) {
|
static int l_lovrHeadsetGetAxis(lua_State* L) {
|
||||||
|
@ -476,6 +492,49 @@ static int l_lovrHeadsetGetAxis(lua_State* L) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_lovrHeadsetGetSkeleton(lua_State* L) {
|
||||||
|
Device device = luax_optdevice(L, 1);
|
||||||
|
float poses[MAX_HEADSET_BONES * 8];
|
||||||
|
uint32_t poseCount = MAX_HEADSET_BONES;
|
||||||
|
FOREACH_TRACKING_DRIVER(driver) {
|
||||||
|
if (driver->getSkeleton(device, poses, &poseCount)) {
|
||||||
|
if (!lua_istable(L, 2)) {
|
||||||
|
lua_createtable(L, poseCount, 0);
|
||||||
|
} else {
|
||||||
|
lua_settop(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < poseCount; i++) {
|
||||||
|
lua_createtable(L, 7, 0);
|
||||||
|
|
||||||
|
float angle, ax, ay, az;
|
||||||
|
float* pose = poses + i * 8;
|
||||||
|
quat_getAngleAxis(pose + 4, &angle, &ax, &ay, &az);
|
||||||
|
lua_pushnumber(L, pose[0]);
|
||||||
|
lua_pushnumber(L, pose[1]);
|
||||||
|
lua_pushnumber(L, pose[2]);
|
||||||
|
lua_pushnumber(L, angle);
|
||||||
|
lua_pushnumber(L, ax);
|
||||||
|
lua_pushnumber(L, ay);
|
||||||
|
lua_pushnumber(L, az);
|
||||||
|
lua_rawseti(L, -8, 7);
|
||||||
|
lua_rawseti(L, -7, 6);
|
||||||
|
lua_rawseti(L, -6, 5);
|
||||||
|
lua_rawseti(L, -5, 4);
|
||||||
|
lua_rawseti(L, -4, 3);
|
||||||
|
lua_rawseti(L, -3, 2);
|
||||||
|
lua_rawseti(L, -2, 1);
|
||||||
|
|
||||||
|
lua_rawseti(L, -2, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int l_lovrHeadsetVibrate(lua_State* L) {
|
static int l_lovrHeadsetVibrate(lua_State* L) {
|
||||||
Device device = luax_optdevice(L, 1);
|
Device device = luax_optdevice(L, 1);
|
||||||
float strength = luax_optfloat(L, 2, 1.f);
|
float strength = luax_optfloat(L, 2, 1.f);
|
||||||
|
@ -616,6 +675,7 @@ static const luaL_Reg lovrHeadset[] = {
|
||||||
{ "getAxis", l_lovrHeadsetGetAxis },
|
{ "getAxis", l_lovrHeadsetGetAxis },
|
||||||
{ "vibrate", l_lovrHeadsetVibrate },
|
{ "vibrate", l_lovrHeadsetVibrate },
|
||||||
{ "newModel", l_lovrHeadsetNewModel },
|
{ "newModel", l_lovrHeadsetNewModel },
|
||||||
|
{ "getSkeleton", l_lovrHeadsetGetSkeleton },
|
||||||
{ "renderTo", l_lovrHeadsetRenderTo },
|
{ "renderTo", l_lovrHeadsetRenderTo },
|
||||||
{ "update", l_lovrHeadsetUpdate },
|
{ "update", l_lovrHeadsetUpdate },
|
||||||
{ "getTime", l_lovrHeadsetGetTime },
|
{ "getTime", l_lovrHeadsetGetTime },
|
||||||
|
|
|
@ -561,10 +561,6 @@ MAF mat4 mat4_perspective(mat4 m, float clipNear, float clipFar, float fovy, flo
|
||||||
|
|
||||||
// This is currently specific to OpenGL
|
// This is currently specific to OpenGL
|
||||||
MAF mat4 mat4_fov(mat4 m, float left, float right, float up, float down, float clipNear, float clipFar) {
|
MAF mat4 mat4_fov(mat4 m, float left, float right, float up, float down, float clipNear, float clipFar) {
|
||||||
left = tanf(left);
|
|
||||||
right = tanf(right);
|
|
||||||
up = tanf(up);
|
|
||||||
down = tanf(down);
|
|
||||||
float idx = 1.f / (right - left);
|
float idx = 1.f / (right - left);
|
||||||
float idy = 1.f / (up - down);
|
float idy = 1.f / (up - down);
|
||||||
float idz = 1.f / (clipFar - clipNear);
|
float idz = 1.f / (clipFar - clipNear);
|
||||||
|
|
|
@ -176,7 +176,7 @@ static void desktop_renderTo(void (*callback)(void*), void* userdata) {
|
||||||
float left, right, up, down;
|
float left, right, up, down;
|
||||||
desktop_getViewAngles(0, &left, &right, &up, &down);
|
desktop_getViewAngles(0, &left, &right, &up, &down);
|
||||||
Camera camera = { .canvas = NULL, .viewMatrix = { MAT4_IDENTITY }, .stereo = true };
|
Camera camera = { .canvas = NULL, .viewMatrix = { MAT4_IDENTITY }, .stereo = true };
|
||||||
mat4_fov(camera.projection[0], left, right, up, down, state.clipNear, state.clipFar);
|
mat4_fov(camera.projection[0], tanf(left), tanf(right), tanf(up), tanf(down), state.clipNear, state.clipFar);
|
||||||
mat4_multiply(camera.viewMatrix[0], state.headTransform);
|
mat4_multiply(camera.viewMatrix[0], state.headTransform);
|
||||||
mat4_invert(camera.viewMatrix[0]);
|
mat4_invert(camera.viewMatrix[0]);
|
||||||
mat4_set(camera.projection[1], camera.projection[0]);
|
mat4_set(camera.projection[1], camera.projection[0]);
|
||||||
|
|
|
@ -4,14 +4,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_HEADSET_BONES 32
|
||||||
|
|
||||||
struct ModelData;
|
struct ModelData;
|
||||||
struct Texture;
|
struct Texture;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ORIGIN_HEAD,
|
|
||||||
ORIGIN_FLOOR
|
|
||||||
} HeadsetOrigin;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DRIVER_DESKTOP,
|
DRIVER_DESKTOP,
|
||||||
DRIVER_LEAP_MOTION,
|
DRIVER_LEAP_MOTION,
|
||||||
|
@ -22,12 +19,27 @@ typedef enum {
|
||||||
DRIVER_WEBVR
|
DRIVER_WEBVR
|
||||||
} HeadsetDriver;
|
} HeadsetDriver;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ORIGIN_HEAD,
|
||||||
|
ORIGIN_FLOOR
|
||||||
|
} HeadsetOrigin;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DEVICE_HEAD,
|
DEVICE_HEAD,
|
||||||
DEVICE_HAND_LEFT,
|
DEVICE_HAND_LEFT,
|
||||||
DEVICE_HAND_RIGHT,
|
DEVICE_HAND_RIGHT,
|
||||||
DEVICE_EYE_LEFT,
|
DEVICE_EYE_LEFT,
|
||||||
DEVICE_EYE_RIGHT,
|
DEVICE_EYE_RIGHT,
|
||||||
|
DEVICE_HAND_LEFT_FINGER_THUMB,
|
||||||
|
DEVICE_HAND_LEFT_FINGER_INDEX,
|
||||||
|
DEVICE_HAND_LEFT_FINGER_MIDDLE,
|
||||||
|
DEVICE_HAND_LEFT_FINGER_RING,
|
||||||
|
DEVICE_HAND_LEFT_FINGER_PINKY,
|
||||||
|
DEVICE_HAND_RIGHT_FINGER_THUMB,
|
||||||
|
DEVICE_HAND_RIGHT_FINGER_INDEX,
|
||||||
|
DEVICE_HAND_RIGHT_FINGER_MIDDLE,
|
||||||
|
DEVICE_HAND_RIGHT_FINGER_RING,
|
||||||
|
DEVICE_HAND_RIGHT_FINGER_PINKY,
|
||||||
MAX_DEVICES
|
MAX_DEVICES
|
||||||
} Device;
|
} Device;
|
||||||
|
|
||||||
|
@ -50,6 +62,9 @@ typedef enum {
|
||||||
AXIS_THUMBSTICK,
|
AXIS_THUMBSTICK,
|
||||||
AXIS_TOUCHPAD,
|
AXIS_TOUCHPAD,
|
||||||
AXIS_GRIP,
|
AXIS_GRIP,
|
||||||
|
AXIS_CURL,
|
||||||
|
AXIS_SPLAY,
|
||||||
|
AXIS_PINCH,
|
||||||
MAX_AXES
|
MAX_AXES
|
||||||
} DeviceAxis;
|
} DeviceAxis;
|
||||||
|
|
||||||
|
@ -82,6 +97,7 @@ typedef struct HeadsetInterface {
|
||||||
bool (*isDown)(Device device, DeviceButton button, bool* down, bool* changed);
|
bool (*isDown)(Device device, DeviceButton button, bool* down, bool* changed);
|
||||||
bool (*isTouched)(Device device, DeviceButton button, bool* touched);
|
bool (*isTouched)(Device device, DeviceButton button, bool* touched);
|
||||||
bool (*getAxis)(Device device, DeviceAxis axis, float* value);
|
bool (*getAxis)(Device device, DeviceAxis axis, float* value);
|
||||||
|
bool (*getSkeleton)(Device device, float* poses, uint32_t* poseCount);
|
||||||
bool (*vibrate)(Device device, float strength, float duration, float frequency);
|
bool (*vibrate)(Device device, float strength, float duration, float frequency);
|
||||||
struct ModelData* (*newModelData)(Device device);
|
struct ModelData* (*newModelData)(Device device);
|
||||||
void (*renderTo)(void (*callback)(void*), void* userdata);
|
void (*renderTo)(void (*callback)(void*), void* userdata);
|
||||||
|
|
|
@ -83,17 +83,37 @@ static void adjustPose(vec3 position, vec3 direction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool leap_getPose(Device device, vec3 position, quat orientation) {
|
static bool leap_getPose(Device device, vec3 position, quat orientation) {
|
||||||
if ((device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) || !state.hands[device - DEVICE_HAND_LEFT]) {
|
if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
|
||||||
|
LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];
|
||||||
|
|
||||||
|
if (!hand) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float direction[4];
|
float direction[4];
|
||||||
LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];
|
|
||||||
vec3_init(position, hand->palm.position.v);
|
vec3_init(position, hand->palm.position.v);
|
||||||
vec3_init(direction, hand->palm.normal.v);
|
vec3_init(direction, hand->palm.normal.v);
|
||||||
adjustPose(position, direction);
|
adjustPose(position, direction);
|
||||||
quat_between(orientation, (float[4]) { 0.f, 0.f, -1.f }, direction);
|
quat_between(orientation, (float[4]) { 0.f, 0.f, -1.f }, direction);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LEAP_BONE* distal;
|
||||||
|
if (state.hands[0] && device >= DEVICE_HAND_LEFT_FINGER_THUMB && device <= DEVICE_HAND_LEFT_FINGER_PINKY) {
|
||||||
|
distal = &state.hands[0]->digits[device - DEVICE_HAND_LEFT_FINGER_THUMB].distal;
|
||||||
|
} else if (state.hands[1] && device >= DEVICE_HAND_RIGHT_FINGER_THUMB && device <= DEVICE_HAND_RIGHT_FINGER_PINKY) {
|
||||||
|
distal = &state.hands[1]->digits[device - DEVICE_HAND_RIGHT_FINGER_THUMB].distal;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float direction[4];
|
||||||
|
vec3_init(position, distal->next_joint.v);
|
||||||
|
vec3_init(direction, distal->next_joint.v);
|
||||||
|
vec3_sub(direction, distal->prev_joint.v);
|
||||||
|
adjustPose(position, direction);
|
||||||
|
quat_between(orientation, (float[4]) { 0.f, 0.f, -1.f }, direction);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool leap_getVelocity(Device device, vec3 velocity, vec3 angularVelocity) {
|
static bool leap_getVelocity(Device device, vec3 velocity, vec3 angularVelocity) {
|
||||||
|
@ -119,7 +139,6 @@ static bool leap_isDown(Device device, DeviceButton button, bool* down, bool* ch
|
||||||
*changed = false; // TODO
|
*changed = false; // TODO
|
||||||
|
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case BUTTON_TRIGGER: *down = hand->pinch_strength > .5f; return true;
|
|
||||||
case BUTTON_GRIP: *down = hand->grab_strength > .5f; return true;
|
case BUTTON_GRIP: *down = hand->grab_strength > .5f; return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
@ -130,17 +149,37 @@ static bool leap_isTouched(Device device, DeviceButton button, bool* touched) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool leap_getAxis(Device device, DeviceAxis axis, float* value) {
|
static bool leap_getAxis(Device device, DeviceAxis axis, float* value) {
|
||||||
if ((device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) || !state.hands[device - DEVICE_HAND_LEFT]) {
|
if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
|
||||||
|
LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];
|
||||||
|
|
||||||
|
if (!hand) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];
|
|
||||||
|
|
||||||
switch (axis) {
|
switch (axis) {
|
||||||
case AXIS_TRIGGER: *value = hand->pinch_strength; return true;
|
case AXIS_PINCH: value[0] = hand->pinch_strength; return true;
|
||||||
case AXIS_GRIP: *value = hand->grab_strength; return true;
|
case AXIS_GRIP: value[0] = hand->grab_strength; return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.hands[0] && device >= DEVICE_HAND_LEFT_FINGER_THUMB && device <= DEVICE_HAND_LEFT_FINGER_PINKY) {
|
||||||
|
LEAP_HAND* hand = state.hands[0];
|
||||||
|
LEAP_DIGIT* digit = &hand->digits[device - DEVICE_HAND_LEFT_FINGER_THUMB];
|
||||||
|
*value = digit->is_extended ? 0.f : 1.f;
|
||||||
|
return axis == AXIS_CURL;
|
||||||
|
} else if (state.hands[1] && device >= DEVICE_HAND_RIGHT_FINGER_THUMB && device <= DEVICE_HAND_RIGHT_FINGER_PINKY) {
|
||||||
|
LEAP_HAND* hand = state.hands[1];
|
||||||
|
LEAP_DIGIT* digit = &hand->digits[device - DEVICE_HAND_RIGHT_FINGER_THUMB];
|
||||||
|
*value = digit->is_extended ? 0.f : 1.f;
|
||||||
|
return axis == AXIS_CURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool leap_getSkeleton(Device device, float* poses, uint32_t* poseCount) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool leap_vibrate(Device device, float strength, float duration, float frequency) {
|
static bool leap_vibrate(Device device, float strength, float duration, float frequency) {
|
||||||
|
@ -200,6 +239,7 @@ HeadsetInterface lovrHeadsetLeapMotionDriver = {
|
||||||
.isDown = leap_isDown,
|
.isDown = leap_isDown,
|
||||||
.isTouched = leap_isTouched,
|
.isTouched = leap_isTouched,
|
||||||
.getAxis = leap_getAxis,
|
.getAxis = leap_getAxis,
|
||||||
|
.getSkeleton = leap_getSkeleton,
|
||||||
.vibrate = leap_vibrate,
|
.vibrate = leap_vibrate,
|
||||||
.newModelData = leap_newModelData,
|
.newModelData = leap_newModelData,
|
||||||
.update = leap_update
|
.update = leap_update
|
||||||
|
|
|
@ -27,6 +27,41 @@ extern bool VR_IsRuntimeInstalled();
|
||||||
#define HEADSET k_unTrackedDeviceIndex_Hmd
|
#define HEADSET k_unTrackedDeviceIndex_Hmd
|
||||||
#define INVALID_DEVICE k_unTrackedDeviceIndexInvalid
|
#define INVALID_DEVICE k_unTrackedDeviceIndexInvalid
|
||||||
|
|
||||||
|
enum {
|
||||||
|
eBone_Root = 0,
|
||||||
|
eBone_Wrist,
|
||||||
|
eBone_Thumb0,
|
||||||
|
eBone_Thumb1,
|
||||||
|
eBone_Thumb2,
|
||||||
|
eBone_Thumb3,
|
||||||
|
eBone_IndexFinger0,
|
||||||
|
eBone_IndexFinger1,
|
||||||
|
eBone_IndexFinger2,
|
||||||
|
eBone_IndexFinger3,
|
||||||
|
eBone_IndexFinger4,
|
||||||
|
eBone_MiddleFinger0,
|
||||||
|
eBone_MiddleFinger1,
|
||||||
|
eBone_MiddleFinger2,
|
||||||
|
eBone_MiddleFinger3,
|
||||||
|
eBone_MiddleFinger4,
|
||||||
|
eBone_RingFinger0,
|
||||||
|
eBone_RingFinger1,
|
||||||
|
eBone_RingFinger2,
|
||||||
|
eBone_RingFinger3,
|
||||||
|
eBone_RingFinger4,
|
||||||
|
eBone_PinkyFinger0,
|
||||||
|
eBone_PinkyFinger1,
|
||||||
|
eBone_PinkyFinger2,
|
||||||
|
eBone_PinkyFinger3,
|
||||||
|
eBone_PinkyFinger4,
|
||||||
|
eBone_Aux_Thumb,
|
||||||
|
eBone_Aux_IndexFinger,
|
||||||
|
eBone_Aux_MiddleFinger,
|
||||||
|
eBone_Aux_RingFinger,
|
||||||
|
eBone_Aux_PinkyFinger,
|
||||||
|
eBone_Count
|
||||||
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct VR_IVRSystem_FnTable* system;
|
struct VR_IVRSystem_FnTable* system;
|
||||||
struct VR_IVRCompositor_FnTable* compositor;
|
struct VR_IVRCompositor_FnTable* compositor;
|
||||||
|
@ -34,7 +69,7 @@ static struct {
|
||||||
struct VR_IVRRenderModels_FnTable* renderModels;
|
struct VR_IVRRenderModels_FnTable* renderModels;
|
||||||
struct VR_IVRInput_FnTable* input;
|
struct VR_IVRInput_FnTable* input;
|
||||||
VRActionSetHandle_t actionSet;
|
VRActionSetHandle_t actionSet;
|
||||||
VRActionHandle_t poseActions[MAX_DEVICES];
|
VRActionHandle_t poseActions[3];
|
||||||
VRActionHandle_t buttonActions[2][MAX_BUTTONS];
|
VRActionHandle_t buttonActions[2][MAX_BUTTONS];
|
||||||
VRActionHandle_t touchActions[2][MAX_BUTTONS];
|
VRActionHandle_t touchActions[2][MAX_BUTTONS];
|
||||||
VRActionHandle_t axisActions[2][MAX_AXES];
|
VRActionHandle_t axisActions[2][MAX_AXES];
|
||||||
|
@ -261,6 +296,10 @@ static bool openvr_getViewPose(uint32_t view, float* position, float* orientatio
|
||||||
static bool openvr_getViewAngles(uint32_t view, float* left, float* right, float* up, float* down) {
|
static bool openvr_getViewAngles(uint32_t view, float* left, float* right, float* up, float* down) {
|
||||||
EVREye eye = view ? EVREye_Eye_Right : EVREye_Eye_Left;
|
EVREye eye = view ? EVREye_Eye_Right : EVREye_Eye_Left;
|
||||||
state.system->GetProjectionRaw(eye, left, right, up, down);
|
state.system->GetProjectionRaw(eye, left, right, up, down);
|
||||||
|
*left = atanf(*left);
|
||||||
|
*right = atanf(*right);
|
||||||
|
*up = atanf(*up);
|
||||||
|
*down = atanf(*down);
|
||||||
return view < 2;
|
return view < 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,24 +334,71 @@ static const float* openvr_getBoundsGeometry(uint32_t* count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool openvr_getPose(Device device, vec3 position, quat orientation) {
|
static bool openvr_getPose(Device device, vec3 position, quat orientation) {
|
||||||
InputPoseActionData_t actionData;
|
float transform[16];
|
||||||
TrackedDevicePose_t* pose;
|
|
||||||
|
|
||||||
|
// Early exit for head pose
|
||||||
if (device == DEVICE_HEAD) {
|
if (device == DEVICE_HEAD) {
|
||||||
pose = &state.headPose;
|
mat4_fromMat34(transform, state.headPose.mDeviceToAbsoluteTracking.m);
|
||||||
} else if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
|
transform[13] += state.offset;
|
||||||
state.input->GetPoseActionData(state.poseActions[device], state.compositor->GetTrackingSpace(), 0.f, &actionData, sizeof(actionData), 0);
|
mat4_getPosition(transform, position);
|
||||||
pose = &actionData.pose;
|
mat4_getOrientation(transform, orientation);
|
||||||
|
return state.headPose.bPoseIsValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Device hand;
|
||||||
|
if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
|
||||||
|
hand = device;
|
||||||
|
} else if (device >= DEVICE_HAND_LEFT_FINGER_THUMB && device <= DEVICE_HAND_LEFT_FINGER_PINKY) {
|
||||||
|
hand = DEVICE_HAND_LEFT;
|
||||||
|
} else if (device >= DEVICE_HAND_RIGHT_FINGER_THUMB && device <= DEVICE_HAND_RIGHT_FINGER_PINKY) {
|
||||||
|
hand = DEVICE_HAND_RIGHT;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float transform[16];
|
InputPoseActionData_t actionData;
|
||||||
mat4_fromMat34(transform, pose->mDeviceToAbsoluteTracking.m);
|
state.input->GetPoseActionData(state.poseActions[hand], state.compositor->GetTrackingSpace(), 0.f, &actionData, sizeof(actionData), 0);
|
||||||
|
mat4_fromMat34(transform, actionData.pose.mDeviceToAbsoluteTracking.m);
|
||||||
|
transform[13] += state.offset;
|
||||||
|
|
||||||
|
// Early exit for hand pose
|
||||||
|
if (device == hand) {
|
||||||
mat4_getPosition(transform, position);
|
mat4_getPosition(transform, position);
|
||||||
mat4_getOrientation(transform, orientation);
|
mat4_getOrientation(transform, orientation);
|
||||||
transform[13] += state.offset;
|
return actionData.pose.bPoseIsValid;
|
||||||
return pose->bPoseIsValid;
|
}
|
||||||
|
|
||||||
|
InputSkeletalActionData_t info;
|
||||||
|
EVRInputError error = state.input->GetSkeletalActionData(state.skeletonActions[hand - DEVICE_HAND_LEFT], &info, sizeof(info));
|
||||||
|
if (error || !info.bActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VRBoneTransform_t bones[31];
|
||||||
|
EVRSkeletalTransformSpace space = EVRSkeletalTransformSpace_VRSkeletalTransformSpace_Model;
|
||||||
|
EVRSkeletalMotionRange motionRange = EVRSkeletalMotionRange_VRSkeletalMotionRange_WithController;
|
||||||
|
error = state.input->GetSkeletalBoneData(state.skeletonActions[hand - DEVICE_HAND_LEFT], space, motionRange, bones, sizeof(bones) / sizeof(bones[0]));
|
||||||
|
if (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t finger = (hand == DEVICE_HAND_LEFT) ? (device - DEVICE_HAND_LEFT_FINGER_THUMB) : (device - DEVICE_HAND_RIGHT_FINGER_THUMB);
|
||||||
|
uint32_t boneIndex;
|
||||||
|
switch (finger) {
|
||||||
|
case 0: boneIndex = eBone_Thumb3; break;
|
||||||
|
case 1: boneIndex = eBone_IndexFinger4; break;
|
||||||
|
case 2: boneIndex = eBone_MiddleFinger4; break;
|
||||||
|
case 3: boneIndex = eBone_RingFinger4; break;
|
||||||
|
case 4: boneIndex = eBone_PinkyFinger4; break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VRBoneTransform_t* bone = &bones[boneIndex];
|
||||||
|
mat4_translate(transform, bone->position.v[0], bone->position.v[1], bone->position.v[2]);
|
||||||
|
mat4_rotateQuat(transform, (float[4]) { bone->orientation.w, bone->orientation.x, bone->orientation.y, bone->orientation.z });
|
||||||
|
mat4_getPosition(transform, position);
|
||||||
|
mat4_getOrientation(transform, orientation);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool openvr_getVelocity(Device device, vec3 velocity, vec3 angularVelocity) {
|
static bool openvr_getVelocity(Device device, vec3 velocity, vec3 angularVelocity) {
|
||||||
|
@ -357,14 +443,79 @@ static bool openvr_isTouched(Device device, DeviceButton button, bool* touched)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool openvr_getAxis(Device device, DeviceAxis axis, vec3 value) {
|
static bool openvr_getAxis(Device device, DeviceAxis axis, vec3 value) {
|
||||||
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
|
if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputAnalogActionData_t actionData;
|
InputAnalogActionData_t actionData;
|
||||||
state.input->GetAnalogActionData(state.axisActions[device - DEVICE_HAND_LEFT][axis], &actionData, sizeof(actionData), 0);
|
state.input->GetAnalogActionData(state.axisActions[device - DEVICE_HAND_LEFT][axis], &actionData, sizeof(actionData), 0);
|
||||||
vec3_set(value, actionData.x, actionData.y, actionData.z);
|
vec3_set(value, actionData.x, actionData.y, actionData.z);
|
||||||
return actionData.bActive;
|
return actionData.bActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t finger;
|
||||||
|
VRActionHandle_t skeletonAction;
|
||||||
|
if (device >= DEVICE_HAND_LEFT_FINGER_THUMB && device <= DEVICE_HAND_LEFT_FINGER_PINKY) {
|
||||||
|
finger = device - DEVICE_HAND_LEFT_FINGER_THUMB;
|
||||||
|
skeletonAction = state.skeletonActions[0];
|
||||||
|
} else if (device >= DEVICE_HAND_RIGHT_FINGER_THUMB && device <= DEVICE_HAND_RIGHT_FINGER_PINKY) {
|
||||||
|
finger = device - DEVICE_HAND_RIGHT_FINGER_THUMB;
|
||||||
|
skeletonAction = state.skeletonActions[1];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VRSkeletalSummaryData_t summary;
|
||||||
|
if (state.input->GetSkeletalSummaryData(skeletonAction, &summary)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis == AXIS_CURL) {
|
||||||
|
value[0] = summary.flFingerCurl[finger];
|
||||||
|
return true;
|
||||||
|
} else if (axis == AXIS_SPLAY && finger < 4) {
|
||||||
|
value[0] = summary.flFingerSplay[finger];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool openvr_getSkeleton(Device device, float* poses, uint32_t* poseCount) {
|
||||||
|
if (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputSkeletalActionData_t info;
|
||||||
|
VRActionHandle_t action = state.skeletonActions[device - DEVICE_HAND_LEFT];
|
||||||
|
EVRInputError error = state.input->GetSkeletalActionData(action, &info, sizeof(info));
|
||||||
|
if (error || !info.bActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t boneCount;
|
||||||
|
error = state.input->GetBoneCount(action, &boneCount);
|
||||||
|
if (error || boneCount > MAX_HEADSET_BONES || boneCount > *poseCount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VRBoneTransform_t bones[MAX_HEADSET_BONES];
|
||||||
|
EVRSkeletalTransformSpace space = EVRSkeletalTransformSpace_VRSkeletalTransformSpace_Parent;
|
||||||
|
EVRSkeletalMotionRange motionRange = EVRSkeletalMotionRange_VRSkeletalMotionRange_WithController;
|
||||||
|
error = state.input->GetSkeletalBoneData(action, space, motionRange, bones, boneCount);
|
||||||
|
if (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float* p = poses;
|
||||||
|
for (uint32_t i = 0; i < boneCount; i++) {
|
||||||
|
memcpy(p, bones[i].position.v, 4 * sizeof(float));
|
||||||
|
p[4] = bones[i].orientation.x;
|
||||||
|
p[5] = bones[i].orientation.y;
|
||||||
|
p[6] = bones[i].orientation.z;
|
||||||
|
p[7] = bones[i].orientation.w;
|
||||||
|
p += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
*poseCount = boneCount;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool openvr_vibrate(Device device, float strength, float duration, float frequency) {
|
static bool openvr_vibrate(Device device, float strength, float duration, float frequency) {
|
||||||
|
@ -506,10 +657,9 @@ static void openvr_renderTo(void (*callback)(void*), void* userdata) {
|
||||||
mat4_fromMat34(head, state.headPose.mDeviceToAbsoluteTracking.m);
|
mat4_fromMat34(head, state.headPose.mDeviceToAbsoluteTracking.m);
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
float left, right, up, down, eye[16];
|
float eye[16];
|
||||||
EVREye vrEye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
EVREye vrEye = (i == 0) ? EVREye_Eye_Left : EVREye_Eye_Right;
|
||||||
openvr_getViewAngles(i, &left, &right, &up, &down);
|
mat4_fromMat44(camera.projection[i], state.system->GetProjectionMatrix(vrEye, state.clipNear, state.clipFar).m);
|
||||||
mat4_fov(camera.projection[i], left, right, up, down, state.clipNear, state.clipFar);
|
|
||||||
mat4_init(camera.viewMatrix[i], head);
|
mat4_init(camera.viewMatrix[i], head);
|
||||||
mat4_multiply(camera.viewMatrix[i], mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m));
|
mat4_multiply(camera.viewMatrix[i], mat4_fromMat34(eye, state.system->GetEyeToHeadTransform(vrEye).m));
|
||||||
mat4_invert(camera.viewMatrix[i]);
|
mat4_invert(camera.viewMatrix[i]);
|
||||||
|
@ -576,6 +726,7 @@ HeadsetInterface lovrHeadsetOpenVRDriver = {
|
||||||
.isDown = openvr_isDown,
|
.isDown = openvr_isDown,
|
||||||
.isTouched = openvr_isTouched,
|
.isTouched = openvr_isTouched,
|
||||||
.getAxis = openvr_getAxis,
|
.getAxis = openvr_getAxis,
|
||||||
|
.getSkeleton = openvr_getSkeleton,
|
||||||
.vibrate = openvr_vibrate,
|
.vibrate = openvr_vibrate,
|
||||||
.newModelData = openvr_newModelData,
|
.newModelData = openvr_newModelData,
|
||||||
.renderTo = openvr_renderTo,
|
.renderTo = openvr_renderTo,
|
||||||
|
|
|
@ -710,7 +710,11 @@ static void openxr_renderTo(void (*callback)(void*), void* userdata) {
|
||||||
XrVector3f* v = &view->pose.position;
|
XrVector3f* v = &view->pose.position;
|
||||||
XrQuaternionf* q = &view->pose.orientation;
|
XrQuaternionf* q = &view->pose.orientation;
|
||||||
XrFovf* fov = &view->fov;
|
XrFovf* fov = &view->fov;
|
||||||
mat4_fov(camera.projection[eye], fov->angleLeft, fov->angleRight, fov->angleUp, fov->angleDown, state.clipNear, state.clipFar);
|
float left = tanf(fov->angleLeft);
|
||||||
|
float right = tanf(fov->angleRight);
|
||||||
|
float up = tanf(fov->angleUp);
|
||||||
|
float down = tanf(fov->angleDown);
|
||||||
|
mat4_fov(camera.projection[eye], left, right, up, down, state.clipNear, state.clipFar);
|
||||||
mat4_identity(camera.viewMatrix[eye]);
|
mat4_identity(camera.viewMatrix[eye]);
|
||||||
mat4_translate(camera.viewMatrix[eye], v->x, v->y, v->z);
|
mat4_translate(camera.viewMatrix[eye], v->x, v->y, v->z);
|
||||||
mat4_rotateQuat(camera.viewMatrix[eye], (float[4]) { q->x, q->y, q->z, q->w });
|
mat4_rotateQuat(camera.viewMatrix[eye], (float[4]) { q->x, q->y, q->z, q->w });
|
||||||
|
|
Loading…
Reference in a new issue