dt uses headset time instead of system time;

This commit is contained in:
bjorn 2022-03-22 17:52:16 -07:00
parent d1dc2f3199
commit 1f3c5dea79
7 changed files with 63 additions and 20 deletions

View File

@ -583,19 +583,20 @@ static int l_lovrHeadsetRenderTo(lua_State* L) {
}
static int l_lovrHeadsetUpdate(lua_State* L) {
float dt = luax_checkfloat(L, 1);
double dt = 0.;
if (lovrHeadsetDisplayDriver->update) {
lovrHeadsetDisplayDriver->update(dt);
dt = lovrHeadsetDisplayDriver->update();
}
FOREACH_TRACKING_DRIVER(driver) {
if (driver->update && driver != lovrHeadsetDisplayDriver) {
driver->update(dt);
driver->update();
}
}
return 0;
lua_pushnumber(L, dt);
return 1;
}
static int l_lovrHeadsetGetTime(lua_State* L) {
@ -603,6 +604,11 @@ static int l_lovrHeadsetGetTime(lua_State* L) {
return 1;
}
static int l_lovrHeadsetGetDeltaTime(lua_State* L) {
lua_pushnumber(L, lovrHeadsetDisplayDriver->getDeltaTime());
return 1;
}
static int l_lovrHeadsetGetMirrorTexture(lua_State* L) {
Texture* texture = NULL;
if (lovrHeadsetDisplayDriver->getMirrorTexture)
@ -672,6 +678,7 @@ static const luaL_Reg lovrHeadset[] = {
{ "renderTo", l_lovrHeadsetRenderTo },
{ "update", l_lovrHeadsetUpdate },
{ "getTime", l_lovrHeadsetGetTime },
{ "getDeltaTime", l_lovrHeadsetGetDeltaTime },
{ "getMirrorTexture", l_lovrHeadsetGetMirrorTexture },
{ "getHands", l_lovrHeadsetGetHands },
{ NULL, NULL }

View File

@ -121,6 +121,7 @@ typedef struct HeadsetInterface {
float (*getDisplayFrequency)(void);
const float* (*getDisplayMask)(uint32_t* count);
double (*getDisplayTime)(void);
double (*getDeltaTime)(void);
uint32_t (*getViewCount)(void);
bool (*getViewPose)(uint32_t view, float* position, float* orientation);
bool (*getViewAngles)(uint32_t view, float* left, float* right, float* up, float* down);
@ -139,7 +140,7 @@ typedef struct HeadsetInterface {
bool (*animate)(Device device, struct Model* model);
void (*renderTo)(void (*callback)(void*), void* userdata);
struct Texture* (*getMirrorTexture)(void);
void (*update)(float dt);
double (*update)(void);
} HeadsetInterface;
// Available drivers

View File

@ -20,6 +20,8 @@ static struct {
float angularVelocity[4];
float headTransform[16];
float leftHandTransform[16];
double prevDisplayTime;
double nextDisplayTime;
double prevCursorX;
double prevCursorY;
bool mouseDown;
@ -29,12 +31,16 @@ static struct {
float clipFar;
float pitch;
float yaw;
double prevTime;
double nextTime;
} state;
static bool desktop_init(float supersample, float offset, uint32_t msaa, bool overlay) {
state.offset = offset;
state.clipNear = .1f;
state.clipFar = 100.f;
state.prevDisplayTime = os_get_time();
state.nextDisplayTime = state.prevDisplayTime;
if (!state.initialized) {
mat4_identity(state.headTransform);
@ -66,7 +72,11 @@ static HeadsetOrigin desktop_getOriginType(void) {
}
static double desktop_getDisplayTime(void) {
return os_get_time();
return state.nextDisplayTime;
}
static double desktop_getDeltaTime(void) {
return state.nextDisplayTime - state.prevDisplayTime;
}
static void desktop_getDisplayDimensions(uint32_t* width, uint32_t* height) {
@ -198,7 +208,7 @@ static void desktop_renderTo(void (*callback)(void*), void* userdata) {
lovrGraphicsSetBackbuffer(NULL, false, false);
}
static void desktop_update(float dt) {
static double desktop_update(void) {
bool front = os_is_key_down(KEY_W) || os_is_key_down(KEY_UP);
bool back = os_is_key_down(KEY_S) || os_is_key_down(KEY_DOWN);
bool left = os_is_key_down(KEY_A) || os_is_key_down(KEY_LEFT);
@ -206,9 +216,13 @@ static void desktop_update(float dt) {
bool up = os_is_key_down(KEY_Q);
bool down = os_is_key_down(KEY_E);
float movespeed = 3.f * dt;
float turnspeed = 3.f * dt;
float damping = MAX(1.f - 20.f * dt, 0);
state.prevDisplayTime = state.nextDisplayTime;
state.nextDisplayTime = os_get_time();
double dt = state.nextDisplayTime - state.prevDisplayTime;
float movespeed = 3.f * (float) dt;
float turnspeed = 3.f * (float) dt;
float damping = MAX(1.f - 20.f * (float) dt, 0);
int width, height;
double mx, my;
@ -228,8 +242,8 @@ static void desktop_update(float dt) {
float dx = (float) (mx - state.prevCursorX) / ((float) width);
float dy = (float) (my - state.prevCursorY) / ((float) height * aspect);
state.angularVelocity[0] = dy / dt;
state.angularVelocity[1] = dx / dt;
state.angularVelocity[0] = dy / (float) dt;
state.angularVelocity[1] = dx / (float) dt;
state.prevCursorX = mx;
state.prevCursorY = my;
} else {
@ -284,6 +298,7 @@ static void desktop_update(float dt) {
mat4_translate(state.leftHandTransform, 0, 0, -.20f);
mat4_rotate(state.leftHandTransform, -px * xrange, 0, 1, 0);
mat4_rotate(state.leftHandTransform, -py * yrange, 1, 0, 0);
return dt;
}
HeadsetInterface lovrHeadsetDesktopDriver = {
@ -294,6 +309,7 @@ HeadsetInterface lovrHeadsetDesktopDriver = {
.getName = desktop_getName,
.getOriginType = desktop_getOriginType,
.getDisplayTime = desktop_getDisplayTime,
.getDeltaTime = desktop_getDeltaTime,
.getDisplayDimensions = desktop_getDisplayDimensions,
.getDisplayMask = desktop_getDisplayMask,
.getViewCount = desktop_getViewCount,

View File

@ -169,6 +169,7 @@ static struct {
XrCompositionLayerProjectionView layerViews[2];
XrFrameState frameState;
Canvas* canvases[MAX_IMAGES];
double lastDisplayTime;
uint32_t imageIndex;
uint32_t imageCount;
uint32_t msaa;
@ -1021,6 +1022,10 @@ static double openxr_getDisplayTime(void) {
return state.frameState.predictedDisplayTime / 1e9;
}
static double openxr_getDeltaTime(void) {
return (state.frameState.predictedDisplayTime - state.lastDisplayTime) / 1e9;
}
static void getViews(XrView views[2], uint32_t* count) {
XrViewLocateInfo viewLocateInfo = {
.type = XR_TYPE_VIEW_LOCATE_INFO,
@ -1714,7 +1719,7 @@ static Texture* openxr_getMirrorTexture(void) {
return canvas ? lovrCanvasGetAttachments(canvas, NULL)[0].texture : NULL;
}
static void openxr_update(float dt) {
static double openxr_update(void) {
XrEventDataBuffer e; // Not using designated initializers here to avoid an implicit 4k zero
e.type = XR_TYPE_EVENT_DATA_BUFFER;
e.next = NULL;
@ -1759,8 +1764,13 @@ static void openxr_update(float dt) {
}
if (SESSION_ACTIVE(state.sessionState)) {
state.lastDisplayTime = state.frameState.predictedDisplayTime;
XR(xrWaitFrame(state.session, NULL, &state.frameState));
if (state.lastDisplayTime == 0.) {
state.lastDisplayTime = state.frameState.predictedDisplayTime - state.frameState.predictedDisplayPeriod;
}
XrActionsSyncInfo syncInfo = {
.type = XR_TYPE_ACTIONS_SYNC_INFO,
.countActiveActionSets = 2,
@ -1772,6 +1782,8 @@ static void openxr_update(float dt) {
XR(xrSyncActions(state.session, &syncInfo));
}
return openxr_getDeltaTime();
}
HeadsetInterface lovrHeadsetOpenXRDriver = {
@ -1785,6 +1797,7 @@ HeadsetInterface lovrHeadsetOpenXRDriver = {
.getDisplayFrequency = openxr_getDisplayFrequency,
.getDisplayMask = openxr_getDisplayMask,
.getDisplayTime = openxr_getDisplayTime,
.getDeltaTime = openxr_getDeltaTime,
.getViewCount = openxr_getViewCount,
.getViewPose = openxr_getViewPose,
.getViewAngles = openxr_getViewAngles,

View File

@ -6,6 +6,7 @@ extern void webxr_destroy(void);
extern bool webxr_getName(char* name, size_t length);
extern HeadsetOrigin webxr_getOriginType(void);
extern double webxr_getDisplayTime(void);
extern double webxr_getDeltaTime(void);
extern void webxr_getDisplayDimensions(uint32_t* width, uint32_t* height);
extern const float* webxr_getDisplayMask(uint32_t* count);
extern uint32_t webxr_getViewCount(void);
@ -25,7 +26,7 @@ extern bool webxr_vibrate(Device device, float strength, float duration, float f
extern struct ModelData* webxr_newModelData(Device device, bool animated);
extern bool webxr_animate(Device device, struct Model* model);
extern void webxr_renderTo(void (*callback)(void*), void* userdata);
extern void webxr_update(float dt);
extern double webxr_update(void);
static bool webxrAttached = false;
static HeadsetInterface* previousHeadsetDriver;

View File

@ -175,7 +175,6 @@ function lovr.boot()
end
function lovr.run()
local dt = 0
if lovr.timer then lovr.timer.step() end
if lovr.load then lovr.load(arg) end
return function()
@ -191,8 +190,9 @@ function lovr.run()
if lovr.handlers[name] then lovr.handlers[name](a, b, c, d) end
end
end
local dt = 0
if lovr.timer then dt = lovr.timer.step() end
if lovr.headset then lovr.headset.update(dt) end
if lovr.headset then dt = lovr.headset.update() end
if lovr.update then lovr.update(dt) end
if lovr.graphics then
lovr.graphics.origin()
@ -258,7 +258,7 @@ function lovr.errhand(message, traceback)
end
lovr.graphics.origin()
if lovr.headset then
lovr.headset.update(0)
lovr.headset.update()
lovr.headset.renderTo(render)
end
if lovr.graphics.hasWindow() then

View File

@ -137,8 +137,9 @@ var webxr = {
Module['_webxr_attach']();
Browser.requestAnimationFrame = function(fn) {
return session.requestAnimationFrame(function(t, frame) {
state.displayTime = t;
state.frame = frame;
state.lastDisplayTime = state.displayTime || state.frame.predictedDisplayTime;
state.displayTime = state.frame.predictedDisplayTime;
state.viewer = state.frame.getViewerPose(state.space);
fn();
state.hands.forEach(function(inputSource, i) {
@ -185,6 +186,10 @@ var webxr = {
return state.displayTime / 1000.0;
},
webxr_getDeltaTime: function() {
return (state.displayTime - state.lastDisplayTime) / 1000.0;
},
webxr_getDisplayDimensions: function(width, height) {
HEAPU32[width >> 2] = state.layer.framebufferWidth;
HEAPU32[height >> 2] = state.layer.framebufferHeight;
@ -406,8 +411,8 @@ var webxr = {
Module._lovrGraphicsSetBackbuffer(0, false, false);
},
webxr_update: function(dt) {
//
webxr_update: function() {
return (state.displayTime - state.lastDisplayTime) / 1000.0;
}
};