Merge pull request #122 from bjornbytes/hand-updates

Hand updates
This commit is contained in:
Bjorn Swenson 2019-06-03 00:14:45 -07:00 committed by GitHub
commit 68c1b6a201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 89 deletions

View File

@ -30,19 +30,15 @@ const char* HeadsetOrigins[] = {
const char* Devices[] = {
[DEVICE_HEAD] = "head",
[DEVICE_HAND] = "hand",
[DEVICE_HAND_LEFT] = "hand/left",
[DEVICE_HAND_RIGHT] = "hand/right",
[DEVICE_EYE_LEFT] = "eye/left",
[DEVICE_EYE_RIGHT] = "eye/right",
[DEVICE_TRACKER_1] = "tracker/1",
[DEVICE_TRACKER_2] = "tracker/2",
[DEVICE_TRACKER_3] = "tracker/3",
[DEVICE_TRACKER_4] = "tracker/4",
NULL
};
const char* DeviceButtons[] = {
[BUTTON_PRIMARY] = "primary",
[BUTTON_TRIGGER] = "trigger",
[BUTTON_THUMBSTICK] = "thumbstick",
[BUTTON_TOUCHPAD] = "touchpad",
@ -57,6 +53,7 @@ const char* DeviceButtons[] = {
};
const char* DeviceAxes[] = {
[AXIS_PRIMARY] = "primary",
[AXIS_TRIGGER] = "trigger",
[AXIS_THUMBSTICK] = "thumbstick",
[AXIS_TOUCHPAD] = "touchpad",
@ -427,6 +424,7 @@ int l_lovrHeadsetGetAxis(lua_State* L) {
case AXIS_GRIP:
lua_pushnumber(L, value[0]);
return 1;
case AXIS_PRIMARY:
case AXIS_THUMBSTICK:
case AXIS_TOUCHPAD:
lua_pushnumber(L, value[0]);
@ -519,16 +517,38 @@ static int l_lovrHeadsetGetMirrorTexture(lua_State* L) {
return 1;
}
static int deviceIterator(lua_State* L) {
static int l_lovrHeadsetGetHands(lua_State* L) {
if (lua_istable(L, 1)) {
lua_settop(L, 1);
} else {
lua_newtable(L);
}
int count = 0;
float position[3], orientation[4];
Device hands[] = { DEVICE_HAND_LEFT, DEVICE_HAND_RIGHT };
for (size_t i = 0; i < sizeof(hands) / sizeof(hands[0]); i++) {
FOREACH_TRACKING_DRIVER(driver) {
if (driver->getPose(hands[i], position, orientation)) {
lua_pushstring(L, Devices[hands[i]]);
lua_rawseti(L, -2, ++count);
}
}
}
lua_pushnil(L);
lua_rawseti(L, -2, ++count);
return 1;
}
static int handIterator(lua_State* L) {
Device hands[] = { DEVICE_HAND_LEFT, DEVICE_HAND_RIGHT };
size_t index = lua_tointeger(L, lua_upvalueindex(1));
Device* devices = (Device*) lua_touserdata(L, lua_upvalueindex(2));
size_t count = lua_tointeger(L, lua_upvalueindex(3));
float position[3], orientation[4];
while (index < count) {
while (index < 2) {
FOREACH_TRACKING_DRIVER(driver) {
if (driver->getPose(devices[index], position, orientation)) {
lua_pushstring(L, Devices[devices[index]]);
if (driver->getPose(hands[index], position, orientation)) {
lua_pushstring(L, Devices[hands[index]]);
lua_pushinteger(L, ++index);
lua_replace(L, lua_upvalueindex(1));
return 1;
@ -540,32 +560,9 @@ static int deviceIterator(lua_State* L) {
return 0;
}
static Device hands[] = {
DEVICE_HAND,
DEVICE_HAND_LEFT,
DEVICE_HAND_RIGHT
};
static Device trackers[] = {
DEVICE_TRACKER_1,
DEVICE_TRACKER_2,
DEVICE_TRACKER_3,
DEVICE_TRACKER_4
};
static int l_lovrHeadsetHands(lua_State* L) {
lua_pushinteger(L, 0);
lua_pushlightuserdata(L, hands);
lua_pushinteger(L, sizeof(hands) / sizeof(hands[0]));
lua_pushcclosure(L, deviceIterator, 3);
return 1;
}
static int l_lovrHeadsetTrackers(lua_State* L) {
lua_pushinteger(L, 0);
lua_pushlightuserdata(L, trackers);
lua_pushinteger(L, sizeof(trackers) / sizeof(trackers[0]));
lua_pushcclosure(L, deviceIterator, 3);
lua_pushcclosure(L, handIterator, 1);
return 1;
}
@ -599,8 +596,8 @@ static const luaL_Reg lovrHeadset[] = {
{ "renderTo", l_lovrHeadsetRenderTo },
{ "update", l_lovrHeadsetUpdate },
{ "getMirrorTexture", l_lovrHeadsetGetMirrorTexture },
{ "getHands", l_lovrHeadsetGetHands },
{ "hands", l_lovrHeadsetHands },
{ "trackers", l_lovrHeadsetTrackers },
{ NULL, NULL }
};

View File

@ -72,11 +72,11 @@ static const float* desktop_getBoundsGeometry(uint32_t* count) {
}
static bool desktop_getPose(Device device, vec3 position, quat orientation) {
if (device != DEVICE_HEAD && device != DEVICE_HAND) {
if (device != DEVICE_HEAD && device != DEVICE_HAND_LEFT) {
return false;
}
vec3_set(position, 0.f, 0.f, device == DEVICE_HAND ? -.75f : 0.f);
vec3_set(position, 0.f, 0.f, device == DEVICE_HAND_LEFT ? -.75f : 0.f);
mat4_transform(state.transform, position);
quat_fromMat4(orientation, state.transform);
return true;
@ -107,7 +107,7 @@ static bool desktop_getAcceleration(Device device, vec3 acceleration, vec3 angul
}
static bool desktop_isDown(Device device, DeviceButton button, bool* down) {
if (device != DEVICE_HAND || button != BUTTON_TRIGGER) {
if (device != DEVICE_HAND_LEFT || (button != BUTTON_TRIGGER && button != BUTTON_PRIMARY)) {
return false;
}

View File

@ -24,19 +24,15 @@ typedef enum {
typedef enum {
DEVICE_HEAD,
DEVICE_HAND,
DEVICE_HAND_LEFT,
DEVICE_HAND_RIGHT,
DEVICE_EYE_LEFT,
DEVICE_EYE_RIGHT,
DEVICE_TRACKER_1,
DEVICE_TRACKER_2,
DEVICE_TRACKER_3,
DEVICE_TRACKER_4,
MAX_DEVICES
} Device;
typedef enum {
BUTTON_PRIMARY,
BUTTON_TRIGGER,
BUTTON_THUMBSTICK,
BUTTON_TOUCHPAD,
@ -51,6 +47,7 @@ typedef enum {
} DeviceButton;
typedef enum {
AXIS_PRIMARY,
AXIS_TRIGGER,
AXIS_THUMBSTICK,
AXIS_TOUCHPAD,

View File

@ -225,6 +225,7 @@ static bool oculus_isDown(Device device, DeviceButton button, bool* down) {
case BUTTON_X: return *down = (buttons & ovrButton_X), true;
case BUTTON_Y: return *down = (buttons & ovrButton_Y), true;
case BUTTON_MENU: return *down = (buttons & ovrButton_Enter), true;
case BUTTON_PRIMARY:
case BUTTON_TRIGGER: return *down = (is->IndexTriggerNoDeadzone[hand] > .5f), true;
case BUTTON_THUMBSTICK: return *down = (buttons & (ovrButton_LThumb | ovrButton_RThumb), true;
case BUTTON_GRIP: return *down = (masks->HandTrigger[hand] > .9f), true;
@ -246,6 +247,7 @@ static bool oculus_isTouched(Device device, DeviceButton button, bool* touched)
case BUTTON_B: return *touched = (touches & ovrTouch_B), true;
case BUTTON_X: return *touched = (touches & ovrTouch_X), true;
case BUTTON_Y: return *touched = (touches & ovrTouch_Y), true;
case BUTTON_PRIMARY:
case BUTTON_TRIGGER: return *touched = (touches & (ovrTouch_LIndexTrigger | ovrTouch_RIndexTrigger)), true;
case BUTTON_THUMBSTICK: return *touched = (touches & (ovrTouch_LThumb | ovrTouch_RThumb)), true;
default: return false;
@ -263,6 +265,7 @@ static bool oculus_getAxis(Device device, DeviceAxis axis, vec3* value) {
switch (axis) {
case AXIS_GRIP: return *value = is->HandTriggerNoDeadzone[hand], true;
case AXIS_TRIGGER: return *value = is->IndexTriggerNoDeadzone[hand], true;
case AXIS_PRIMARY:
case AXIS_THUMBSTICK:
value[0] = is->ThumbstickNoDeadzone[hand].x;
value[1] = is->ThumbstickNoDeadzone[hand].y;

View File

@ -76,23 +76,14 @@ static const float* vrapi_getBoundsGeometry(uint32_t* count) {
}
static int getHandIdx(Device device) {
switch (device) {
case DEVICE_HAND:
if (bridgeLovrMobileData.deviceType != BRIDGE_LOVR_DEVICE_GO || bridgeLovrMobileData.updateData.controllerCount <= 0)
return -1;
return 0;
case DEVICE_HAND_LEFT:
case DEVICE_HAND_RIGHT:
if (bridgeLovrMobileData.deviceType == BRIDGE_LOVR_DEVICE_QUEST) {
for(int c = 0; c < BRIDGE_LOVR_CONTROLLERMAX && c < bridgeLovrMobileData.updateData.controllerCount; c++) {
BridgeLovrHand hand = (device == DEVICE_HAND_LEFT ? BRIDGE_LOVR_HAND_LEFT : BRIDGE_LOVR_HAND_RIGHT);
if (bridgeLovrMobileData.updateData.controllers[c].hand & hand)
return c;
}
}
default: // FALLTHROUGH
return -1;
if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
for(int c = 0; c < BRIDGE_LOVR_CONTROLLERMAX && c < bridgeLovrMobileData.updateData.controllerCount; c++) {
BridgeLovrHand hand = (device == DEVICE_HAND_LEFT ? BRIDGE_LOVR_HAND_LEFT : BRIDGE_LOVR_HAND_RIGHT);
if (bridgeLovrMobileData.updateData.controllers[c].hand & hand)
return c;
}
}
return -1;
}
static bool vrapi_getPose(Device device, vec3 position, quat orientation) {
@ -148,6 +139,7 @@ static bool buttonDown(BridgeLovrButton field, DeviceButton button, bool *result
if (bridgeLovrMobileData.deviceType == BRIDGE_LOVR_DEVICE_QUEST) {
switch (button) {
case BUTTON_MENU: *result = field & BRIDGE_LOVR_BUTTON_MENU; break; // Technically "LMENU" but only fires on left controller
case BUTTON_PRIMARY:
case BUTTON_TRIGGER: *result = field & BRIDGE_LOVR_BUTTON_SHOULDER; break;
case BUTTON_GRIP: *result = field & BRIDGE_LOVR_BUTTON_GRIP; break;
case BUTTON_TOUCHPAD: *result = field & BRIDGE_LOVR_BUTTON_JOYSTICK; break;
@ -160,6 +152,7 @@ static bool buttonDown(BridgeLovrButton field, DeviceButton button, bool *result
} else {
switch (button) {
case BUTTON_MENU: *result = field & BRIDGE_LOVR_BUTTON_GOMENU; break; // Technically "RMENU" but quest only has one
case BUTTON_PRIMARY:
case BUTTON_TRIGGER: *result = field & BRIDGE_LOVR_BUTTON_GOSHOULDER; break;
case BUTTON_TOUCHPAD: *result = field & BRIDGE_LOVR_BUTTON_TOUCHPAD; break;
default: return false;
@ -174,6 +167,7 @@ static bool buttonTouch(BridgeLovrTouch field, DeviceButton button, bool *result
return false;
switch (button) {
case BUTTON_PRIMARY:
case BUTTON_TRIGGER: *result = field & (BRIDGE_LOVR_TOUCH_TRIGGER); break;
case BUTTON_TOUCHPAD: *result = field & (BRIDGE_LOVR_TOUCH_TOUCHPAD | BRIDGE_LOVR_TOUCH_JOYSTICK); break;
case BUTTON_A: *result = field & BRIDGE_LOVR_TOUCH_A; break;
@ -207,9 +201,10 @@ static bool vrapi_getAxis(Device device, DeviceAxis axis, float* value) {
return false;
BridgeLovrController *data = &bridgeLovrMobileData.updateData.controllers[idx];
if (bridgeLovrMobileData.deviceType == BRIDGE_LOVR_DEVICE_QUEST) {
switch (axis) {
case AXIS_PRIMARY:
case AXIS_THUMBSTICK:
value[0] = data->trackpad.x;
value[1] = data->trackpad.y;
@ -220,6 +215,7 @@ static bool vrapi_getAxis(Device device, DeviceAxis axis, float* value) {
}
} else {
switch (axis) {
case AXIS_PRIMARY:
case AXIS_TOUCHPAD:
value[0] = (data->trackpad.x - 160) / 160.f;
value[1] = (data->trackpad.y - 160) / 160.f;
@ -447,8 +443,6 @@ void bridgeLovrUpdate(BridgeLovrUpdateData *updateData) {
// Unpack update data
bridgeLovrMobileData.updateData = *updateData;
// for(int c = 0; c < updateData->controllerCount; c++) lovrLog("%d: d %x t %x\n", c, (uint32_t)updateData->controllers[c].buttonDown, (uint32_t)updateData->controllers[c].buttonTouch);
if (pauseState == PAUSESTATE_BUG) { // Bad frame-- replace bad time with last known good oculus time
bridgeLovrMobileData.updateData.displayTime = lastPauseAtRaw;
pauseState = PAUSESTATE_RESUME;

View File

@ -95,18 +95,8 @@ static struct {
static TrackedDeviceIndex_t getDeviceIndex(Device device) {
switch (device) {
case DEVICE_HEAD: return HEADSET;
case DEVICE_HAND: return INVALID_DEVICE;
case DEVICE_HAND_LEFT: return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_LeftHand);
case DEVICE_HAND_RIGHT: return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_RightHand);
case DEVICE_TRACKER_1:
case DEVICE_TRACKER_2:
case DEVICE_TRACKER_3:
case DEVICE_TRACKER_4: {
TrackedDeviceIndex_t trackers[4];
uint32_t trackerCount = state.system->GetSortedTrackedDeviceIndicesOfClass(ETrackedDeviceClass_TrackedDeviceClass_GenericTracker, trackers, 4, 0);
uint32_t i = device - DEVICE_TRACKER_1;
return i < trackerCount ? trackers[i] : INVALID_DEVICE;
}
default: return INVALID_DEVICE;
}
}

View File

@ -1,22 +1,23 @@
var LibraryLOVR = {
$webvr: {
buttonMap: {
'OpenVR Gamepad': [1, null, 0, 2],
'Oculus Touch (Left)': [1, 0, null, 2, null, null, null, 3, 4],
'Oculus Touch (Right)': [1, 0, null, 2, null, 3, 4, null, null],
'Spatial Controller (Spatial Interaction Source) 045E-065D': [0, 1, 3, 2, 4]
'OpenVR Gamepad': [1, 1, null, 0, 2],
'Oculus Touch (Left)': [1, 1, 0, null, 2, null, null, null, 3, 4],
'Oculus Touch (Right)': [1, 1, 0, null, 2, null, 3, 4, null, null],
'Spatial Controller (Spatial Interaction Source) 045E-065D': [0, 0, 1, 3, 2, 4]
},
refreshGamepads: function(event) {
if (event.gamepad.hand) {
var device = ({
'': C.DEVICE_HAND,
'left': C.DEVICE_HAND_LEFT,
'right': C.DEVICE_HAND_RIGHT
})[event.gamepad.hand];
webvr.gamepads[device] = event.gamepad;
webvr.poses[device] = event.gamepad.pose;
if (device) {
webvr.gamepads[device] = event.gamepad;
webvr.poses[device] = event.gamepad.pose;
}
}
}
},
@ -227,7 +228,7 @@ var LibraryLOVR = {
return false;
}
HEAPF32[down >> 2] = gamepad.buttons[webvr.buttonMaps[gamepad.id][button]].pressed;
HEAPF32[down >> 2] = gamepad.buttons[webvr.buttonMap[gamepad.id][button]].pressed;
return true;
},
@ -238,7 +239,7 @@ var LibraryLOVR = {
return false;
}
HEAPF32[touched >> 2] = gamepad.buttons[webvr.buttonMaps[gamepad.id][button]].touched;
HEAPF32[touched >> 2] = gamepad.buttons[webvr.buttonMap[gamepad.id][button]].touched;
return true;
},
@ -252,7 +253,8 @@ var LibraryLOVR = {
if (gamepad.id.startsWith('OpenVR')) {
switch (axis) {
case C.AXIS_TRIGGER: HEAPF32[value >> 2] = gamepad.buttons[1].value; return true;
case C.AXIS_TRACKPAD:
case C.AXIS_PRIMARY:
case C.AXIS_TOUCHPAD:
HEAPF32[value >> 2 + 0] = gamepad.axes[0];
HEAPF32[value >> 2 + 1] = gamepad.axes[1];
return true;
@ -262,6 +264,7 @@ var LibraryLOVR = {
switch (axis) {
case C.AXIS_TRIGGER: HEAPF32[value >> 2] = gamepad.buttons[1].value; return true;
case C.AXIS_GRIP: HEAPF32[value >> 2] = gamepad.buttons[2].value; return true;
case C.AXIS_PRIMARY:
case C.AXIS_THUMBSTICK:
HEAPF32[value >> 2 + 0] = gamepad.axes[0];
HEAPF32[value >> 2 + 1] = gamepad.axes[1];
@ -271,11 +274,12 @@ var LibraryLOVR = {
} else if (gamepad.id.startsWith('Spatial Controller')) {
switch (axis) {
case C.AXIS_TRIGGER: HEAPF32[value >> 2] = gamepad.buttons[0].value; return true;
case C.AXIS_PRIMARY:
case C.AXIS_THUMBSTICK:
HEAPF32[value >> 2 + 0] = gamepad.axes[0];
HEAPF32[value >> 2 + 1] = gamepad.axes[1];
return true;
case C.AXIS_TRACKPAD:
case C.AXIS_TOUCHPAD:
HEAPF32[value >> 2 + 0] = gamepad.axes[2];
HEAPF32[value >> 2 + 1] = gamepad.axes[3];
return true;
@ -313,11 +317,12 @@ var LibraryLOVR = {
ORIGIN_FLOOR: 1,
// DeviceAxis
AXIS_TRIGGER: 0,
AXIS_THUMBSTICK: 1,
AXIS_TRACKPAD: 2,
AXIS_PINCH: 5,
AXIS_GRIP: 6
AXIS_PRIMARY: 0,
AXIS_TRIGGER: 1,
AXIS_THUMBSTICK: 2,
AXIS_TOUCHPAD: 3,
AXIS_PINCH: 4,
AXIS_GRIP: 5
}
};