Skip to content
Permalink
Browse files

Merge pull request #197 from bjornbytes/hand-devices

More Hand Stuff
  • Loading branch information
bjornbytes committed Feb 14, 2020
2 parents f048f6d + 409c2ad commit cce7fa8581bdf9098cd626330f76e21d92ede2c4
@@ -35,6 +35,16 @@ const char* Devices[] = {
[DEVICE_HAND_RIGHT] = "hand/right",
[DEVICE_EYE_LEFT] = "eye/left",
[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
};

@@ -57,6 +67,9 @@ const char* DeviceAxes[] = {
[AXIS_THUMBSTICK] = "thumbstick",
[AXIS_TOUCHPAD] = "touchpad",
[AXIS_GRIP] = "grip",
[AXIS_CURL] = "curl",
[AXIS_SPLAY] = "splay",
[AXIS_PINCH] = "pinch",
NULL
};

@@ -454,7 +467,10 @@ static const int axisCounts[MAX_AXES] = {
[AXIS_TRIGGER] = 1,
[AXIS_THUMBSTICK] = 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) {
@@ -476,6 +492,49 @@ static int l_lovrHeadsetGetAxis(lua_State* L) {
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) {
Device device = luax_optdevice(L, 1);
float strength = luax_optfloat(L, 2, 1.f);
@@ -616,6 +675,7 @@ static const luaL_Reg lovrHeadset[] = {
{ "getAxis", l_lovrHeadsetGetAxis },
{ "vibrate", l_lovrHeadsetVibrate },
{ "newModel", l_lovrHeadsetNewModel },
{ "getSkeleton", l_lovrHeadsetGetSkeleton },
{ "renderTo", l_lovrHeadsetRenderTo },
{ "update", l_lovrHeadsetUpdate },
{ "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
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 idy = 1.f / (up - down);
float idz = 1.f / (clipFar - clipNear);
@@ -176,7 +176,7 @@ static void desktop_renderTo(void (*callback)(void*), void* userdata) {
float left, right, up, down;
desktop_getViewAngles(0, &left, &right, &up, &down);
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_invert(camera.viewMatrix[0]);
mat4_set(camera.projection[1], camera.projection[0]);
@@ -4,14 +4,11 @@

#pragma once

#define MAX_HEADSET_BONES 32

struct ModelData;
struct Texture;

typedef enum {
ORIGIN_HEAD,
ORIGIN_FLOOR
} HeadsetOrigin;

typedef enum {
DRIVER_DESKTOP,
DRIVER_LEAP_MOTION,
@@ -22,12 +19,27 @@ typedef enum {
DRIVER_WEBVR
} HeadsetDriver;

typedef enum {
ORIGIN_HEAD,
ORIGIN_FLOOR
} HeadsetOrigin;

typedef enum {
DEVICE_HEAD,
DEVICE_HAND_LEFT,
DEVICE_HAND_RIGHT,
DEVICE_EYE_LEFT,
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
} Device;

@@ -50,6 +62,9 @@ typedef enum {
AXIS_THUMBSTICK,
AXIS_TOUCHPAD,
AXIS_GRIP,
AXIS_CURL,
AXIS_SPLAY,
AXIS_PINCH,
MAX_AXES
} DeviceAxis;

@@ -82,6 +97,7 @@ typedef struct HeadsetInterface {
bool (*isDown)(Device device, DeviceButton button, bool* down, bool* changed);
bool (*isTouched)(Device device, DeviceButton button, bool* touched);
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);
struct ModelData* (*newModelData)(Device device);
void (*renderTo)(void (*callback)(void*), void* userdata);
@@ -83,14 +83,34 @@ static void adjustPose(vec3 position, vec3 direction) {
}

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;
}

float direction[4];
vec3_init(position, hand->palm.position.v);
vec3_init(direction, hand->palm.normal.v);
adjustPose(position, direction);
quat_between(orientation, (float[4]) { 0.f, 0.f, -1.f }, direction);
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];
LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];
vec3_init(position, hand->palm.position.v);
vec3_init(direction, hand->palm.normal.v);
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;
@@ -119,7 +139,6 @@ static bool leap_isDown(Device device, DeviceButton button, bool* down, bool* ch
*changed = false; // TODO

switch (button) {
case BUTTON_TRIGGER: *down = hand->pinch_strength > .5f; return true;
case BUTTON_GRIP: *down = hand->grab_strength > .5f; return true;
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) {
if ((device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT) || !state.hands[device - DEVICE_HAND_LEFT]) {
return false;
}
if (device == DEVICE_HAND_LEFT || device == DEVICE_HAND_RIGHT) {
LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];

LEAP_HAND* hand = state.hands[device - DEVICE_HAND_LEFT];
if (!hand) {
return false;
}

switch (axis) {
case AXIS_TRIGGER: *value = hand->pinch_strength; return true;
case AXIS_GRIP: *value = hand->grab_strength; return true;
default: return false;
switch (axis) {
case AXIS_PINCH: value[0] = hand->pinch_strength; return true;
case AXIS_GRIP: value[0] = hand->grab_strength; return true;
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) {
@@ -200,6 +239,7 @@ HeadsetInterface lovrHeadsetLeapMotionDriver = {
.isDown = leap_isDown,
.isTouched = leap_isTouched,
.getAxis = leap_getAxis,
.getSkeleton = leap_getSkeleton,
.vibrate = leap_vibrate,
.newModelData = leap_newModelData,
.update = leap_update

0 comments on commit cce7fa8

Please sign in to comment.
You can’t perform that action at this time.