lovr.headset.isDown; lovr.headset.isTouched;

This commit is contained in:
bjorn 2019-04-03 14:13:08 +09:00
parent 45757f2fa3
commit cb0a40a4b6
6 changed files with 159 additions and 67 deletions

View File

@ -77,8 +77,13 @@ const char* Subpaths[] = {
[PATH_LEFT] = "left",
[PATH_RIGHT] = "right",
[PATH_TRIGGER] = "trigger",
[PATH_TRACKPAD] = "trackpad",
[PATH_MENU] = "menu",
[PATH_GRIP] = "grip",
[PATH_TOUCHPAD] = "touchpad"
[PATH_A] = "a",
[PATH_B] = "b",
[PATH_X] = "x",
[PATH_Y] = "y"
};
typedef struct {
@ -338,6 +343,30 @@ int l_lovrHeadsetGetAngularVelocity(lua_State* L) {
return 0;
}
int l_lovrHeadsetIsDown(lua_State* L) {
Path path = luax_optpath(L, 1, "head");
bool down;
FOREACH_TRACKING_DRIVER(driver) {
if (driver->isDown(path, &down)) {
lua_pushboolean(L, down);
return 1;
}
}
return 0;
}
int l_lovrHeadsetIsTouched(lua_State* L) {
Path path = luax_optpath(L, 1, "head");
bool touched;
FOREACH_TRACKING_DRIVER(driver) {
if (driver->isDown(path, &touched)) {
lua_pushboolean(L, touched);
return 1;
}
}
return 0;
}
int l_lovrHeadsetGetAxis(lua_State* L) {
Path path = luax_optpath(L, 1, "head");
float x, y, z;
@ -465,6 +494,8 @@ static const luaL_Reg lovrHeadset[] = {
{ "getDirection", l_lovrHeadsetGetDirection },
{ "getVelocity", l_lovrHeadsetGetVelocity },
{ "getAngularVelocity", l_lovrHeadsetGetAngularVelocity },
{ "isDown", l_lovrHeadsetIsDown },
{ "isTouched", l_lovrHeadsetIsTouched },
{ "getAxis", l_lovrHeadsetGetAxis },
{ "vibrate", l_lovrHeadsetVibrate },
{ "newModel", l_lovrHeadsetNewModel },

View File

@ -6,6 +6,8 @@ int l_lovrHeadsetGetPosition(lua_State* L);
int l_lovrHeadsetGetOrientation(lua_State* L);
int l_lovrHeadsetGetVelocity(lua_State* L);
int l_lovrHeadsetGetAngularVelocity(lua_State* L);
int l_lovrHeadsetIsDown(lua_State* L);
int l_lovrHeadsetIsTouched(lua_State* L);
int l_lovrHeadsetGetAxis(lua_State* L);
int l_lovrHeadsetVibrate(lua_State* L);
int l_lovrHeadsetNewModel(lua_State* L);

View File

@ -72,16 +72,16 @@ static int l_lovrControllerGetAxis(lua_State* L) {
static int l_lovrControllerIsDown(lua_State* L) {
Controller* controller = luax_checktype(L, 1, Controller);
ControllerButton button = luaL_checkoption(L, 2, NULL, ControllerButtons);
lua_pushboolean(L, lovrHeadsetDriver->controllerIsDown(controller, button));
return 1;
luax_pushpath(L, controller->path);
lua_replace(L, 1);
return l_lovrHeadsetIsDown(L);
}
static int l_lovrControllerIsTouched(lua_State* L) {
Controller* controller = luax_checktype(L, 1, Controller);
ControllerButton button = luaL_checkoption(L, 2, NULL, ControllerButtons);
lua_pushboolean(L, lovrHeadsetDriver->controllerIsTouched(controller, button));
return 1;
luax_pushpath(L, controller->path);
lua_replace(L, 1);
return l_lovrHeadsetIsTouched(L);
}
static int l_lovrControllerVibrate(lua_State* L) {

View File

@ -151,6 +151,19 @@ static bool desktopGetAngularVelocity(Path path, float* vx, float* vy, float* vz
return false;
}
static bool desktopIsDown(Path path, bool* down) {
if (PATH_EQ(path, PATH_HANDS, PATH_LEFT) || PATH_EQ(path, PATH_HANDS, PATH_RIGHT)) {
*down = lovrPlatformIsMouseDown(MOUSE_RIGHT);
return true;
}
return false;
}
static bool desktopIsTouched(Path path, bool* touched) {
return false;
}
static int desktopGetAxis(Path path, float* x, float* y, float* z) {
return 0;
}
@ -176,14 +189,6 @@ static ControllerHand desktopControllerGetHand(Controller* controller) {
return HAND_UNKNOWN;
}
static bool desktopControllerIsDown(Controller* controller, ControllerButton button) {
return lovrPlatformIsMouseDown(MOUSE_RIGHT);
}
static bool desktopControllerIsTouched(Controller* controller, ControllerButton button) {
return false;
}
static void desktopRenderTo(void (*callback)(void*), void* userdata) {
uint32_t width, height;
desktopGetDisplayDimensions(&width, &height);
@ -275,14 +280,14 @@ HeadsetInterface lovrHeadsetDesktopDriver = {
.getPose = desktopGetPose,
.getVelocity = desktopGetVelocity,
.getAngularVelocity = desktopGetAngularVelocity,
.isDown = desktopIsDown,
.isTouched = desktopIsTouched,
.getAxis = desktopGetAxis,
.vibrate = desktopVibrate,
.newModelData = desktopNewModelData,
.getControllers = desktopGetControllers,
.controllerIsConnected = desktopControllerIsConnected,
.controllerGetHand = desktopControllerGetHand,
.controllerIsDown = desktopControllerIsDown,
.controllerIsTouched = desktopControllerIsTouched,
.renderTo = desktopRenderTo,
.update = desktopUpdate
};

View File

@ -43,8 +43,13 @@ typedef enum {
PATH_LEFT,
PATH_RIGHT,
PATH_TRIGGER,
PATH_TRACKPAD,
PATH_MENU,
PATH_GRIP,
PATH_TOUCHPAD
PATH_A,
PATH_B,
PATH_X,
PATH_Y
} Subpath;
typedef union {
@ -112,14 +117,14 @@ typedef struct HeadsetInterface {
bool (*getPose)(Path path, float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az);
bool (*getVelocity)(Path path, float* vx, float* vy, float* vz);
bool (*getAngularVelocity)(Path path, float* vx, float* vy, float* vz);
bool (*isDown)(Path path, bool* down);
bool (*isTouched)(Path path, bool* touched);
int (*getAxis)(Path path, float* x, float* y, float* z);
bool (*vibrate)(Path path, float strength, float duration, float frequency);
struct ModelData* (*newModelData)(Path path);
Controller** (*getControllers)(uint8_t* count);
bool (*controllerIsConnected)(Controller* controller);
ControllerHand (*controllerGetHand)(Controller* controller);
bool (*controllerIsDown)(Controller* controller, ControllerButton button);
bool (*controllerIsTouched)(Controller* controller, ControllerButton button);
void (*renderTo)(void (*callback)(void*), void* userdata);
struct Texture* (*getMirrorTexture)(void);
void (*update)(float dt);

View File

@ -60,6 +60,18 @@ static bool getTransform(unsigned int device, mat4 transform) {
}
}
static TrackedDeviceIndex_t getDeviceIndexForPath(Path path) {
if (PATH_EQ(path, PATH_HEAD)) {
return HEADSET_INDEX;
} else if (PATH_EQ(path, PATH_HANDS, PATH_LEFT)) {
return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_LeftHand);
} else if (PATH_EQ(path, PATH_HANDS, PATH_RIGHT)) {
return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_RightHand);
} else {
return k_unTrackedDeviceIndexInvalid;
}
}
static bool isController(TrackedDeviceIndex_t id) {
return state.system->IsTrackedDeviceConnected(id) &&
(state.system->GetTrackedDeviceClass(id) == ETrackedDeviceClass_TrackedDeviceClass_Controller ||
@ -103,28 +115,83 @@ static ControllerButton getButton(uint32_t button, ControllerHand hand) {
return CONTROLLER_BUTTON_UNKNOWN;
}
static int getButtonState(uint64_t mask, ControllerButton button, ControllerHand hand) {
static bool getButtonState(Path path, bool touch, bool* value) {
if (!PATH_EQ(path, PATH_HANDS, PATH_LEFT) && !PATH_EQ(path, PATH_HANDS, PATH_RIGHT)) {
return false;
}
TrackedDeviceIndex_t deviceIndex = getDeviceIndexForPath(path);
if (deviceIndex == INVALID_INDEX) {
return false;
}
VRControllerState_t input;
if (!state.system->GetControllerState(deviceIndex, &input, sizeof(input))) {
return false;
}
uint64_t mask = touch ? input.ulButtonTouched : input.ulButtonPressed;
ControllerHand hand = HAND_UNKNOWN;
switch (state.system->GetControllerRoleForTrackedDeviceIndex(deviceIndex)) {
case ETrackedControllerRole_TrackedControllerRole_LeftHand: return HAND_LEFT;
case ETrackedControllerRole_TrackedControllerRole_RightHand: return HAND_RIGHT;
default: break;
}
switch (state.type) {
case HEADSET_RIFT:
switch (button) {
case CONTROLLER_BUTTON_TRIGGER: return (mask >> EVRButtonId_k_EButton_Axis1) & 1;
case CONTROLLER_BUTTON_GRIP: return (mask >> EVRButtonId_k_EButton_Axis2) & 1;
case CONTROLLER_BUTTON_TOUCHPAD: return (mask >> EVRButtonId_k_EButton_Axis0) & 1;
case CONTROLLER_BUTTON_A: return hand == HAND_RIGHT && (mask >> EVRButtonId_k_EButton_A) & 1;
case CONTROLLER_BUTTON_B: return hand == HAND_RIGHT && (mask >> EVRButtonId_k_EButton_ApplicationMenu) & 1;
case CONTROLLER_BUTTON_X: return hand == HAND_LEFT && (mask >> EVRButtonId_k_EButton_A) & 1;
case CONTROLLER_BUTTON_Y: return hand == HAND_LEFT && (mask >> EVRButtonId_k_EButton_ApplicationMenu) & 1;
default: return 0;
switch (path.pieces[2]) {
case PATH_TRIGGER:
*value = (mask >> EVRButtonId_k_EButton_Axis1) & 1;
return true;
case PATH_GRIP:
*value = (mask >> EVRButtonId_k_EButton_Axis2) & 1;
return true;
case PATH_TRACKPAD:
*value = (mask >> EVRButtonId_k_EButton_Axis0) & 1;
return true;
case PATH_A:
*value = hand == HAND_RIGHT && (mask >> EVRButtonId_k_EButton_A) & 1;
return true;
case PATH_B:
*value = hand == HAND_RIGHT && (mask >> EVRButtonId_k_EButton_ApplicationMenu) & 1;
return true;
case PATH_X:
*value = hand == HAND_LEFT && (mask >> EVRButtonId_k_EButton_A) & 1;
return true;
case PATH_Y:
*value = hand == HAND_LEFT && (mask >> EVRButtonId_k_EButton_ApplicationMenu) & 1;
return true;
default: return false;
}
default:
switch (button) {
case CONTROLLER_BUTTON_SYSTEM: return (mask >> EVRButtonId_k_EButton_System) & 1;
case CONTROLLER_BUTTON_MENU: return (mask >> EVRButtonId_k_EButton_ApplicationMenu) & 1;
case CONTROLLER_BUTTON_TRIGGER: return (mask >> EVRButtonId_k_EButton_SteamVR_Trigger) & 1;
case CONTROLLER_BUTTON_GRIP: return (mask >> EVRButtonId_k_EButton_Grip) & 1;
case CONTROLLER_BUTTON_TOUCHPAD: return (mask >> EVRButtonId_k_EButton_SteamVR_Touchpad) & 1;
default: return 0;
switch (path.pieces[2]) {
case PATH_TRIGGER:
*value = (mask >> EVRButtonId_k_EButton_SteamVR_Trigger) & 1;
return true;
case PATH_TRACKPAD:
*value = (mask >> EVRButtonId_k_EButton_SteamVR_Touchpad) & 1;
return true;
case PATH_MENU:
*value = (mask >> EVRButtonId_k_EButton_ApplicationMenu) & 1;
return true;
case PATH_GRIP:
*value = (mask >> EVRButtonId_k_EButton_Grip) & 1;
return true;
default: return false;
}
}
}
@ -257,18 +324,6 @@ static const float* openvrGetBoundsGeometry(int* count) {
return NULL;
}
static TrackedDeviceIndex_t getDeviceIndexForPath(Path path) {
if (PATH_EQ(path, PATH_HEAD)) {
return HEADSET_INDEX;
} else if (PATH_EQ(path, PATH_HANDS, PATH_LEFT)) {
return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_LeftHand);
} else if (PATH_EQ(path, PATH_HANDS, PATH_RIGHT)) {
return state.system->GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole_TrackedControllerRole_RightHand);
} else {
return k_unTrackedDeviceIndexInvalid;
}
}
static bool openvrGetPose(Path path, float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az) {
TrackedDeviceIndex_t deviceIndex = getDeviceIndexForPath(path);
float transform[16];
@ -313,6 +368,14 @@ static bool openvrGetAngularVelocity(Path path, float* vx, float* vy, float* vz)
}
}
static bool openvrIsDown(Path path, bool* down) {
return getButtonState(path, false, down);
}
static bool openvrIsTouched(Path path, bool* touched) {
return getButtonState(path, true, touched);
}
static int openvrGetAxis(Path path, float* x, float* y, float* z) {
if (path.pieces[3] != PATH_NONE) {
return 0;
@ -339,7 +402,7 @@ static int openvrGetAxis(Path path, float* x, float* y, float* z) {
*x = input.rAxis[2].x;
return 1;
case PATH_TOUCHPAD:
case PATH_TRACKPAD:
*x = input.rAxis[0].x;
*y = input.rAxis[0].y;
return 2;
@ -353,7 +416,7 @@ static int openvrGetAxis(Path path, float* x, float* y, float* z) {
*x = input.rAxis[1].x;
return 1;
case PATH_TOUCHPAD:
case PATH_TRACKPAD:
*x = input.rAxis[0].x;
*y = input.rAxis[0].y;
return 2;
@ -503,20 +566,6 @@ static ControllerHand openvrControllerGetHand(Controller* controller) {
}
}
static bool openvrControllerIsDown(Controller* controller, ControllerButton button) {
VRControllerState_t input;
state.system->GetControllerState(controller->id, &input, sizeof(input));
ControllerHand hand = openvrControllerGetHand(controller);
return getButtonState(input.ulButtonPressed, button, hand);
}
static bool openvrControllerIsTouched(Controller* controller, ControllerButton button) {
VRControllerState_t input;
state.system->GetControllerState(controller->id, &input, sizeof(input));
ControllerHand hand = openvrControllerGetHand(controller);
return getButtonState(input.ulButtonTouched, button, hand);
}
static void openvrRenderTo(void (*callback)(void*), void* userdata) {
if (!state.canvas) {
uint32_t width, height;
@ -642,14 +691,14 @@ HeadsetInterface lovrHeadsetOpenVRDriver = {
.getPose = openvrGetPose,
.getVelocity = openvrGetVelocity,
.getAngularVelocity = openvrGetAngularVelocity,
.isDown = openvrIsDown,
.isTouched = openvrIsTouched,
.getAxis = openvrGetAxis,
.vibrate = openvrVibrate,
.newModelData = openvrNewModelData,
.getControllers = openvrGetControllers,
.controllerIsConnected = openvrControllerIsConnected,
.controllerGetHand = openvrControllerGetHand,
.controllerIsDown = openvrControllerIsDown,
.controllerIsTouched = openvrControllerIsTouched,
.renderTo = openvrRenderTo,
.getMirrorTexture = openvrGetMirrorTexture,
.update = openvrUpdate