mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-04 13:33:34 +00:00
Rework fake headset driver inertia;
This commit is contained in:
parent
7aedff1278
commit
b29a2d0471
|
@ -10,7 +10,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct {
|
static struct {
|
||||||
HeadsetType type;
|
HeadsetType type;
|
||||||
bool mirrored;
|
bool mirrored;
|
||||||
float offset;
|
float offset;
|
||||||
|
@ -22,6 +22,7 @@ typedef struct {
|
||||||
|
|
||||||
float position[3];
|
float position[3];
|
||||||
float velocity[3];
|
float velocity[3];
|
||||||
|
float localVelocity[3];
|
||||||
float angularVelocity[3];
|
float angularVelocity[3];
|
||||||
|
|
||||||
double yaw;
|
double yaw;
|
||||||
|
@ -29,78 +30,21 @@ typedef struct {
|
||||||
float transform[16];
|
float transform[16];
|
||||||
|
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
bool mouselook;
|
|
||||||
double prevCursorX;
|
double prevCursorX;
|
||||||
double prevCursorY;
|
double prevCursorY;
|
||||||
double prevMove;
|
} state;
|
||||||
} FakeHeadsetState;
|
|
||||||
|
|
||||||
static FakeHeadsetState state;
|
|
||||||
|
|
||||||
static void enableMouselook(GLFWwindow* window) {
|
|
||||||
if (window) {
|
|
||||||
glfwGetCursorPos(window, &state.prevCursorX, &state.prevCursorY);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.mouselook = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disableMouselook(GLFWwindow* window) {
|
|
||||||
state.mouselook = false;
|
|
||||||
if (glfwGetTime() - state.prevMove > .1) {
|
|
||||||
vec3_set(state.angularVelocity, 0, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onFocus(GLFWwindow* window, int focused) {
|
|
||||||
if (!focused) {
|
|
||||||
disableMouselook(window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onMouseMove(GLFWwindow* window, double xpos, double ypos) {
|
|
||||||
if (!state.mouselook) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double dx = xpos - state.prevCursorX;
|
|
||||||
double dy = ypos - state.prevCursorY;
|
|
||||||
state.prevCursorX = xpos;
|
|
||||||
state.prevCursorY = ypos;
|
|
||||||
|
|
||||||
const double k = 0.003;
|
|
||||||
const double l = 0.003;
|
|
||||||
|
|
||||||
double t = glfwGetTime();
|
|
||||||
|
|
||||||
state.yaw -= dx * k;
|
|
||||||
state.pitch = CLAMP(state.pitch - dy * l, -M_PI / 2., M_PI / 2.);
|
|
||||||
state.angularVelocity[0] = dy / (t - state.prevMove);
|
|
||||||
state.angularVelocity[1] = dx / (t - state.prevMove);
|
|
||||||
|
|
||||||
state.prevMove = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void onMouseButton(GLFWwindow* window, int button, int action, int mods) {
|
static void onMouseButton(GLFWwindow* window, int button, int action, int mods) {
|
||||||
if (button == GLFW_MOUSE_BUTTON_LEFT) {
|
if (button != GLFW_MOUSE_BUTTON_RIGHT) {
|
||||||
if (!state.mouselook && action == GLFW_PRESS) {
|
|
||||||
enableMouselook(window);
|
|
||||||
} else if (state.mouselook && action == GLFW_RELEASE) {
|
|
||||||
disableMouselook(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller* controller;
|
Controller* controller; int i;
|
||||||
int i;
|
|
||||||
vec_foreach(&state.controllers, controller, i) {
|
vec_foreach(&state.controllers, controller, i) {
|
||||||
if (button == GLFW_MOUSE_BUTTON_RIGHT) {
|
lovrEventPush((Event) {
|
||||||
lovrEventPush((Event) {
|
.type = action == GLFW_PRESS ? EVENT_CONTROLLER_PRESSED : EVENT_CONTROLLER_RELEASED,
|
||||||
.type = action == GLFW_PRESS ? EVENT_CONTROLLER_PRESSED : EVENT_CONTROLLER_RELEASED,
|
.data.controller = { controller, CONTROLLER_BUTTON_TRIGGER }
|
||||||
.data.controller = { controller, CONTROLLER_BUTTON_TRIGGER }
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,20 +57,9 @@ static void updateWindow() {
|
||||||
|
|
||||||
state.window = window;
|
state.window = window;
|
||||||
if (window) {
|
if (window) {
|
||||||
|
glfwSwapInterval(1);
|
||||||
GLFWmousebuttonfun prevMouseButton = glfwSetMouseButtonCallback(window, onMouseButton);
|
GLFWmousebuttonfun prevMouseButton = glfwSetMouseButtonCallback(window, onMouseButton);
|
||||||
if (prevMouseButton) glfwSetMouseButtonCallback(window, prevMouseButton);
|
if (prevMouseButton) glfwSetMouseButtonCallback(window, prevMouseButton);
|
||||||
|
|
||||||
GLFWcursorposfun prevMouseMove = glfwSetCursorPosCallback(window, onMouseMove);
|
|
||||||
if (prevMouseMove) glfwSetCursorPosCallback(window, prevMouseMove);
|
|
||||||
|
|
||||||
GLFWwindowfocusfun prevFocus = glfwSetWindowFocusCallback(window, onFocus);
|
|
||||||
if (prevFocus) glfwSetWindowFocusCallback(window, onFocus);
|
|
||||||
|
|
||||||
if (state.mouselook) {
|
|
||||||
enableMouselook(window);
|
|
||||||
} else {
|
|
||||||
disableMouselook(window);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,31 +70,24 @@ static bool fakeInit(float offset, int msaa) {
|
||||||
state.clipNear = 0.1f;
|
state.clipNear = 0.1f;
|
||||||
state.clipFar = 100.f;
|
state.clipFar = 100.f;
|
||||||
|
|
||||||
state.pitch = 0.0;
|
|
||||||
state.yaw = 0.0;
|
|
||||||
mat4_identity(state.transform);
|
mat4_identity(state.transform);
|
||||||
|
|
||||||
vec3_set(state.velocity, 0, 0, 0);
|
|
||||||
vec3_set(state.position, 0, 0, 0);
|
|
||||||
|
|
||||||
vec_init(&state.controllers);
|
vec_init(&state.controllers);
|
||||||
Controller* controller = lovrAlloc(Controller, free);
|
Controller* controller = lovrAlloc(Controller, free);
|
||||||
controller->id = 0;
|
controller->id = 0;
|
||||||
vec_push(&state.controllers, controller);
|
vec_push(&state.controllers, controller);
|
||||||
|
|
||||||
state.mouselook = false;
|
|
||||||
state.window = NULL;
|
state.window = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fakeDestroy() {
|
static void fakeDestroy() {
|
||||||
int i;
|
Controller *controller; int i;
|
||||||
Controller *controller;
|
|
||||||
vec_foreach(&state.controllers, controller, i) {
|
vec_foreach(&state.controllers, controller, i) {
|
||||||
lovrRelease(controller);
|
lovrRelease(controller);
|
||||||
}
|
}
|
||||||
vec_deinit(&state.controllers);
|
vec_deinit(&state.controllers);
|
||||||
memset(&state, 0, sizeof(FakeHeadsetState));
|
memset(&state, 0, sizeof(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
static HeadsetType fakeGetType() {
|
static HeadsetType fakeGetType() {
|
||||||
|
@ -309,20 +235,53 @@ static void fakeUpdate(float dt) {
|
||||||
bool up = glfwGetKey(state.window, GLFW_KEY_Q) == GLFW_PRESS;
|
bool up = glfwGetKey(state.window, GLFW_KEY_Q) == GLFW_PRESS;
|
||||||
bool down = glfwGetKey(state.window, GLFW_KEY_E) == GLFW_PRESS;
|
bool down = glfwGetKey(state.window, GLFW_KEY_E) == GLFW_PRESS;
|
||||||
|
|
||||||
float k = 4.0f * dt;
|
float movespeed = 3.f * dt;
|
||||||
state.velocity[0] = left ? -k : (right ? k : 0);
|
float turnspeed = 3.f * dt;
|
||||||
state.velocity[1] = up ? k : (down ? -k : 0);
|
double damping = MAX(1 - 20 * dt, 0);
|
||||||
state.velocity[2] = front ? -k : (back ? k : 0);
|
|
||||||
|
|
||||||
mat4_transformDirection(state.transform, &state.velocity[0], &state.velocity[1], &state.velocity[2]);
|
if (glfwGetMouseButton(state.window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) {
|
||||||
vec3_add(state.position, state.velocity);
|
glfwSetInputMode(state.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
|
||||||
if (!state.mouselook) {
|
int width, height;
|
||||||
state.pitch = CLAMP(state.pitch - state.angularVelocity[0] * .002 * dt, -M_PI / 2., M_PI / 2.);
|
glfwGetWindowSize(state.window, &width, &height);
|
||||||
state.yaw -= state.angularVelocity[1] * .002 * dt;
|
|
||||||
vec3_scale(state.angularVelocity, pow(.001, dt));
|
double mx, my;
|
||||||
|
glfwGetCursorPos(state.window, &mx, &my);
|
||||||
|
|
||||||
|
if (state.prevCursorX == -1 && state.prevCursorY == -1) {
|
||||||
|
state.prevCursorX = mx;
|
||||||
|
state.prevCursorY = my;
|
||||||
|
}
|
||||||
|
|
||||||
|
double aspect = (double) width / height;
|
||||||
|
double dx = (mx - state.prevCursorX) / ((double) width);
|
||||||
|
double dy = (my - state.prevCursorY) / ((double) height * aspect);
|
||||||
|
state.angularVelocity[0] = dy / dt;
|
||||||
|
state.angularVelocity[1] = dx / dt;
|
||||||
|
state.prevCursorX = mx;
|
||||||
|
state.prevCursorY = my;
|
||||||
|
} else {
|
||||||
|
glfwSetInputMode(state.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
vec3_scale(state.angularVelocity, damping);
|
||||||
|
state.prevCursorX = state.prevCursorY = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update velocity
|
||||||
|
state.localVelocity[0] = left ? -movespeed : (right ? movespeed : state.localVelocity[0]);
|
||||||
|
state.localVelocity[1] = up ? movespeed : (down ? -movespeed : state.localVelocity[1]);
|
||||||
|
state.localVelocity[2] = front ? -movespeed : (back ? movespeed : state.localVelocity[2]);
|
||||||
|
vec3_init(state.velocity, state.localVelocity);
|
||||||
|
mat4_transformDirection(state.transform, &state.velocity[0], &state.velocity[1], &state.velocity[2]);
|
||||||
|
vec3_scale(state.localVelocity, damping);
|
||||||
|
|
||||||
|
// Update position
|
||||||
|
vec3_add(state.position, state.velocity);
|
||||||
|
|
||||||
|
// Update orientation
|
||||||
|
state.pitch = CLAMP(state.pitch - state.angularVelocity[0] * turnspeed, -M_PI / 2., M_PI / 2.);
|
||||||
|
state.yaw -= state.angularVelocity[1] * turnspeed;
|
||||||
|
|
||||||
|
// Update transform
|
||||||
mat4_identity(state.transform);
|
mat4_identity(state.transform);
|
||||||
mat4_translate(state.transform, state.position[0], state.position[1], state.position[2]);
|
mat4_translate(state.transform, state.position[0], state.position[1], state.position[2]);
|
||||||
mat4_rotate(state.transform, state.yaw, 0, 1, 0);
|
mat4_rotate(state.transform, state.yaw, 0, 1, 0);
|
||||||
|
|
Loading…
Reference in a new issue