Update oculus_mobile backend;

This commit is contained in:
bjorn 2019-04-07 07:09:19 -07:00
parent 77f848ea8f
commit 7a5ae2bfe1
1 changed files with 126 additions and 133 deletions

View File

@ -9,200 +9,193 @@
// Data passed from bridge code to headset code
typedef struct {
static struct {
BridgeLovrDimensions displayDimensions;
BridgeLovrDevice deviceType;
BridgeLovrUpdateData updateData;
} BridgeLovrMobileData;
BridgeLovrMobileData bridgeLovrMobileData;
} bridgeLovrMobileData;
// Headset
static void (*renderCallback)(void*);
static void* renderUserdata;
static float offset;
static struct {
void (*renderCallback)(void*);
void* renderUserdata;
float offset;
} state;
// Headset driver object
static bool oculusMobileInit(float _offset, int msaa) {
static bool init(float offset, int msaa) {
// Make sure HeadsetDriver and BridgeLovrDevice have not gone out of sync
assert(BRIDGE_LOVR_DEVICE_UNKNOWN == HEADSET_UNKNOWN);
assert(BRIDGE_LOVR_DEVICE_GEAR == HEADSET_GEAR);
assert(BRIDGE_LOVR_DEVICE_GO == HEADSET_GO);
offset = _offset;
state.offset = offset;
return true;
}
static void oculusMobileDestroy() {
static void destroy() {
//
}
static HeadsetType oculusMobileGetType() {
return (HeadsetType) bridgeLovrMobileData.deviceType;
static const char* getName() {
switch (bridgeLovrMobileData.deviceType) {
case BRIDGE_LOVR_DEVICE_GEAR: return "Gear VR";
case BRIDGE_LOVR_DEVICE_GO: return "Oculus Go";
default: return NULL;
}
}
static HeadsetOrigin oculusMobileGetOriginType() {
static HeadsetOrigin getOriginType() {
return ORIGIN_HEAD;
}
static bool oculusMobileIsMounted() {
return true;
}
static void oculusMobileGetDisplayDimensions(uint32_t* width, uint32_t* height) {
static void getDisplayDimensions(uint32_t* width, uint32_t* height) {
*width = bridgeLovrMobileData.displayDimensions.width;
*height = bridgeLovrMobileData.displayDimensions.height;
}
static void oculusMobileGetClipDistance(float* clipNear, float* clipFar) {
static void getClipDistance(float* clipNear, float* clipFar) {
// TODO
}
static void oculusMobileSetClipDistance(float clipNear, float clipFar) {
static void setClipDistance(float clipNear, float clipFar) {
// TODO
}
static void oculusMobileGetBoundsDimensions(float* width, float* depth) {
static void getBoundsDimensions(float* width, float* depth) {
*width = 0.f;
*depth = 0.f;
}
static const float* oculusMobileGetBoundsGeometry(int* count) {
static const float* getBoundsGeometry(int* count) {
*count = 0;
return NULL;
}
static bool oculusMobileGetPose(float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az) {
*x = bridgeLovrMobileData.updateData.lastHeadPose.x;
*y = bridgeLovrMobileData.updateData.lastHeadPose.y + offset; // Correct for head height
*z = bridgeLovrMobileData.updateData.lastHeadPose.z;
quat_getAngleAxis(bridgeLovrMobileData.updateData.lastHeadPose.q, angle, ax, ay, az);
return true;
}
static bool oculusMobileGetVelocity(float* vx, float* vy, float* vz) {
*vx = bridgeLovrMobileData.updateData.lastHeadVelocity.x;
*vy = bridgeLovrMobileData.updateData.lastHeadVelocity.y;
*vz = bridgeLovrMobileData.updateData.lastHeadVelocity.z;
return true;
}
static bool oculusMobileGetAngularVelocity(float* vx, float* vy, float* vz) {
*vx = bridgeLovrMobileData.updateData.lastHeadVelocity.ax;
*vy = bridgeLovrMobileData.updateData.lastHeadVelocity.ay;
*vz = bridgeLovrMobileData.updateData.lastHeadVelocity.az;
return true;
}
static Controller *controller;
static Controller** oculusMobileGetControllers(uint8_t* count) {
if (!controller)
controller = lovrAlloc(Controller);
*count = bridgeLovrMobileData.updateData.goPresent; // TODO: Figure out what multi controller Oculus Mobile looks like and support it
return &controller;
}
static bool oculusMobileControllerIsConnected(Controller* controller) {
return bridgeLovrMobileData.updateData.goPresent;
}
static ControllerHand oculusMobileControllerGetHand(Controller* controller) {
return HAND_UNKNOWN;
}
static void oculusMobileControllerGetPose(Controller* controller, float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az) {
*x = bridgeLovrMobileData.updateData.goPose.x;
*y = bridgeLovrMobileData.updateData.goPose.y + offset; // Correct for head height
*z = bridgeLovrMobileData.updateData.goPose.z;
quat_getAngleAxis(bridgeLovrMobileData.updateData.goPose.q, angle, ax, ay, az);
}
static void oculusMobileControllerGetVelocity(Controller* controller, float* vx, float* vy, float* vz) {
*vx = bridgeLovrMobileData.updateData.goVelocity.x;
*vy = bridgeLovrMobileData.updateData.goVelocity.y;
*vz = bridgeLovrMobileData.updateData.goVelocity.z;
}
static void oculusMobileControllerGetAngularVelocity(Controller* controller, float* vx, float* vy, float* vz) {
*vx = bridgeLovrMobileData.updateData.goVelocity.ax;
*vy = bridgeLovrMobileData.updateData.goVelocity.ay;
*vz = bridgeLovrMobileData.updateData.goVelocity.az;
}
static float oculusMobileControllerGetAxis(Controller* controller, ControllerAxis axis) {
switch (axis) {
case CONTROLLER_AXIS_TOUCHPAD_X:
return (bridgeLovrMobileData.updateData.goTrackpad.x - 160.f) / 160.f;
case CONTROLLER_AXIS_TOUCHPAD_Y:
return (bridgeLovrMobileData.updateData.goTrackpad.y - 160.f) / 160.f;
case CONTROLLER_AXIS_TRIGGER:
return bridgeLovrMobileData.updateData.goButtonDown ? 1.f : 0.f;
default:
return 0.f;
static bool getPose(Path path, float* x, float* y, float* z, float* angle, float* ax, float* ay, float* az) {
if (PATH_EQ(path, P_HEAD)) {
*x = bridgeLovrMobileData.updateData.lastHeadPose.x;
*y = bridgeLovrMobileData.updateData.lastHeadPose.y + state.offset; // Correct for head height
*z = bridgeLovrMobileData.updateData.lastHeadPose.z;
quat_getAngleAxis(bridgeLovrMobileData.updateData.lastHeadPose.q, angle, ax, ay, az);
return true;
} else if (PATH_EQ(path, P_HAND)) {
*x = bridgeLovrMobileData.updateData.goPose.x;
*y = bridgeLovrMobileData.updateData.goPose.y + state.offset; // Correct for head height
*z = bridgeLovrMobileData.updateData.goPose.z;
quat_getAngleAxis(bridgeLovrMobileData.updateData.goPose.q, angle, ax, ay, az);
return true;
}
return false;
}
static bool buttonCheck(BridgeLovrButton field, ControllerButton button) {
switch (button) {
case CONTROLLER_BUTTON_MENU: return field & BRIDGE_LOVR_BUTTON_MENU;
case CONTROLLER_BUTTON_TRIGGER: return field & BRIDGE_LOVR_BUTTON_SHOULDER;
case CONTROLLER_BUTTON_TOUCHPAD: return field & BRIDGE_LOVR_BUTTON_TOUCHPAD;
static bool getVelocity(Path path, float* vx, float* vy, float* vz) {
if (PATH_EQ(path, P_HEAD)) {
*vx = bridgeLovrMobileData.updateData.lastHeadVelocity.x;
*vy = bridgeLovrMobileData.updateData.lastHeadVelocity.y;
*vz = bridgeLovrMobileData.updateData.lastHeadVelocity.z;
return true;
} else if (PATH_EQ(path, P_HAND)) {
*vx = bridgeLovrMobileData.updateData.goVelocity.x;
*vy = bridgeLovrMobileData.updateData.goVelocity.y;
*vz = bridgeLovrMobileData.updateData.goVelocity.z;
return true;
}
return false;
}
static bool getAngularVelocity(Path path, float* vx, float* vy, float* vz) {
if (PATH_EQ(path, P_HEAD)) {
*vx = bridgeLovrMobileData.updateData.lastHeadVelocity.ax;
*vy = bridgeLovrMobileData.updateData.lastHeadVelocity.ay;
*vz = bridgeLovrMobileData.updateData.lastHeadVelocity.az;
return true;
} else if (PATH_EQ(path, P_HAND)) {
*vx = bridgeLovrMobileData.updateData.goVelocity.ax;
*vy = bridgeLovrMobileData.updateData.goVelocity.ay;
*vz = bridgeLovrMobileData.updateData.goVelocity.az;
return true;
}
return false;
}
static bool buttonCheck(BridgeLovrButton field, Path path, bool* result) {
if (!PATH_EQ(path, PATH_HAND) || path.p[2] != PATH_NONE) {
return false; // Path needs to start with /hand and have exactly one more piece
}
switch (path.p[1]) {
case P_MENU: *result = (field & BRIDGE_LOVR_BUTTON_MENU); return true;
case P_TRIGGER: *result = (field & BRIDGE_LOVR_BUTTON_SHOULDER); return true;
case P_TRACKPAD: *result = (field & BRIDGE_LOVR_BUTTON_TOUCHPAD); return true;
default: return false;
}
}
static bool oculusMobileControllerIsDown(Controller* controller, ControllerButton button) {
return buttonCheck(bridgeLovrMobileData.updateData.goButtonDown, button);
static bool isDown(Path path, bool* down) {
return buttonCheck(bridgeLovrMobileData.updateData.goButtonDown, path, down);
}
static bool oculusMobileControllerIsTouched(Controller* controller, ControllerButton button) {
return buttonCheck(bridgeLovrMobileData.updateData.goButtonTouch, button);
static bool isTouched(Path path, bool* touched) {
return buttonCheck(bridgeLovrMobileData.updateData.goButtonTouch, path, touched);
}
static void oculusMobileControllerVibrate(Controller* controller, float duration, float power) {
//
static int getAxis(Path path, float* x, float* y, float* z) {
if (!PATH_EQ(path, PATH_HAND) || path.p[2] != PATH_NONE) {
return 0; // Path needs to start with /hand and have exactly one more piece
}
switch (path.p[1]) {
case P_TOUCHPAD:
*x = (bridgeLovrMobileData.updateData.goTrackpad.x - 160.f) / 160.f;
*y = (bridgeLovrMobileData.updateData.goTrackpad.y - 160.f) / 160.f;
return 2;
case P_TRIGGER:
*x = bridgeLovrMobileData.updateData.goButtonDown ? 1.f : 0.f;
return 1;
default:
return 0;
}
}
static ModelData* oculusMobileControllerNewModelData(Controller* controller) {
static bool vibrate(Path path, float strength, float duration, float frequency) {
return false;
}
static ModelData* newModelData(Path path) {
return NULL;
}
// TODO: need to set up swap chain textures for the eyes and finish view transforms
static void oculusMobileRenderTo(void (*callback)(void*), void* userdata) {
renderCallback = callback;
renderUserdata = userdata;
static void renderTo(void (*callback)(void*), void* userdata) {
state.renderCallback = callback;
state.renderUserdata = userdata;
}
HeadsetInterface lovrHeadsetOculusMobileDriver = {
.driverType = DRIVER_OCULUS_MOBILE,
.init = oculusMobileInit,
.destroy = oculusMobileDestroy,
.getType = oculusMobileGetType,
.getOriginType = oculusMobileGetOriginType,
.isMounted = oculusMobileIsMounted,
.getDisplayDimensions = oculusMobileGetDisplayDimensions,
.getClipDistance = oculusMobileGetClipDistance,
.setClipDistance = oculusMobileSetClipDistance,
.getBoundsDimensions = oculusMobileGetBoundsDimensions,
.getBoundsGeometry = oculusMobileGetBoundsGeometry,
.getPose = oculusMobileGetPose,
.getVelocity = oculusMobileGetVelocity,
.getAngularVelocity = oculusMobileGetAngularVelocity,
.getControllers = oculusMobileGetControllers,
.controllerIsConnected = oculusMobileControllerIsConnected,
.controllerGetHand = oculusMobileControllerGetHand,
.controllerGetPose = oculusMobileControllerGetPose,
.controllerGetVelocity = oculusMobileControllerGetVelocity,
.controllerGetAngularVelocity = oculusMobileControllerGetAngularVelocity,
.controllerGetAxis = oculusMobileControllerGetAxis,
.controllerIsDown = oculusMobileControllerIsDown,
.controllerIsTouched = oculusMobileControllerIsTouched,
.controllerVibrate = oculusMobileControllerVibrate,
.controllerNewModelData = oculusMobileControllerNewModelData,
.renderTo = oculusMobileRenderTo
.init = init,
.destroy = destroy,
.getType = getType,
.getOriginType = getOriginType,
.isMounted = isMounted,
.getDisplayDimensions = getDisplayDimensions,
.getClipDistance = getClipDistance,
.setClipDistance = setClipDistance,
.getBoundsDimensions = getBoundsDimensions,
.getBoundsGeometry = getBoundsGeometry,
.getPose = getPose,
.getVelocity = getVelocity,
.getAngularVelocity = getAngularVelocity,
.isDown = isDown,
.isTouched = isTouched,
.getAxis = getAxis,
.vibrate = vibrate,
.newModelData = newModelData,
.renderTo = renderTo
};
// Oculus-specific platform functions
@ -412,14 +405,14 @@ static void lovrOculusMobileDraw(int framebuffer, int width, int height, float *
Camera camera = { .canvas = &canvas, .stereo = false };
memcpy(camera.viewMatrix[0], eyeViewMatrix, sizeof(camera.viewMatrix[0]));
mat4_translate(camera.viewMatrix[0], 0, -offset, 0);
mat4_translate(camera.viewMatrix[0], 0, -state.offset, 0);
memcpy(camera.projection[0], projectionMatrix, sizeof(camera.projection[0]));
lovrGraphicsSetCamera(&camera, true);
if (renderCallback) {
renderCallback(renderUserdata);
if (state.renderCallback) {
state.renderCallback(state.renderUserdata);
}
lovrGraphicsSetCamera(NULL, false);