mirror of https://github.com/bjornbytes/lovr.git
Add getSkeleton;
This commit is contained in:
parent
0e4c42c8b0
commit
5197d30b94
|
@ -492,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);
|
||||
|
@ -632,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 },
|
||||
|
|
|
@ -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,6 +19,11 @@ typedef enum {
|
|||
DRIVER_WEBVR
|
||||
} HeadsetDriver;
|
||||
|
||||
typedef enum {
|
||||
ORIGIN_HEAD,
|
||||
ORIGIN_FLOOR
|
||||
} HeadsetOrigin;
|
||||
|
||||
typedef enum {
|
||||
DEVICE_HEAD,
|
||||
DEVICE_HAND_LEFT,
|
||||
|
@ -95,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);
|
||||
|
|
|
@ -239,6 +239,10 @@ static bool leap_getAxis(Device device, DeviceAxis axis, float* value) {
|
|||
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) {
|
||||
return false;
|
||||
}
|
||||
|
@ -296,6 +300,7 @@ HeadsetInterface lovrHeadsetLeapMotionDriver = {
|
|||
.isDown = leap_isDown,
|
||||
.isTouched = leap_isTouched,
|
||||
.getAxis = leap_getAxis,
|
||||
.getSkeleton = leap_getSkeleton,
|
||||
.vibrate = leap_vibrate,
|
||||
.newModelData = leap_newModelData,
|
||||
.update = leap_update
|
||||
|
|
|
@ -475,6 +475,46 @@ static bool openvr_getAxis(Device device, DeviceAxis axis, vec3 value) {
|
|||
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) {
|
||||
if (duration <= 0.f || (device != DEVICE_HAND_LEFT && device != DEVICE_HAND_RIGHT)) return false;
|
||||
|
||||
|
@ -684,6 +724,7 @@ HeadsetInterface lovrHeadsetOpenVRDriver = {
|
|||
.isDown = openvr_isDown,
|
||||
.isTouched = openvr_isTouched,
|
||||
.getAxis = openvr_getAxis,
|
||||
.getSkeleton = openvr_getSkeleton,
|
||||
.vibrate = openvr_vibrate,
|
||||
.newModelData = openvr_newModelData,
|
||||
.renderTo = openvr_renderTo,
|
||||
|
|
Loading…
Reference in New Issue