2017-04-16 23:56:49 +00:00
|
|
|
#include "headset/headset.h"
|
2018-05-09 04:15:41 +00:00
|
|
|
#include "event/event.h"
|
2017-04-16 23:56:49 +00:00
|
|
|
#include "graphics/graphics.h"
|
2017-04-22 23:59:54 +00:00
|
|
|
#include "lib/vec/vec.h"
|
2017-10-31 08:14:09 +00:00
|
|
|
#include <stdbool.h>
|
2017-04-16 23:56:49 +00:00
|
|
|
|
2018-05-01 22:10:51 +00:00
|
|
|
// Provided by resources/lovr.js
|
2018-05-28 01:58:30 +00:00
|
|
|
extern bool webvrInit(float offset, 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 void webvrDestroy(void);
|
2018-05-09 04:15:41 +00:00
|
|
|
extern HeadsetType webvrGetType(void);
|
2018-04-29 21:38:08 +00:00
|
|
|
extern HeadsetOrigin webvrGetOriginType(void);
|
2018-05-13 23:40:53 +00:00
|
|
|
extern bool webvrIsMounted(void);
|
2018-10-21 15:40:57 +00:00
|
|
|
extern void webvrGetDisplayDimensions(uint32_t* width, uint32_t* height);
|
2018-04-29 21:38:08 +00:00
|
|
|
extern void webvrGetClipDistance(float* near, float* far);
|
|
|
|
extern void webvrSetClipDistance(float near, float far);
|
|
|
|
extern void webvrGetBoundsDimensions(float* width, float* depth);
|
2018-10-10 01:03:53 +00:00
|
|
|
extern const float* webvrGetBoundsGeometry(int* count);
|
2018-05-01 22:10:51 +00:00
|
|
|
extern void webvrGetPose(float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az);
|
2018-11-19 15:38:46 +00:00
|
|
|
extern void webvrGetVelocity(float* vx, float* vy, float* vz);
|
|
|
|
extern void webvrGetAngularVelocity(float* vx, float* vy, float* vz);
|
2018-05-09 04:15:41 +00:00
|
|
|
extern bool webvrControllerIsConnected(Controller* controller);
|
|
|
|
extern ControllerHand webvrControllerGetHand(Controller* controller);
|
|
|
|
extern void webvrControllerGetPose(Controller* controller, float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az);
|
2018-11-19 15:38:46 +00:00
|
|
|
extern void webvrControllerGetVelocity(Controller* controller, float* vx, float* vy, float* vz);
|
|
|
|
extern void webvrControllerGetAngularVelocity(Controller* controller, float* vx, float* vy, float* vz);
|
2018-05-13 23:38:46 +00:00
|
|
|
extern float webvrControllerGetAxis(Controller* controller, ControllerAxis axis);
|
|
|
|
extern bool webvrControllerIsDown(Controller* controller, ControllerButton button);
|
|
|
|
extern bool webvrControllerIsTouched(Controller* controller, ControllerButton button);
|
2018-05-09 04:15:41 +00:00
|
|
|
extern void webvrControllerVibrate(Controller* controller, float duration, float power);
|
|
|
|
extern ModelData* webvrControllerNewModelData(Controller* controller);
|
2018-05-28 01:58:30 +00:00
|
|
|
extern void webvrSetRenderCallback(void (*callback)(float*, float*, float*, float*, void*), void* userdata);
|
2018-05-20 18:01:52 +00:00
|
|
|
extern void webvrUpdate(float dt);
|
2018-04-29 21:38:08 +00:00
|
|
|
|
2017-04-21 03:46:35 +00:00
|
|
|
typedef struct {
|
2018-05-08 00:46:14 +00:00
|
|
|
vec_controller_t controllers;
|
2018-05-23 09:22:56 +00:00
|
|
|
void (*renderCallback)(void*);
|
2017-04-21 03:46:35 +00:00
|
|
|
} HeadsetState;
|
|
|
|
|
|
|
|
static HeadsetState state;
|
2017-04-16 23:56:49 +00:00
|
|
|
|
2018-05-09 04:15:41 +00:00
|
|
|
static void onControllerAdded(uint32_t id) {
|
2018-12-19 08:25:20 +00:00
|
|
|
Controller* controller = lovrAlloc(Controller);
|
2018-05-09 04:15:41 +00:00
|
|
|
controller->id = id;
|
|
|
|
vec_push(&state.controllers, controller);
|
|
|
|
lovrRetain(controller);
|
2018-05-20 18:01:52 +00:00
|
|
|
lovrEventPush((Event) {
|
|
|
|
.type = EVENT_CONTROLLER_ADDED,
|
2018-07-26 20:40:15 +00:00
|
|
|
.data.controller = { controller, 0 }
|
2018-05-20 18:01:52 +00:00
|
|
|
});
|
2018-05-09 04:15:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void onControllerRemoved(uint32_t id) {
|
|
|
|
for (int i = 0; i < state.controllers.length; i++) {
|
2018-05-23 09:22:56 +00:00
|
|
|
if (state.controllers.data[i]->id == id) {
|
|
|
|
Controller* controller = state.controllers.data[i];
|
|
|
|
lovrRetain(controller);
|
|
|
|
lovrEventPush((Event) {
|
|
|
|
.type = EVENT_CONTROLLER_REMOVED,
|
2018-07-26 20:40:15 +00:00
|
|
|
.data.controller = { controller, 0 }
|
2018-05-23 09:22:56 +00:00
|
|
|
});
|
|
|
|
vec_splice(&state.controllers, i, 1);
|
2019-04-05 13:07:46 +00:00
|
|
|
lovrRelease(Controller, controller);
|
2018-05-23 09:22:56 +00:00
|
|
|
break;
|
2018-05-09 04:15:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-20 18:01:52 +00:00
|
|
|
static void onControllerPressed(uint32_t id, ControllerButton button) {
|
|
|
|
lovrEventPush((Event) {
|
|
|
|
.type = EVENT_CONTROLLER_PRESSED,
|
2018-07-26 20:40:15 +00:00
|
|
|
.data.controller = { state.controllers.data[id], button }
|
2018-05-20 18:01:52 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static void onControllerReleased(uint32_t id, ControllerButton button) {
|
|
|
|
lovrEventPush((Event) {
|
|
|
|
.type = EVENT_CONTROLLER_RELEASED,
|
2018-07-26 20:40:15 +00:00
|
|
|
.data.controller = { state.controllers.data[id], button }
|
2018-05-20 18:01:52 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static void onMountChanged(bool mounted) {
|
|
|
|
lovrEventPush((Event) {
|
|
|
|
.type = EVENT_MOUNT,
|
2018-07-26 20:40:15 +00:00
|
|
|
.data.boolean = { mounted }
|
2018-05-20 18:01:52 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-05-28 01:58:30 +00:00
|
|
|
static void onFrame(float* leftView, float* rightView, float* leftProjection, float* rightProjection, void* userdata) {
|
2018-08-30 03:57:30 +00:00
|
|
|
Camera camera = { .canvas = NULL, .stereo = true };
|
2018-08-02 10:40:47 +00:00
|
|
|
memcpy(camera.projection[0], leftProjection, 16 * sizeof(float));
|
|
|
|
memcpy(camera.projection[1], rightProjection, 16 * sizeof(float));
|
|
|
|
memcpy(camera.viewMatrix[0], leftView, 16 * sizeof(float));
|
|
|
|
memcpy(camera.viewMatrix[1], rightView, 16 * sizeof(float));
|
2018-07-21 12:30:13 +00:00
|
|
|
lovrGraphicsSetCamera(&camera, true);
|
|
|
|
state.renderCallback(userdata);
|
2018-07-17 06:51:11 +00:00
|
|
|
lovrGraphicsSetCamera(NULL, false);
|
2018-05-23 09:22:56 +00:00
|
|
|
}
|
|
|
|
|
2018-07-29 01:12:57 +00:00
|
|
|
static bool webvrDriverInit(float offset, int msaa) {
|
2018-05-08 00:46:14 +00:00
|
|
|
vec_init(&state.controllers);
|
2018-05-28 01:58:30 +00:00
|
|
|
|
|
|
|
if (webvrInit(offset, onControllerAdded, onControllerRemoved, onControllerPressed, onControllerReleased, onMountChanged)) {
|
|
|
|
state.renderCallback = NULL;
|
2018-05-23 09:22:56 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
2017-04-16 23:56:49 +00:00
|
|
|
}
|
|
|
|
|
2018-04-29 21:38:08 +00:00
|
|
|
static void webvrDriverDestroy() {
|
2018-05-28 01:58:30 +00:00
|
|
|
webvrDestroy();
|
2018-05-08 00:46:14 +00:00
|
|
|
vec_deinit(&state.controllers);
|
2018-04-12 01:32:16 +00:00
|
|
|
memset(&state, 0, sizeof(HeadsetState));
|
2017-04-16 23:56:49 +00:00
|
|
|
}
|
|
|
|
|
2018-05-09 04:15:41 +00:00
|
|
|
Controller** webvrGetControllers(uint8_t* count) {
|
|
|
|
*count = state.controllers.length;
|
|
|
|
return state.controllers.data;
|
|
|
|
}
|
|
|
|
|
2018-05-23 09:22:56 +00:00
|
|
|
void webvrRenderTo(void (*callback)(void*), void* userdata) {
|
|
|
|
state.renderCallback = callback;
|
|
|
|
webvrSetRenderCallback(onFrame, userdata);
|
|
|
|
}
|
|
|
|
|
2017-10-22 23:44:26 +00:00
|
|
|
HeadsetInterface lovrHeadsetWebVRDriver = {
|
2017-11-25 21:01:56 +00:00
|
|
|
DRIVER_WEBVR,
|
2018-04-29 21:38:08 +00:00
|
|
|
webvrDriverInit,
|
|
|
|
webvrDriverDestroy,
|
2018-05-09 04:15:41 +00:00
|
|
|
webvrGetType,
|
2017-10-21 09:52:07 +00:00
|
|
|
webvrGetOriginType,
|
2018-05-13 23:40:53 +00:00
|
|
|
webvrIsMounted,
|
2017-10-21 09:52:07 +00:00
|
|
|
webvrGetDisplayDimensions,
|
|
|
|
webvrGetClipDistance,
|
|
|
|
webvrSetClipDistance,
|
2018-04-29 21:38:08 +00:00
|
|
|
webvrGetBoundsDimensions,
|
2018-10-10 00:51:05 +00:00
|
|
|
webvrGetBoundsGeometry,
|
2018-05-01 22:10:51 +00:00
|
|
|
webvrGetPose,
|
|
|
|
webvrGetVelocity,
|
2018-05-03 02:36:49 +00:00
|
|
|
webvrGetAngularVelocity,
|
2018-05-09 04:15:41 +00:00
|
|
|
webvrGetControllers,
|
|
|
|
webvrControllerIsConnected,
|
|
|
|
webvrControllerGetHand,
|
|
|
|
webvrControllerGetPose,
|
2018-11-19 15:38:46 +00:00
|
|
|
webvrControllerGetVelocity,
|
|
|
|
webvrControllerGetAngularVelocity,
|
2018-05-13 23:38:46 +00:00
|
|
|
webvrControllerGetAxis,
|
|
|
|
webvrControllerIsDown,
|
|
|
|
webvrControllerIsTouched,
|
2018-05-09 04:15:41 +00:00
|
|
|
webvrControllerVibrate,
|
|
|
|
webvrControllerNewModelData,
|
2017-10-21 09:52:07 +00:00
|
|
|
webvrRenderTo,
|
2019-01-25 20:08:45 +00:00
|
|
|
NULL, // No mirror texture
|
2018-05-20 18:01:52 +00:00
|
|
|
webvrUpdate
|
2017-10-21 09:52:07 +00:00
|
|
|
};
|