1
0
Fork 0
mirror of https://github.com/bjornbytes/lovr.git synced 2024-07-18 11:43:34 +00:00
lovr/src/headset/webvr.c

157 lines
5.4 KiB
C
Raw Normal View History

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);
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);
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);
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) {
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));
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
}
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 = {
DRIVER_WEBVR,
2018-04-29 21:38:08 +00:00
webvrDriverInit,
webvrDriverDestroy,
2018-05-09 04:15:41 +00:00
webvrGetType,
webvrGetOriginType,
2018-05-13 23:40:53 +00:00
webvrIsMounted,
webvrGetDisplayDimensions,
webvrGetClipDistance,
webvrSetClipDistance,
2018-04-29 21:38:08 +00:00
webvrGetBoundsDimensions,
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,
webvrControllerGetVelocity,
webvrControllerGetAngularVelocity,
2018-05-13 23:38:46 +00:00
webvrControllerGetAxis,
webvrControllerIsDown,
webvrControllerIsTouched,
2018-05-09 04:15:41 +00:00
webvrControllerVibrate,
webvrControllerNewModelData,
webvrRenderTo,
2019-01-25 20:08:45 +00:00
NULL, // No mirror texture
2018-05-20 18:01:52 +00:00
webvrUpdate
};