Controller events;

This commit is contained in:
bjorn 2018-05-20 11:01:52 -07:00 committed by bjornbytes
parent b51e8694ac
commit 8bc7802246
2 changed files with 122 additions and 36 deletions

View File

@ -6,8 +6,7 @@
// Provided by resources/lovr.js
extern void webvrInit(void);
extern void webvrSetControllerAddedCallback(void (*callback)(uint32_t id));
extern void webvrSetControllerRemovedCallback(void (*callback)(uint32_t id));
extern void webvrSetCallbacks(void (*added)(uint32_t id), void (*removed)(uint32_t id), void (*pressed)(uint32_t, ControllerButton button), void (*released)(uint32_t id, ControllerButton button), void (*mount)(bool mounted));
extern HeadsetType webvrGetType(void);
extern HeadsetOrigin webvrGetOriginType(void);
extern bool webvrIsMounted(void);
@ -30,6 +29,7 @@ extern bool webvrControllerIsTouched(Controller* controller, ControllerButton bu
extern void webvrControllerVibrate(Controller* controller, float duration, float power);
extern ModelData* webvrControllerNewModelData(Controller* controller);
extern void webvrRenderTo(void (*callback)(void*), void* userdata);
extern void webvrUpdate(float dt);
typedef struct {
float offset;
@ -42,35 +42,57 @@ static void onControllerAdded(uint32_t id) {
Controller* controller = lovrAlloc(sizeof(Controller), free);
controller->id = id;
vec_push(&state.controllers, controller);
EventType type = EVENT_CONTROLLER_ADDED;
EventData data = { .controlleradded = { controller } };
Event event = { .type = type, .data = data };
lovrRetain(controller);
lovrEventPush(event);
lovrEventPush((Event) {
.type = EVENT_CONTROLLER_ADDED,
.data = { .controlleradded = { controller } }
});
}
static void onControllerRemoved(uint32_t id) {
for (int i = 0; i < state.controllers.length; i++) {
if (state.controllers.data[i]->id == id) {
Controller* controller = state.controllers.data[i];
EventType type = EVENT_CONTROLLER_REMOVED;
EventData data = { .controllerremoved = { controller } };
Event event = { .type = type, .data = data };
lovrRetain(controller);
lovrEventPush(event);
vec_splice(&state.controllers, i, 1);
lovrRelease(controller);
break;
if (state.controllers.data[i]->id != id) {
continue;
}
Controller* controller = state.controllers.data[i];
lovrRetain(controller);
lovrEventPush((Event) {
.type = EVENT_CONTROLLER_REMOVED,
.data = { .controllerremoved = { controller } }
});
vec_splice(&state.controllers, i, 1);
lovrRelease(controller);
break;
}
}
static void onControllerPressed(uint32_t id, ControllerButton button) {
lovrEventPush((Event) {
.type = EVENT_CONTROLLER_PRESSED,
.data = { .controllerpressed = { state.controllers.data[id], button } }
});
}
static void onControllerReleased(uint32_t id, ControllerButton button) {
lovrEventPush((Event) {
.type = EVENT_CONTROLLER_RELEASED,
.data = { .controllerreleased = { state.controllers.data[id], button } }
});
}
static void onMountChanged(bool mounted) {
lovrEventPush((Event) {
.type = EVENT_MOUNT,
.data = { .mount = { mounted } }
});
}
static bool webvrDriverInit(float offset) {
state.offset = offset;
vec_init(&state.controllers);
webvrInit();
webvrSetControllerAddedCallback(onControllerAdded);
webvrSetControllerRemovedCallback(onControllerRemoved);
webvrSetCallbacks(onControllerAdded, onControllerRemoved, onControllerPressed, onControllerReleased, onMountChanged);
return true;
}
@ -111,5 +133,5 @@ HeadsetInterface lovrHeadsetWebVRDriver = {
webvrControllerVibrate,
webvrControllerNewModelData,
webvrRenderTo,
NULL //void (*update)(float dt);
webvrUpdate
};

View File

@ -12,17 +12,21 @@ var LibraryLOVR = {
CONTROLLER_AXIS_GRIP: 1,
CONTROLLER_AXIS_TOUCHPAD_X: 2,
CONTROLLER_AXIS_TOUCHPAD_Y: 3,
sizeofRef: 8,
sizeofRef: 8
},
$lovr: {
WebVR: {
display: null,
gamepads: {},
lastGamepadState: {},
initialized: false,
mirrored: true,
ongamepadconnected: 0,
ongamepaddisconnected: 0,
oncontrolleradded: 0,
oncontrollerremoved: 0,
oncontrollerpressed: 0,
oncontrollerreleased: 0,
onmount: 0,
renderCallback: 0,
renderUserdata: 0,
frameData: null,
@ -32,9 +36,38 @@ var LibraryLOVR = {
matB: null,
quat: null,
buttonMap: {
'OpenVR Gamepad': [null, null, 3, 1, 2, 0, null, null, null, null, null],
'Oculus Touch (Right)': [null, null, null, 1, 2, 0, null, 3, 4],
'Oculus Touch (Left)': [null, null, null, 1, 2, 0, null, null, null, 3, 4]
'OpenVR Gamepad': [
/* C.CONTROLLER_BUTTON_UNKNOWN */ null,
/* C.CONTROLLER_BUTTON_SYSTEM */ null,
/* C.CONTROLLER_BUTTON_MENU */ 3,
/* C.CONTROLLER_BUTTON_TRIGGER */ 1,
/* C.CONTROLLER_BUTTON_GRIP */ 2,
/* C.CONTROLLER_BUTTON_TOUCHPAD */ 0
],
'Oculus Touch (Right)': [
/* C.CONTROLLER_BUTTON_UNKNOWN */ null,
/* C.CONTROLLER_BUTTON_SYSTEM */ null,
/* C.CONTROLLER_BUTTON_MENU */ 3,
/* C.CONTROLLER_BUTTON_TRIGGER */ 1,
/* C.CONTROLLER_BUTTON_GRIP */ 2,
/* C.CONTROLLER_BUTTON_TOUCHPAD */ 0,
/* C.CONTROLLER_BUTTON_JOYSTICK */ null,
/* C.CONTROLLER_BUTTON_A */ 3,
/* C.CONTROLLER_BUTTON_B */ 4
],
'Oculus Touch (Left)': [
/* C.CONTROLLER_BUTTON_UNKNOWN */ null,
/* C.CONTROLLER_BUTTON_SYSTEM */ null,
/* C.CONTROLLER_BUTTON_MENU */ 3,
/* C.CONTROLLER_BUTTON_TRIGGER */ 1,
/* C.CONTROLLER_BUTTON_GRIP */ 2,
/* C.CONTROLLER_BUTTON_TOUCHPAD */ 0,
/* C.CONTROLLER_BUTTON_JOYSTICK */ null,
/* C.CONTROLLER_BUTTON_A */ null,
/* C.CONTROLLER_BUTTON_B */ null,
/* C.CONTROLLER_BUTTON_X */ 3,
/* C.CONTROLLER_BUTTON_Y */ 4
]
},
init: function() {
@ -68,6 +101,14 @@ var LibraryLOVR = {
}
}
function onPresentChange() {
if (display) {
Runtime.dynCall('vi', lovr.WebVR.onmount, [display.isPresenting]);
}
onResize();
}
window.requestAnimationFrame(function onAnimationFrame() {
if (display) {
display.requestAnimationFrame(onAnimationFrame);
@ -99,14 +140,16 @@ var LibraryLOVR = {
var gamepad = event.gamepad;
if (display && gamepad.displayId === display.displayId && gamepad.pose) {
gamepads[gamepad.index] = gamepad;
lovr.WebVR.ongamepadconnected && Runtime.dynCall('vi', lovr.WebVR.ongamepadconnected, [gamepad.index]);
lovr.WebVR.lastGamepadState[gamepad.index] = gamepad.buttons.map(function(button) { return button.pressed; });
lovr.WebVR.oncontrolleradded && Runtime.dynCall('vi', lovr.WebVR.oncontrolleradded, [gamepad.index]);
}
});
window.addEventListener('gamepaddisconnected', function(event) {
var gamepad = event.gamepad;
if (gamepads[gamepad.index]) {
lovr.WebVR.ongamepaddisconnected && Runtime.dynCall('vi', lovr.WebVR.ongamepaddisconnected, [gamepad.index]);
lovr.WebVR.oncontrollerremoved && Runtime.dynCall('vi', lovr.WebVR.oncontrollerremoved, [gamepad.index]);
delete lovr.WebVR.lastGamepadState[gamepad.index];
delete gamepads[gamepad.index];
}
});
@ -123,7 +166,7 @@ var LibraryLOVR = {
}
});
window.addEventListener('vrdisplaypresentchange', onResize);
window.addEventListener('vrdisplaypresentchange', onPresentChange);
window.addEventListener('resize', onResize);
findDisplay();
@ -141,12 +184,12 @@ var LibraryLOVR = {
lovr.WebVR.init();
},
webvrSetControllerAddedCallback: function(callback) {
lovr.WebVR.ongamepadconnected = callback;
},
webvrSetControllerRemovedCallback: function(callback) {
lovr.WebVR.ongamepaddisconnected = callback;
webvrSetCallbacks: function(added, removed, pressed, released, mount) {
lovr.WebVR.oncontrolleradded = added;
lovr.WebVR.oncontrollerremoved = removed;
lovr.WebVR.oncontrollerpressed = pressed;
lovr.WebVR.oncontrollerreleased = released;
lovr.WebVR.onmount = mount;
},
webvrGetType: function() {
@ -370,13 +413,13 @@ var LibraryLOVR = {
webvrControllerIsDown: function(controller, button) {
var gamepad = lovr.WebVR.controllerToGamepad(controller);
var buttonMap = lovr.WebVR.buttonMap;
return gamepad && buttonMap[gamepad.id] && gamepad.buttons[buttonMap[gamepad.id]].pressed;
return gamepad && buttonMap[gamepad.id] && buttonMap[gamepad.id][button] && gamepad.buttons[buttonMap[gamepad.id][button]].pressed;
},
webvrControllerIsTouched: function(controller, button) {
var gamepad = lovr.WebVR.controllerToGamepad(controller);
var buttonMap = lovr.WebVR.buttonMap;
return gamepad && buttonMap[gamepad.id] && gamepad.buttons[buttonMap[gamepad.id]].touched;
return gamepad && buttonMap[gamepad.id] && buttonMap[gamepad.id][button] && gamepad.buttons[buttonMap[gamepad.id][button]].touched;
},
webvrControllerVibrate: function(controller, duration, power) {
@ -394,6 +437,27 @@ var LibraryLOVR = {
webvrRenderTo: function(callback, userdata) {
lovr.WebVR.renderCallback = callback;
lovr.WebVR.renderUserdata = userdata;
},
webvrUpdate: function(dt) {
for (var index in lovr.WebVR.gamepads) {
var gamepad = lovr.WebVR.gamepads[index];
var lastState = lovr.WebVR.lastGamepadState[index];
var buttonMap = lovr.WebVR.buttonMap[gamepad.id];
for (var button in buttonMap) {
if (buttonMap[button]) {
var pressed = gamepad.buttons[buttonMap[button]].pressed;
if (lastState[buttonIndex] !== pressed) {
lastState[buttonIndex] = pressed;
if (pressed) {
Runtime.dynCall('vii', lovr.WebVR.oncontrollerpressed, [gamepad.index, button]);
} else {
Runtime.dynCall('vii', lovr.WebVR.oncontrollerreleased, [gamepad.index, button]);
}
}
}
}
}
}
};