mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-17 04:39:34 +00:00
OpenXR - VR code formatting fixed
This commit is contained in:
parent
8daba0d881
commit
13221edbfc
240
VR/VRBase.cpp
240
VR/VRBase.cpp
@ -9,155 +9,155 @@ static engine_t vr_engine;
|
||||
int vr_initialized = 0;
|
||||
|
||||
const char* const requiredExtensionNames[] = {
|
||||
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
|
||||
XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME};
|
||||
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
|
||||
XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME};
|
||||
const uint32_t numRequiredExtensions =
|
||||
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);
|
||||
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);
|
||||
|
||||
void VR_Init( ovrJava java ) {
|
||||
if (vr_initialized)
|
||||
return;
|
||||
if (vr_initialized)
|
||||
return;
|
||||
|
||||
ovrApp_Clear(&vr_engine.appState);
|
||||
ovrApp_Clear(&vr_engine.appState);
|
||||
|
||||
PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
|
||||
xrGetInstanceProcAddr(
|
||||
XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&xrInitializeLoaderKHR);
|
||||
if (xrInitializeLoaderKHR != NULL) {
|
||||
XrLoaderInitInfoAndroidKHR loaderInitializeInfoAndroid;
|
||||
memset(&loaderInitializeInfoAndroid, 0, sizeof(loaderInitializeInfoAndroid));
|
||||
loaderInitializeInfoAndroid.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR;
|
||||
loaderInitializeInfoAndroid.next = NULL;
|
||||
loaderInitializeInfoAndroid.applicationVM = java.Vm;
|
||||
loaderInitializeInfoAndroid.applicationContext = java.ActivityObject;
|
||||
xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loaderInitializeInfoAndroid);
|
||||
}
|
||||
PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
|
||||
xrGetInstanceProcAddr(
|
||||
XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&xrInitializeLoaderKHR);
|
||||
if (xrInitializeLoaderKHR != NULL) {
|
||||
XrLoaderInitInfoAndroidKHR loaderInitializeInfoAndroid;
|
||||
memset(&loaderInitializeInfoAndroid, 0, sizeof(loaderInitializeInfoAndroid));
|
||||
loaderInitializeInfoAndroid.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR;
|
||||
loaderInitializeInfoAndroid.next = NULL;
|
||||
loaderInitializeInfoAndroid.applicationVM = java.Vm;
|
||||
loaderInitializeInfoAndroid.applicationContext = java.ActivityObject;
|
||||
xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loaderInitializeInfoAndroid);
|
||||
}
|
||||
|
||||
// Create the OpenXR instance.
|
||||
XrApplicationInfo appInfo;
|
||||
memset(&appInfo, 0, sizeof(appInfo));
|
||||
strcpy(appInfo.applicationName, "PPSSPP");
|
||||
appInfo.applicationVersion = 0;
|
||||
strcpy(appInfo.engineName, "PPSSPP");
|
||||
appInfo.engineVersion = 0;
|
||||
appInfo.apiVersion = XR_CURRENT_API_VERSION;
|
||||
// Create the OpenXR instance.
|
||||
XrApplicationInfo appInfo;
|
||||
memset(&appInfo, 0, sizeof(appInfo));
|
||||
strcpy(appInfo.applicationName, "PPSSPP");
|
||||
appInfo.applicationVersion = 0;
|
||||
strcpy(appInfo.engineName, "PPSSPP");
|
||||
appInfo.engineVersion = 0;
|
||||
appInfo.apiVersion = XR_CURRENT_API_VERSION;
|
||||
|
||||
XrInstanceCreateInfo instanceCreateInfo;
|
||||
memset(&instanceCreateInfo, 0, sizeof(instanceCreateInfo));
|
||||
instanceCreateInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
|
||||
instanceCreateInfo.next = NULL;
|
||||
instanceCreateInfo.createFlags = 0;
|
||||
instanceCreateInfo.applicationInfo = appInfo;
|
||||
instanceCreateInfo.enabledApiLayerCount = 0;
|
||||
instanceCreateInfo.enabledApiLayerNames = NULL;
|
||||
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions;
|
||||
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames;
|
||||
XrInstanceCreateInfo instanceCreateInfo;
|
||||
memset(&instanceCreateInfo, 0, sizeof(instanceCreateInfo));
|
||||
instanceCreateInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
|
||||
instanceCreateInfo.next = NULL;
|
||||
instanceCreateInfo.createFlags = 0;
|
||||
instanceCreateInfo.applicationInfo = appInfo;
|
||||
instanceCreateInfo.enabledApiLayerCount = 0;
|
||||
instanceCreateInfo.enabledApiLayerNames = NULL;
|
||||
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions;
|
||||
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames;
|
||||
|
||||
XrResult initResult;
|
||||
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &vr_engine.appState.Instance));
|
||||
if (initResult != XR_SUCCESS) {
|
||||
ALOGE("Failed to create XR instance: %d.", initResult);
|
||||
exit(1);
|
||||
}
|
||||
XrResult initResult;
|
||||
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &vr_engine.appState.Instance));
|
||||
if (initResult != XR_SUCCESS) {
|
||||
ALOGE("Failed to create XR instance: %d.", initResult);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
XrInstanceProperties instanceInfo;
|
||||
instanceInfo.type = XR_TYPE_INSTANCE_PROPERTIES;
|
||||
instanceInfo.next = NULL;
|
||||
OXR(xrGetInstanceProperties(vr_engine.appState.Instance, &instanceInfo));
|
||||
ALOGV(
|
||||
"Runtime %s: Version : %u.%u.%u",
|
||||
instanceInfo.runtimeName,
|
||||
XR_VERSION_MAJOR(instanceInfo.runtimeVersion),
|
||||
XR_VERSION_MINOR(instanceInfo.runtimeVersion),
|
||||
XR_VERSION_PATCH(instanceInfo.runtimeVersion));
|
||||
XrInstanceProperties instanceInfo;
|
||||
instanceInfo.type = XR_TYPE_INSTANCE_PROPERTIES;
|
||||
instanceInfo.next = NULL;
|
||||
OXR(xrGetInstanceProperties(vr_engine.appState.Instance, &instanceInfo));
|
||||
ALOGV(
|
||||
"Runtime %s: Version : %u.%u.%u",
|
||||
instanceInfo.runtimeName,
|
||||
XR_VERSION_MAJOR(instanceInfo.runtimeVersion),
|
||||
XR_VERSION_MINOR(instanceInfo.runtimeVersion),
|
||||
XR_VERSION_PATCH(instanceInfo.runtimeVersion));
|
||||
|
||||
XrSystemGetInfo systemGetInfo;
|
||||
memset(&systemGetInfo, 0, sizeof(systemGetInfo));
|
||||
systemGetInfo.type = XR_TYPE_SYSTEM_GET_INFO;
|
||||
systemGetInfo.next = NULL;
|
||||
systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
|
||||
XrSystemGetInfo systemGetInfo;
|
||||
memset(&systemGetInfo, 0, sizeof(systemGetInfo));
|
||||
systemGetInfo.type = XR_TYPE_SYSTEM_GET_INFO;
|
||||
systemGetInfo.next = NULL;
|
||||
systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
|
||||
|
||||
XrSystemId systemId;
|
||||
OXR(initResult = xrGetSystem(vr_engine.appState.Instance, &systemGetInfo, &systemId));
|
||||
if (initResult != XR_SUCCESS) {
|
||||
ALOGE("Failed to get system.");
|
||||
exit(1);
|
||||
}
|
||||
XrSystemId systemId;
|
||||
OXR(initResult = xrGetSystem(vr_engine.appState.Instance, &systemGetInfo, &systemId));
|
||||
if (initResult != XR_SUCCESS) {
|
||||
ALOGE("Failed to get system.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Get the graphics requirements.
|
||||
PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = NULL;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
vr_engine.appState.Instance,
|
||||
"xrGetOpenGLESGraphicsRequirementsKHR",
|
||||
(PFN_xrVoidFunction*)(&pfnGetOpenGLESGraphicsRequirementsKHR)));
|
||||
// Get the graphics requirements.
|
||||
PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = NULL;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
vr_engine.appState.Instance,
|
||||
"xrGetOpenGLESGraphicsRequirementsKHR",
|
||||
(PFN_xrVoidFunction*)(&pfnGetOpenGLESGraphicsRequirementsKHR)));
|
||||
|
||||
XrGraphicsRequirementsOpenGLESKHR graphicsRequirements = {};
|
||||
graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
|
||||
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(vr_engine.appState.Instance, systemId, &graphicsRequirements));
|
||||
XrGraphicsRequirementsOpenGLESKHR graphicsRequirements = {};
|
||||
graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
|
||||
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(vr_engine.appState.Instance, systemId, &graphicsRequirements));
|
||||
|
||||
vr_engine.appState.MainThreadTid = gettid();
|
||||
vr_engine.appState.SystemId = systemId;
|
||||
vr_engine.appState.MainThreadTid = gettid();
|
||||
vr_engine.appState.SystemId = systemId;
|
||||
|
||||
vr_engine.java = java;
|
||||
vr_initialized = 1;
|
||||
vr_engine.java = java;
|
||||
vr_initialized = 1;
|
||||
}
|
||||
|
||||
void VR_Destroy( engine_t* engine ) {
|
||||
if (engine == &vr_engine) {
|
||||
xrDestroyInstance(engine->appState.Instance);
|
||||
ovrApp_Destroy(&engine->appState);
|
||||
}
|
||||
if (engine == &vr_engine) {
|
||||
xrDestroyInstance(engine->appState.Instance);
|
||||
ovrApp_Destroy(&engine->appState);
|
||||
}
|
||||
}
|
||||
|
||||
void VR_EnterVR( engine_t* engine ) {
|
||||
|
||||
if (engine->appState.Session) {
|
||||
ALOGE("VR_EnterVR called with existing session");
|
||||
return;
|
||||
}
|
||||
if (engine->appState.Session) {
|
||||
ALOGE("VR_EnterVR called with existing session");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the OpenXR Session.
|
||||
XrGraphicsBindingOpenGLESAndroidKHR graphicsBindingAndroidGLES = {};
|
||||
graphicsBindingAndroidGLES.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR;
|
||||
graphicsBindingAndroidGLES.next = NULL;
|
||||
graphicsBindingAndroidGLES.display = eglGetCurrentDisplay();
|
||||
graphicsBindingAndroidGLES.config = eglGetCurrentSurface(EGL_DRAW);
|
||||
graphicsBindingAndroidGLES.context = eglGetCurrentContext();
|
||||
// Create the OpenXR Session.
|
||||
XrGraphicsBindingOpenGLESAndroidKHR graphicsBindingAndroidGLES = {};
|
||||
graphicsBindingAndroidGLES.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR;
|
||||
graphicsBindingAndroidGLES.next = NULL;
|
||||
graphicsBindingAndroidGLES.display = eglGetCurrentDisplay();
|
||||
graphicsBindingAndroidGLES.config = eglGetCurrentSurface(EGL_DRAW);
|
||||
graphicsBindingAndroidGLES.context = eglGetCurrentContext();
|
||||
|
||||
XrSessionCreateInfo sessionCreateInfo = {};
|
||||
memset(&sessionCreateInfo, 0, sizeof(sessionCreateInfo));
|
||||
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
|
||||
sessionCreateInfo.next = &graphicsBindingAndroidGLES;
|
||||
sessionCreateInfo.createFlags = 0;
|
||||
sessionCreateInfo.systemId = engine->appState.SystemId;
|
||||
XrSessionCreateInfo sessionCreateInfo = {};
|
||||
memset(&sessionCreateInfo, 0, sizeof(sessionCreateInfo));
|
||||
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
|
||||
sessionCreateInfo.next = &graphicsBindingAndroidGLES;
|
||||
sessionCreateInfo.createFlags = 0;
|
||||
sessionCreateInfo.systemId = engine->appState.SystemId;
|
||||
|
||||
XrResult initResult;
|
||||
OXR(initResult = xrCreateSession(engine->appState.Instance, &sessionCreateInfo, &engine->appState.Session));
|
||||
if (initResult != XR_SUCCESS) {
|
||||
ALOGE("Failed to create XR session: %d.", initResult);
|
||||
exit(1);
|
||||
}
|
||||
XrResult initResult;
|
||||
OXR(initResult = xrCreateSession(engine->appState.Instance, &sessionCreateInfo, &engine->appState.Session));
|
||||
if (initResult != XR_SUCCESS) {
|
||||
ALOGE("Failed to create XR session: %d.", initResult);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create a space to the first path
|
||||
XrReferenceSpaceCreateInfo spaceCreateInfo = {};
|
||||
spaceCreateInfo.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
|
||||
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
|
||||
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.HeadSpace));
|
||||
// Create a space to the first path
|
||||
XrReferenceSpaceCreateInfo spaceCreateInfo = {};
|
||||
spaceCreateInfo.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
|
||||
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
|
||||
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.HeadSpace));
|
||||
}
|
||||
|
||||
void VR_LeaveVR( engine_t* engine ) {
|
||||
if (engine->appState.Session) {
|
||||
OXR(xrDestroySpace(engine->appState.HeadSpace));
|
||||
// StageSpace is optional.
|
||||
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
|
||||
OXR(xrDestroySpace(engine->appState.StageSpace));
|
||||
}
|
||||
OXR(xrDestroySpace(engine->appState.FakeStageSpace));
|
||||
engine->appState.CurrentSpace = XR_NULL_HANDLE;
|
||||
OXR(xrDestroySession(engine->appState.Session));
|
||||
engine->appState.Session = NULL;
|
||||
}
|
||||
if (engine->appState.Session) {
|
||||
OXR(xrDestroySpace(engine->appState.HeadSpace));
|
||||
// StageSpace is optional.
|
||||
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
|
||||
OXR(xrDestroySpace(engine->appState.StageSpace));
|
||||
}
|
||||
OXR(xrDestroySpace(engine->appState.FakeStageSpace));
|
||||
engine->appState.CurrentSpace = XR_NULL_HANDLE;
|
||||
OXR(xrDestroySession(engine->appState.Session));
|
||||
engine->appState.Session = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
engine_t* VR_GetEngine( void ) {
|
||||
|
@ -22,154 +22,154 @@ ovrFramebuffer
|
||||
|
||||
|
||||
void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
|
||||
frameBuffer->Width = 0;
|
||||
frameBuffer->Height = 0;
|
||||
frameBuffer->TextureSwapChainLength = 0;
|
||||
frameBuffer->TextureSwapChainIndex = 0;
|
||||
frameBuffer->ColorSwapChain.Handle = XR_NULL_HANDLE;
|
||||
frameBuffer->ColorSwapChain.Width = 0;
|
||||
frameBuffer->ColorSwapChain.Height = 0;
|
||||
frameBuffer->ColorSwapChainImage = NULL;
|
||||
frameBuffer->DepthBuffers = NULL;
|
||||
frameBuffer->FrameBuffers = NULL;
|
||||
frameBuffer->Width = 0;
|
||||
frameBuffer->Height = 0;
|
||||
frameBuffer->TextureSwapChainLength = 0;
|
||||
frameBuffer->TextureSwapChainIndex = 0;
|
||||
frameBuffer->ColorSwapChain.Handle = XR_NULL_HANDLE;
|
||||
frameBuffer->ColorSwapChain.Width = 0;
|
||||
frameBuffer->ColorSwapChain.Height = 0;
|
||||
frameBuffer->ColorSwapChainImage = NULL;
|
||||
frameBuffer->DepthBuffers = NULL;
|
||||
frameBuffer->FrameBuffers = NULL;
|
||||
}
|
||||
|
||||
bool ovrFramebuffer_Create(
|
||||
XrSession session,
|
||||
ovrFramebuffer* frameBuffer,
|
||||
const int width,
|
||||
const int height) {
|
||||
XrSession session,
|
||||
ovrFramebuffer* frameBuffer,
|
||||
const int width,
|
||||
const int height) {
|
||||
|
||||
frameBuffer->Width = width;
|
||||
frameBuffer->Height = height;
|
||||
frameBuffer->Width = width;
|
||||
frameBuffer->Height = height;
|
||||
|
||||
XrSwapchainCreateInfo swapChainCreateInfo;
|
||||
memset(&swapChainCreateInfo, 0, sizeof(swapChainCreateInfo));
|
||||
swapChainCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO;
|
||||
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapChainCreateInfo.format = GL_RGBA8;
|
||||
swapChainCreateInfo.sampleCount = 1;
|
||||
swapChainCreateInfo.width = width;
|
||||
swapChainCreateInfo.height = height;
|
||||
swapChainCreateInfo.faceCount = 1;
|
||||
swapChainCreateInfo.arraySize = 1;
|
||||
swapChainCreateInfo.mipCount = 1;
|
||||
XrSwapchainCreateInfo swapChainCreateInfo;
|
||||
memset(&swapChainCreateInfo, 0, sizeof(swapChainCreateInfo));
|
||||
swapChainCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO;
|
||||
swapChainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
swapChainCreateInfo.format = GL_RGBA8;
|
||||
swapChainCreateInfo.sampleCount = 1;
|
||||
swapChainCreateInfo.width = width;
|
||||
swapChainCreateInfo.height = height;
|
||||
swapChainCreateInfo.faceCount = 1;
|
||||
swapChainCreateInfo.arraySize = 1;
|
||||
swapChainCreateInfo.mipCount = 1;
|
||||
|
||||
frameBuffer->ColorSwapChain.Width = swapChainCreateInfo.width;
|
||||
frameBuffer->ColorSwapChain.Height = swapChainCreateInfo.height;
|
||||
frameBuffer->ColorSwapChain.Width = swapChainCreateInfo.width;
|
||||
frameBuffer->ColorSwapChain.Height = swapChainCreateInfo.height;
|
||||
|
||||
// Create the swapchain.
|
||||
OXR(xrCreateSwapchain(session, &swapChainCreateInfo, &frameBuffer->ColorSwapChain.Handle));
|
||||
// Get the number of swapchain images.
|
||||
OXR(xrEnumerateSwapchainImages(
|
||||
frameBuffer->ColorSwapChain.Handle, 0, &frameBuffer->TextureSwapChainLength, NULL));
|
||||
// Allocate the swapchain images array.
|
||||
frameBuffer->ColorSwapChainImage = (XrSwapchainImageOpenGLESKHR*)malloc(
|
||||
frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageOpenGLESKHR));
|
||||
// Create the swapchain.
|
||||
OXR(xrCreateSwapchain(session, &swapChainCreateInfo, &frameBuffer->ColorSwapChain.Handle));
|
||||
// Get the number of swapchain images.
|
||||
OXR(xrEnumerateSwapchainImages(
|
||||
frameBuffer->ColorSwapChain.Handle, 0, &frameBuffer->TextureSwapChainLength, NULL));
|
||||
// Allocate the swapchain images array.
|
||||
frameBuffer->ColorSwapChainImage = (XrSwapchainImageOpenGLESKHR*)malloc(
|
||||
frameBuffer->TextureSwapChainLength * sizeof(XrSwapchainImageOpenGLESKHR));
|
||||
|
||||
// Populate the swapchain image array.
|
||||
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
|
||||
frameBuffer->ColorSwapChainImage[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
|
||||
frameBuffer->ColorSwapChainImage[i].next = NULL;
|
||||
}
|
||||
OXR(xrEnumerateSwapchainImages(
|
||||
frameBuffer->ColorSwapChain.Handle,
|
||||
frameBuffer->TextureSwapChainLength,
|
||||
&frameBuffer->TextureSwapChainLength,
|
||||
(XrSwapchainImageBaseHeader*)frameBuffer->ColorSwapChainImage));
|
||||
// Populate the swapchain image array.
|
||||
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
|
||||
frameBuffer->ColorSwapChainImage[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
|
||||
frameBuffer->ColorSwapChainImage[i].next = NULL;
|
||||
}
|
||||
OXR(xrEnumerateSwapchainImages(
|
||||
frameBuffer->ColorSwapChain.Handle,
|
||||
frameBuffer->TextureSwapChainLength,
|
||||
&frameBuffer->TextureSwapChainLength,
|
||||
(XrSwapchainImageBaseHeader*)frameBuffer->ColorSwapChainImage));
|
||||
|
||||
frameBuffer->DepthBuffers =
|
||||
(GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
|
||||
frameBuffer->FrameBuffers =
|
||||
(GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
|
||||
frameBuffer->DepthBuffers =
|
||||
(GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
|
||||
frameBuffer->FrameBuffers =
|
||||
(GLuint*)malloc(frameBuffer->TextureSwapChainLength * sizeof(GLuint));
|
||||
|
||||
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
|
||||
// Create the color buffer texture.
|
||||
const GLuint colorTexture = frameBuffer->ColorSwapChainImage[i].image;
|
||||
GLenum colorTextureTarget = GL_TEXTURE_2D;
|
||||
GL(glBindTexture(colorTextureTarget, colorTexture));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GL(glBindTexture(colorTextureTarget, 0));
|
||||
for (uint32_t i = 0; i < frameBuffer->TextureSwapChainLength; i++) {
|
||||
// Create the color buffer texture.
|
||||
const GLuint colorTexture = frameBuffer->ColorSwapChainImage[i].image;
|
||||
GLenum colorTextureTarget = GL_TEXTURE_2D;
|
||||
GL(glBindTexture(colorTextureTarget, colorTexture));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL(glTexParameteri(colorTextureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GL(glBindTexture(colorTextureTarget, 0));
|
||||
|
||||
// Create depth buffer.
|
||||
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
|
||||
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
|
||||
GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height));
|
||||
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
|
||||
// Create depth buffer.
|
||||
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
|
||||
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
|
||||
GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height));
|
||||
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
|
||||
|
||||
// Create the frame buffer.
|
||||
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
|
||||
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
|
||||
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
|
||||
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0));
|
||||
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||
if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
|
||||
ALOGE(
|
||||
"Incomplete frame buffer object: %d", renderFramebufferStatus);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Create the frame buffer.
|
||||
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
|
||||
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
|
||||
GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
|
||||
GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0));
|
||||
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||
if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) {
|
||||
ALOGE(
|
||||
"Incomplete frame buffer object: %d", renderFramebufferStatus);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ovrFramebuffer_Destroy(ovrFramebuffer* frameBuffer) {
|
||||
GL(glDeleteFramebuffers(frameBuffer->TextureSwapChainLength, frameBuffer->FrameBuffers));
|
||||
GL(glDeleteRenderbuffers(frameBuffer->TextureSwapChainLength, frameBuffer->DepthBuffers));
|
||||
OXR(xrDestroySwapchain(frameBuffer->ColorSwapChain.Handle));
|
||||
free(frameBuffer->ColorSwapChainImage);
|
||||
GL(glDeleteFramebuffers(frameBuffer->TextureSwapChainLength, frameBuffer->FrameBuffers));
|
||||
GL(glDeleteRenderbuffers(frameBuffer->TextureSwapChainLength, frameBuffer->DepthBuffers));
|
||||
OXR(xrDestroySwapchain(frameBuffer->ColorSwapChain.Handle));
|
||||
free(frameBuffer->ColorSwapChainImage);
|
||||
|
||||
free(frameBuffer->DepthBuffers);
|
||||
free(frameBuffer->FrameBuffers);
|
||||
free(frameBuffer->DepthBuffers);
|
||||
free(frameBuffer->FrameBuffers);
|
||||
|
||||
ovrFramebuffer_Clear(frameBuffer);
|
||||
ovrFramebuffer_Clear(frameBuffer);
|
||||
}
|
||||
|
||||
void ovrFramebuffer_SetCurrent(ovrFramebuffer* frameBuffer) {
|
||||
GL(glBindFramebuffer(
|
||||
GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[frameBuffer->TextureSwapChainIndex]));
|
||||
GL(glBindFramebuffer(
|
||||
GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[frameBuffer->TextureSwapChainIndex]));
|
||||
}
|
||||
|
||||
void ovrFramebuffer_SetNone() {
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||
}
|
||||
|
||||
void ovrFramebuffer_Resolve(ovrFramebuffer* frameBuffer) {
|
||||
// Discard the depth buffer, so the tiler won't need to write it back out to memory.
|
||||
const GLenum depthAttachment[1] = {GL_DEPTH_ATTACHMENT};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, depthAttachment);
|
||||
// Discard the depth buffer, so the tiler won't need to write it back out to memory.
|
||||
const GLenum depthAttachment[1] = {GL_DEPTH_ATTACHMENT};
|
||||
glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, depthAttachment);
|
||||
}
|
||||
|
||||
void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) {
|
||||
// Acquire the swapchain image
|
||||
XrSwapchainImageAcquireInfo acquireInfo = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, NULL};
|
||||
OXR(xrAcquireSwapchainImage(
|
||||
frameBuffer->ColorSwapChain.Handle, &acquireInfo, &frameBuffer->TextureSwapChainIndex));
|
||||
// Acquire the swapchain image
|
||||
XrSwapchainImageAcquireInfo acquireInfo = {XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO, NULL};
|
||||
OXR(xrAcquireSwapchainImage(
|
||||
frameBuffer->ColorSwapChain.Handle, &acquireInfo, &frameBuffer->TextureSwapChainIndex));
|
||||
|
||||
XrSwapchainImageWaitInfo waitInfo;
|
||||
waitInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO;
|
||||
waitInfo.next = NULL;
|
||||
waitInfo.timeout = 1000; /* timeout in nanoseconds */
|
||||
XrResult res = xrWaitSwapchainImage(frameBuffer->ColorSwapChain.Handle, &waitInfo);
|
||||
int i = 0;
|
||||
while (res != XR_SUCCESS) {
|
||||
res = xrWaitSwapchainImage(frameBuffer->ColorSwapChain.Handle, &waitInfo);
|
||||
i++;
|
||||
ALOGV(
|
||||
" Retry xrWaitSwapchainImage %d times due to XR_TIMEOUT_EXPIRED (duration %f micro seconds)",
|
||||
i,
|
||||
waitInfo.timeout * (1E-9));
|
||||
}
|
||||
XrSwapchainImageWaitInfo waitInfo;
|
||||
waitInfo.type = XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO;
|
||||
waitInfo.next = NULL;
|
||||
waitInfo.timeout = 1000; /* timeout in nanoseconds */
|
||||
XrResult res = xrWaitSwapchainImage(frameBuffer->ColorSwapChain.Handle, &waitInfo);
|
||||
int i = 0;
|
||||
while (res != XR_SUCCESS) {
|
||||
res = xrWaitSwapchainImage(frameBuffer->ColorSwapChain.Handle, &waitInfo);
|
||||
i++;
|
||||
ALOGV(
|
||||
" Retry xrWaitSwapchainImage %d times due to XR_TIMEOUT_EXPIRED (duration %f micro seconds)",
|
||||
i,
|
||||
waitInfo.timeout * (1E-9));
|
||||
}
|
||||
}
|
||||
|
||||
void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
|
||||
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
|
||||
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
|
||||
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
|
||||
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -181,30 +181,30 @@ ovrRenderer
|
||||
*/
|
||||
|
||||
void ovrRenderer_Clear(ovrRenderer* renderer) {
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer_Clear(&renderer->FrameBuffer[eye]);
|
||||
}
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer_Clear(&renderer->FrameBuffer[eye]);
|
||||
}
|
||||
}
|
||||
|
||||
void ovrRenderer_Create(
|
||||
XrSession session,
|
||||
ovrRenderer* renderer,
|
||||
int suggestedEyeTextureWidth,
|
||||
int suggestedEyeTextureHeight) {
|
||||
// Create the frame buffers.
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer_Create(
|
||||
session,
|
||||
&renderer->FrameBuffer[eye],
|
||||
suggestedEyeTextureWidth,
|
||||
suggestedEyeTextureHeight);
|
||||
}
|
||||
XrSession session,
|
||||
ovrRenderer* renderer,
|
||||
int suggestedEyeTextureWidth,
|
||||
int suggestedEyeTextureHeight) {
|
||||
// Create the frame buffers.
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer_Create(
|
||||
session,
|
||||
&renderer->FrameBuffer[eye],
|
||||
suggestedEyeTextureWidth,
|
||||
suggestedEyeTextureHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void ovrRenderer_Destroy(ovrRenderer* renderer) {
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer_Destroy(&renderer->FrameBuffer[eye]);
|
||||
}
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer_Destroy(&renderer->FrameBuffer[eye]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -216,132 +216,132 @@ ovrApp
|
||||
*/
|
||||
|
||||
void ovrApp_Clear(ovrApp* app) {
|
||||
app->Focused = false;
|
||||
app->Instance = XR_NULL_HANDLE;
|
||||
app->Session = XR_NULL_HANDLE;
|
||||
memset(&app->ViewportConfig, 0, sizeof(XrViewConfigurationProperties));
|
||||
memset(&app->ViewConfigurationView, 0, ovrMaxNumEyes * sizeof(XrViewConfigurationView));
|
||||
app->SystemId = XR_NULL_SYSTEM_ID;
|
||||
app->HeadSpace = XR_NULL_HANDLE;
|
||||
app->StageSpace = XR_NULL_HANDLE;
|
||||
app->FakeStageSpace = XR_NULL_HANDLE;
|
||||
app->CurrentSpace = XR_NULL_HANDLE;
|
||||
app->SessionActive = false;
|
||||
app->SwapInterval = 1;
|
||||
memset(app->Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||
app->LayerCount = 0;
|
||||
app->MainThreadTid = 0;
|
||||
app->RenderThreadTid = 0;
|
||||
app->TouchPadDownLastFrame = false;
|
||||
app->Focused = false;
|
||||
app->Instance = XR_NULL_HANDLE;
|
||||
app->Session = XR_NULL_HANDLE;
|
||||
memset(&app->ViewportConfig, 0, sizeof(XrViewConfigurationProperties));
|
||||
memset(&app->ViewConfigurationView, 0, ovrMaxNumEyes * sizeof(XrViewConfigurationView));
|
||||
app->SystemId = XR_NULL_SYSTEM_ID;
|
||||
app->HeadSpace = XR_NULL_HANDLE;
|
||||
app->StageSpace = XR_NULL_HANDLE;
|
||||
app->FakeStageSpace = XR_NULL_HANDLE;
|
||||
app->CurrentSpace = XR_NULL_HANDLE;
|
||||
app->SessionActive = false;
|
||||
app->SwapInterval = 1;
|
||||
memset(app->Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||
app->LayerCount = 0;
|
||||
app->MainThreadTid = 0;
|
||||
app->RenderThreadTid = 0;
|
||||
app->TouchPadDownLastFrame = false;
|
||||
|
||||
ovrRenderer_Clear(&app->Renderer);
|
||||
ovrRenderer_Clear(&app->Renderer);
|
||||
}
|
||||
|
||||
void ovrApp_Destroy(ovrApp* app) {
|
||||
ovrApp_Clear(app);
|
||||
ovrApp_Clear(app);
|
||||
}
|
||||
|
||||
void ovrApp_HandleSessionStateChanges(ovrApp* app, XrSessionState state) {
|
||||
if (state == XR_SESSION_STATE_READY) {
|
||||
assert(app->SessionActive == false);
|
||||
if (state == XR_SESSION_STATE_READY) {
|
||||
assert(app->SessionActive == false);
|
||||
|
||||
XrSessionBeginInfo sessionBeginInfo;
|
||||
memset(&sessionBeginInfo, 0, sizeof(sessionBeginInfo));
|
||||
sessionBeginInfo.type = XR_TYPE_SESSION_BEGIN_INFO;
|
||||
sessionBeginInfo.next = NULL;
|
||||
sessionBeginInfo.primaryViewConfigurationType = app->ViewportConfig.viewConfigurationType;
|
||||
XrSessionBeginInfo sessionBeginInfo;
|
||||
memset(&sessionBeginInfo, 0, sizeof(sessionBeginInfo));
|
||||
sessionBeginInfo.type = XR_TYPE_SESSION_BEGIN_INFO;
|
||||
sessionBeginInfo.next = NULL;
|
||||
sessionBeginInfo.primaryViewConfigurationType = app->ViewportConfig.viewConfigurationType;
|
||||
|
||||
XrResult result;
|
||||
OXR(result = xrBeginSession(app->Session, &sessionBeginInfo));
|
||||
XrResult result;
|
||||
OXR(result = xrBeginSession(app->Session, &sessionBeginInfo));
|
||||
|
||||
app->SessionActive = (result == XR_SUCCESS);
|
||||
} else if (state == XR_SESSION_STATE_STOPPING) {
|
||||
assert(app->SessionActive);
|
||||
app->SessionActive = (result == XR_SUCCESS);
|
||||
} else if (state == XR_SESSION_STATE_STOPPING) {
|
||||
assert(app->SessionActive);
|
||||
|
||||
OXR(xrEndSession(app->Session));
|
||||
app->SessionActive = false;
|
||||
}
|
||||
OXR(xrEndSession(app->Session));
|
||||
app->SessionActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
int ovrApp_HandleXrEvents(ovrApp* app) {
|
||||
XrEventDataBuffer eventDataBuffer = {};
|
||||
int recenter = 0;
|
||||
XrEventDataBuffer eventDataBuffer = {};
|
||||
int recenter = 0;
|
||||
|
||||
// Poll for events
|
||||
for (;;) {
|
||||
XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
|
||||
baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
|
||||
baseEventHeader->next = NULL;
|
||||
XrResult r;
|
||||
OXR(r = xrPollEvent(app->Instance, &eventDataBuffer));
|
||||
if (r != XR_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
// Poll for events
|
||||
for (;;) {
|
||||
XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
|
||||
baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
|
||||
baseEventHeader->next = NULL;
|
||||
XrResult r;
|
||||
OXR(r = xrPollEvent(app->Instance, &eventDataBuffer));
|
||||
if (r != XR_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (baseEventHeader->type) {
|
||||
case XR_TYPE_EVENT_DATA_EVENTS_LOST:
|
||||
ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_EVENTS_LOST event");
|
||||
break;
|
||||
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
|
||||
const XrEventDataInstanceLossPending* instance_loss_pending_event =
|
||||
(XrEventDataInstanceLossPending*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING event: time %f",
|
||||
FromXrTime(instance_loss_pending_event->lossTime));
|
||||
} break;
|
||||
case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
|
||||
ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED event");
|
||||
break;
|
||||
case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: {
|
||||
const XrEventDataPerfSettingsEXT* perf_settings_event =
|
||||
(XrEventDataPerfSettingsEXT*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT event: type %d subdomain %d : level %d -> level %d",
|
||||
perf_settings_event->type,
|
||||
perf_settings_event->subDomain,
|
||||
perf_settings_event->fromLevel,
|
||||
perf_settings_event->toLevel);
|
||||
} break;
|
||||
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: {
|
||||
XrEventDataReferenceSpaceChangePending* ref_space_change_event =
|
||||
(XrEventDataReferenceSpaceChangePending*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING event: changed space: %d for session %p at time %f",
|
||||
ref_space_change_event->referenceSpaceType,
|
||||
(void*)ref_space_change_event->session,
|
||||
FromXrTime(ref_space_change_event->changeTime));
|
||||
recenter = 1;
|
||||
} break;
|
||||
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
|
||||
const XrEventDataSessionStateChanged* session_state_changed_event =
|
||||
(XrEventDataSessionStateChanged*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: %d for session %p at time %f",
|
||||
session_state_changed_event->state,
|
||||
(void*)session_state_changed_event->session,
|
||||
FromXrTime(session_state_changed_event->time));
|
||||
switch (baseEventHeader->type) {
|
||||
case XR_TYPE_EVENT_DATA_EVENTS_LOST:
|
||||
ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_EVENTS_LOST event");
|
||||
break;
|
||||
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
|
||||
const XrEventDataInstanceLossPending* instance_loss_pending_event =
|
||||
(XrEventDataInstanceLossPending*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING event: time %f",
|
||||
FromXrTime(instance_loss_pending_event->lossTime));
|
||||
} break;
|
||||
case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
|
||||
ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED event");
|
||||
break;
|
||||
case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: {
|
||||
const XrEventDataPerfSettingsEXT* perf_settings_event =
|
||||
(XrEventDataPerfSettingsEXT*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT event: type %d subdomain %d : level %d -> level %d",
|
||||
perf_settings_event->type,
|
||||
perf_settings_event->subDomain,
|
||||
perf_settings_event->fromLevel,
|
||||
perf_settings_event->toLevel);
|
||||
} break;
|
||||
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: {
|
||||
XrEventDataReferenceSpaceChangePending* ref_space_change_event =
|
||||
(XrEventDataReferenceSpaceChangePending*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING event: changed space: %d for session %p at time %f",
|
||||
ref_space_change_event->referenceSpaceType,
|
||||
(void*)ref_space_change_event->session,
|
||||
FromXrTime(ref_space_change_event->changeTime));
|
||||
recenter = 1;
|
||||
} break;
|
||||
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
|
||||
const XrEventDataSessionStateChanged* session_state_changed_event =
|
||||
(XrEventDataSessionStateChanged*)(baseEventHeader);
|
||||
ALOGV(
|
||||
"xrPollEvent: received XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: %d for session %p at time %f",
|
||||
session_state_changed_event->state,
|
||||
(void*)session_state_changed_event->session,
|
||||
FromXrTime(session_state_changed_event->time));
|
||||
|
||||
switch (session_state_changed_event->state) {
|
||||
case XR_SESSION_STATE_FOCUSED:
|
||||
app->Focused = true;
|
||||
break;
|
||||
case XR_SESSION_STATE_VISIBLE:
|
||||
app->Focused = false;
|
||||
break;
|
||||
case XR_SESSION_STATE_READY:
|
||||
case XR_SESSION_STATE_STOPPING:
|
||||
ovrApp_HandleSessionStateChanges(app, session_state_changed_event->state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
ALOGV("xrPollEvent: Unknown event");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return recenter;
|
||||
switch (session_state_changed_event->state) {
|
||||
case XR_SESSION_STATE_FOCUSED:
|
||||
app->Focused = true;
|
||||
break;
|
||||
case XR_SESSION_STATE_VISIBLE:
|
||||
app->Focused = false;
|
||||
break;
|
||||
case XR_SESSION_STATE_READY:
|
||||
case XR_SESSION_STATE_STOPPING:
|
||||
ovrApp_HandleSessionStateChanges(app, session_state_changed_event->state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
ALOGV("xrPollEvent: Unknown event");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return recenter;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -353,172 +353,172 @@ ovrMatrix4f
|
||||
*/
|
||||
|
||||
ovrMatrix4f ovrMatrix4f_CreateProjectionFov(
|
||||
const float angleLeft,
|
||||
const float angleRight,
|
||||
const float angleUp,
|
||||
const float angleDown,
|
||||
const float nearZ,
|
||||
const float farZ) {
|
||||
const float angleLeft,
|
||||
const float angleRight,
|
||||
const float angleUp,
|
||||
const float angleDown,
|
||||
const float nearZ,
|
||||
const float farZ) {
|
||||
|
||||
const float tanAngleLeft = tanf(angleLeft);
|
||||
const float tanAngleRight = tanf(angleRight);
|
||||
const float tanAngleLeft = tanf(angleLeft);
|
||||
const float tanAngleRight = tanf(angleRight);
|
||||
|
||||
const float tanAngleDown = tanf(angleDown);
|
||||
const float tanAngleUp = tanf(angleUp);
|
||||
const float tanAngleDown = tanf(angleDown);
|
||||
const float tanAngleUp = tanf(angleUp);
|
||||
|
||||
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
|
||||
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
|
||||
|
||||
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y
|
||||
// down (Vulkan). Set to tanAngleUp - tanAngleDown for a clip space with
|
||||
// positive Y up (OpenGL / D3D / Metal).
|
||||
const float tanAngleHeight = tanAngleUp - tanAngleDown;
|
||||
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y
|
||||
// down (Vulkan). Set to tanAngleUp - tanAngleDown for a clip space with
|
||||
// positive Y up (OpenGL / D3D / Metal).
|
||||
const float tanAngleHeight = tanAngleUp - tanAngleDown;
|
||||
|
||||
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
|
||||
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
|
||||
const float offsetZ = nearZ;
|
||||
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
|
||||
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
|
||||
const float offsetZ = nearZ;
|
||||
|
||||
ovrMatrix4f result;
|
||||
if (farZ <= nearZ) {
|
||||
// place the far plane at infinity
|
||||
result.M[0][0] = 2 / tanAngleWidth;
|
||||
result.M[0][1] = 0;
|
||||
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result.M[0][3] = 0;
|
||||
ovrMatrix4f result;
|
||||
if (farZ <= nearZ) {
|
||||
// place the far plane at infinity
|
||||
result.M[0][0] = 2 / tanAngleWidth;
|
||||
result.M[0][1] = 0;
|
||||
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result.M[0][3] = 0;
|
||||
|
||||
result.M[1][0] = 0;
|
||||
result.M[1][1] = 2 / tanAngleHeight;
|
||||
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result.M[1][3] = 0;
|
||||
result.M[1][0] = 0;
|
||||
result.M[1][1] = 2 / tanAngleHeight;
|
||||
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result.M[1][3] = 0;
|
||||
|
||||
result.M[2][0] = 0;
|
||||
result.M[2][1] = 0;
|
||||
result.M[2][2] = -1;
|
||||
result.M[2][3] = -(nearZ + offsetZ);
|
||||
result.M[2][0] = 0;
|
||||
result.M[2][1] = 0;
|
||||
result.M[2][2] = -1;
|
||||
result.M[2][3] = -(nearZ + offsetZ);
|
||||
|
||||
result.M[3][0] = 0;
|
||||
result.M[3][1] = 0;
|
||||
result.M[3][2] = -1;
|
||||
result.M[3][3] = 0;
|
||||
} else {
|
||||
// normal projection
|
||||
result.M[0][0] = 2 / tanAngleWidth;
|
||||
result.M[0][1] = 0;
|
||||
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result.M[0][3] = 0;
|
||||
result.M[3][0] = 0;
|
||||
result.M[3][1] = 0;
|
||||
result.M[3][2] = -1;
|
||||
result.M[3][3] = 0;
|
||||
} else {
|
||||
// normal projection
|
||||
result.M[0][0] = 2 / tanAngleWidth;
|
||||
result.M[0][1] = 0;
|
||||
result.M[0][2] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result.M[0][3] = 0;
|
||||
|
||||
result.M[1][0] = 0;
|
||||
result.M[1][1] = 2 / tanAngleHeight;
|
||||
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result.M[1][3] = 0;
|
||||
result.M[1][0] = 0;
|
||||
result.M[1][1] = 2 / tanAngleHeight;
|
||||
result.M[1][2] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result.M[1][3] = 0;
|
||||
|
||||
result.M[2][0] = 0;
|
||||
result.M[2][1] = 0;
|
||||
result.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ);
|
||||
result.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
||||
result.M[2][0] = 0;
|
||||
result.M[2][1] = 0;
|
||||
result.M[2][2] = -(farZ + offsetZ) / (farZ - nearZ);
|
||||
result.M[2][3] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
||||
|
||||
result.M[3][0] = 0;
|
||||
result.M[3][1] = 0;
|
||||
result.M[3][2] = -1;
|
||||
result.M[3][3] = 0;
|
||||
}
|
||||
return result;
|
||||
result.M[3][0] = 0;
|
||||
result.M[3][1] = 0;
|
||||
result.M[3][2] = -1;
|
||||
result.M[3][3] = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q) {
|
||||
const float ww = q->w * q->w;
|
||||
const float xx = q->x * q->x;
|
||||
const float yy = q->y * q->y;
|
||||
const float zz = q->z * q->z;
|
||||
const float ww = q->w * q->w;
|
||||
const float xx = q->x * q->x;
|
||||
const float yy = q->y * q->y;
|
||||
const float zz = q->z * q->z;
|
||||
|
||||
ovrMatrix4f out;
|
||||
out.M[0][0] = ww + xx - yy - zz;
|
||||
out.M[0][1] = 2 * (q->x * q->y - q->w * q->z);
|
||||
out.M[0][2] = 2 * (q->x * q->z + q->w * q->y);
|
||||
out.M[0][3] = 0;
|
||||
ovrMatrix4f out;
|
||||
out.M[0][0] = ww + xx - yy - zz;
|
||||
out.M[0][1] = 2 * (q->x * q->y - q->w * q->z);
|
||||
out.M[0][2] = 2 * (q->x * q->z + q->w * q->y);
|
||||
out.M[0][3] = 0;
|
||||
|
||||
out.M[1][0] = 2 * (q->x * q->y + q->w * q->z);
|
||||
out.M[1][1] = ww - xx + yy - zz;
|
||||
out.M[1][2] = 2 * (q->y * q->z - q->w * q->x);
|
||||
out.M[1][3] = 0;
|
||||
out.M[1][0] = 2 * (q->x * q->y + q->w * q->z);
|
||||
out.M[1][1] = ww - xx + yy - zz;
|
||||
out.M[1][2] = 2 * (q->y * q->z - q->w * q->x);
|
||||
out.M[1][3] = 0;
|
||||
|
||||
out.M[2][0] = 2 * (q->x * q->z - q->w * q->y);
|
||||
out.M[2][1] = 2 * (q->y * q->z + q->w * q->x);
|
||||
out.M[2][2] = ww - xx - yy + zz;
|
||||
out.M[2][3] = 0;
|
||||
out.M[2][0] = 2 * (q->x * q->z - q->w * q->y);
|
||||
out.M[2][1] = 2 * (q->y * q->z + q->w * q->x);
|
||||
out.M[2][2] = ww - xx - yy + zz;
|
||||
out.M[2][3] = 0;
|
||||
|
||||
out.M[3][0] = 0;
|
||||
out.M[3][1] = 0;
|
||||
out.M[3][2] = 0;
|
||||
out.M[3][3] = 1;
|
||||
return out;
|
||||
out.M[3][0] = 0;
|
||||
out.M[3][1] = 0;
|
||||
out.M[3][2] = 0;
|
||||
out.M[3][3] = 1;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/// Use left-multiplication to accumulate transformations.
|
||||
ovrMatrix4f ovrMatrix4f_Multiply(const ovrMatrix4f* a, const ovrMatrix4f* b) {
|
||||
ovrMatrix4f out;
|
||||
out.M[0][0] = a->M[0][0] * b->M[0][0] + a->M[0][1] * b->M[1][0] + a->M[0][2] * b->M[2][0] +
|
||||
a->M[0][3] * b->M[3][0];
|
||||
out.M[1][0] = a->M[1][0] * b->M[0][0] + a->M[1][1] * b->M[1][0] + a->M[1][2] * b->M[2][0] +
|
||||
a->M[1][3] * b->M[3][0];
|
||||
out.M[2][0] = a->M[2][0] * b->M[0][0] + a->M[2][1] * b->M[1][0] + a->M[2][2] * b->M[2][0] +
|
||||
a->M[2][3] * b->M[3][0];
|
||||
out.M[3][0] = a->M[3][0] * b->M[0][0] + a->M[3][1] * b->M[1][0] + a->M[3][2] * b->M[2][0] +
|
||||
a->M[3][3] * b->M[3][0];
|
||||
ovrMatrix4f out;
|
||||
out.M[0][0] = a->M[0][0] * b->M[0][0] + a->M[0][1] * b->M[1][0] + a->M[0][2] * b->M[2][0] +
|
||||
a->M[0][3] * b->M[3][0];
|
||||
out.M[1][0] = a->M[1][0] * b->M[0][0] + a->M[1][1] * b->M[1][0] + a->M[1][2] * b->M[2][0] +
|
||||
a->M[1][3] * b->M[3][0];
|
||||
out.M[2][0] = a->M[2][0] * b->M[0][0] + a->M[2][1] * b->M[1][0] + a->M[2][2] * b->M[2][0] +
|
||||
a->M[2][3] * b->M[3][0];
|
||||
out.M[3][0] = a->M[3][0] * b->M[0][0] + a->M[3][1] * b->M[1][0] + a->M[3][2] * b->M[2][0] +
|
||||
a->M[3][3] * b->M[3][0];
|
||||
|
||||
out.M[0][1] = a->M[0][0] * b->M[0][1] + a->M[0][1] * b->M[1][1] + a->M[0][2] * b->M[2][1] +
|
||||
a->M[0][3] * b->M[3][1];
|
||||
out.M[1][1] = a->M[1][0] * b->M[0][1] + a->M[1][1] * b->M[1][1] + a->M[1][2] * b->M[2][1] +
|
||||
a->M[1][3] * b->M[3][1];
|
||||
out.M[2][1] = a->M[2][0] * b->M[0][1] + a->M[2][1] * b->M[1][1] + a->M[2][2] * b->M[2][1] +
|
||||
a->M[2][3] * b->M[3][1];
|
||||
out.M[3][1] = a->M[3][0] * b->M[0][1] + a->M[3][1] * b->M[1][1] + a->M[3][2] * b->M[2][1] +
|
||||
a->M[3][3] * b->M[3][1];
|
||||
out.M[0][1] = a->M[0][0] * b->M[0][1] + a->M[0][1] * b->M[1][1] + a->M[0][2] * b->M[2][1] +
|
||||
a->M[0][3] * b->M[3][1];
|
||||
out.M[1][1] = a->M[1][0] * b->M[0][1] + a->M[1][1] * b->M[1][1] + a->M[1][2] * b->M[2][1] +
|
||||
a->M[1][3] * b->M[3][1];
|
||||
out.M[2][1] = a->M[2][0] * b->M[0][1] + a->M[2][1] * b->M[1][1] + a->M[2][2] * b->M[2][1] +
|
||||
a->M[2][3] * b->M[3][1];
|
||||
out.M[3][1] = a->M[3][0] * b->M[0][1] + a->M[3][1] * b->M[1][1] + a->M[3][2] * b->M[2][1] +
|
||||
a->M[3][3] * b->M[3][1];
|
||||
|
||||
out.M[0][2] = a->M[0][0] * b->M[0][2] + a->M[0][1] * b->M[1][2] + a->M[0][2] * b->M[2][2] +
|
||||
a->M[0][3] * b->M[3][2];
|
||||
out.M[1][2] = a->M[1][0] * b->M[0][2] + a->M[1][1] * b->M[1][2] + a->M[1][2] * b->M[2][2] +
|
||||
a->M[1][3] * b->M[3][2];
|
||||
out.M[2][2] = a->M[2][0] * b->M[0][2] + a->M[2][1] * b->M[1][2] + a->M[2][2] * b->M[2][2] +
|
||||
a->M[2][3] * b->M[3][2];
|
||||
out.M[3][2] = a->M[3][0] * b->M[0][2] + a->M[3][1] * b->M[1][2] + a->M[3][2] * b->M[2][2] +
|
||||
a->M[3][3] * b->M[3][2];
|
||||
out.M[0][2] = a->M[0][0] * b->M[0][2] + a->M[0][1] * b->M[1][2] + a->M[0][2] * b->M[2][2] +
|
||||
a->M[0][3] * b->M[3][2];
|
||||
out.M[1][2] = a->M[1][0] * b->M[0][2] + a->M[1][1] * b->M[1][2] + a->M[1][2] * b->M[2][2] +
|
||||
a->M[1][3] * b->M[3][2];
|
||||
out.M[2][2] = a->M[2][0] * b->M[0][2] + a->M[2][1] * b->M[1][2] + a->M[2][2] * b->M[2][2] +
|
||||
a->M[2][3] * b->M[3][2];
|
||||
out.M[3][2] = a->M[3][0] * b->M[0][2] + a->M[3][1] * b->M[1][2] + a->M[3][2] * b->M[2][2] +
|
||||
a->M[3][3] * b->M[3][2];
|
||||
|
||||
out.M[0][3] = a->M[0][0] * b->M[0][3] + a->M[0][1] * b->M[1][3] + a->M[0][2] * b->M[2][3] +
|
||||
a->M[0][3] * b->M[3][3];
|
||||
out.M[1][3] = a->M[1][0] * b->M[0][3] + a->M[1][1] * b->M[1][3] + a->M[1][2] * b->M[2][3] +
|
||||
a->M[1][3] * b->M[3][3];
|
||||
out.M[2][3] = a->M[2][0] * b->M[0][3] + a->M[2][1] * b->M[1][3] + a->M[2][2] * b->M[2][3] +
|
||||
a->M[2][3] * b->M[3][3];
|
||||
out.M[3][3] = a->M[3][0] * b->M[0][3] + a->M[3][1] * b->M[1][3] + a->M[3][2] * b->M[2][3] +
|
||||
a->M[3][3] * b->M[3][3];
|
||||
return out;
|
||||
out.M[0][3] = a->M[0][0] * b->M[0][3] + a->M[0][1] * b->M[1][3] + a->M[0][2] * b->M[2][3] +
|
||||
a->M[0][3] * b->M[3][3];
|
||||
out.M[1][3] = a->M[1][0] * b->M[0][3] + a->M[1][1] * b->M[1][3] + a->M[1][2] * b->M[2][3] +
|
||||
a->M[1][3] * b->M[3][3];
|
||||
out.M[2][3] = a->M[2][0] * b->M[0][3] + a->M[2][1] * b->M[1][3] + a->M[2][2] * b->M[2][3] +
|
||||
a->M[2][3] * b->M[3][3];
|
||||
out.M[3][3] = a->M[3][0] * b->M[0][3] + a->M[3][1] * b->M[1][3] + a->M[3][2] * b->M[2][3] +
|
||||
a->M[3][3] * b->M[3][3];
|
||||
return out;
|
||||
}
|
||||
|
||||
ovrMatrix4f ovrMatrix4f_CreateRotation(const float radiansX, const float radiansY, const float radiansZ) {
|
||||
const float sinX = sinf(radiansX);
|
||||
const float cosX = cosf(radiansX);
|
||||
const ovrMatrix4f rotationX = {
|
||||
{{1, 0, 0, 0}, {0, cosX, -sinX, 0}, {0, sinX, cosX, 0}, {0, 0, 0, 1}}};
|
||||
const float sinY = sinf(radiansY);
|
||||
const float cosY = cosf(radiansY);
|
||||
const ovrMatrix4f rotationY = {
|
||||
{{cosY, 0, sinY, 0}, {0, 1, 0, 0}, {-sinY, 0, cosY, 0}, {0, 0, 0, 1}}};
|
||||
const float sinZ = sinf(radiansZ);
|
||||
const float cosZ = cosf(radiansZ);
|
||||
const ovrMatrix4f rotationZ = {
|
||||
{{cosZ, -sinZ, 0, 0}, {sinZ, cosZ, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};
|
||||
const ovrMatrix4f rotationXY = ovrMatrix4f_Multiply(&rotationY, &rotationX);
|
||||
return ovrMatrix4f_Multiply(&rotationZ, &rotationXY);
|
||||
const float sinX = sinf(radiansX);
|
||||
const float cosX = cosf(radiansX);
|
||||
const ovrMatrix4f rotationX = {
|
||||
{{1, 0, 0, 0}, {0, cosX, -sinX, 0}, {0, sinX, cosX, 0}, {0, 0, 0, 1}}};
|
||||
const float sinY = sinf(radiansY);
|
||||
const float cosY = cosf(radiansY);
|
||||
const ovrMatrix4f rotationY = {
|
||||
{{cosY, 0, sinY, 0}, {0, 1, 0, 0}, {-sinY, 0, cosY, 0}, {0, 0, 0, 1}}};
|
||||
const float sinZ = sinf(radiansZ);
|
||||
const float cosZ = cosf(radiansZ);
|
||||
const ovrMatrix4f rotationZ = {
|
||||
{{cosZ, -sinZ, 0, 0}, {sinZ, cosZ, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}};
|
||||
const ovrMatrix4f rotationXY = ovrMatrix4f_Multiply(&rotationY, &rotationX);
|
||||
return ovrMatrix4f_Multiply(&rotationZ, &rotationXY);
|
||||
}
|
||||
|
||||
XrVector4f XrVector4f_MultiplyMatrix4f(const ovrMatrix4f* a, const XrVector4f* v) {
|
||||
XrVector4f out;
|
||||
out.x = a->M[0][0] * v->x + a->M[0][1] * v->y + a->M[0][2] * v->z + a->M[0][3] * v->w;
|
||||
out.y = a->M[1][0] * v->x + a->M[1][1] * v->y + a->M[1][2] * v->z + a->M[1][3] * v->w;
|
||||
out.z = a->M[2][0] * v->x + a->M[2][1] * v->y + a->M[2][2] * v->z + a->M[2][3] * v->w;
|
||||
out.w = a->M[3][0] * v->x + a->M[3][1] * v->y + a->M[3][2] * v->z + a->M[3][3] * v->w;
|
||||
return out;
|
||||
XrVector4f out;
|
||||
out.x = a->M[0][0] * v->x + a->M[0][1] * v->y + a->M[0][2] * v->z + a->M[0][3] * v->w;
|
||||
out.y = a->M[1][0] * v->x + a->M[1][1] * v->y + a->M[1][2] * v->z + a->M[1][3] * v->w;
|
||||
out.z = a->M[2][0] * v->x + a->M[2][1] * v->y + a->M[2][2] * v->z + a->M[2][3] * v->w;
|
||||
out.w = a->M[3][0] * v->x + a->M[3][1] * v->y + a->M[3][2] * v->z + a->M[3][3] * v->w;
|
||||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -530,6 +530,6 @@ ovrTrackedController
|
||||
*/
|
||||
|
||||
void ovrTrackedController_Clear(ovrTrackedController* controller) {
|
||||
controller->Active = false;
|
||||
controller->Pose = XrPosef_Identity();
|
||||
controller->Active = false;
|
||||
controller->Pose = XrPosef_Identity();
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
#define ALOGV(...) printf(__VA_ARGS__)
|
||||
|
||||
typedef union {
|
||||
XrCompositionLayerProjection Projection;
|
||||
XrCompositionLayerCylinderKHR Cylinder;
|
||||
XrCompositionLayerProjection Projection;
|
||||
XrCompositionLayerCylinderKHR Cylinder;
|
||||
} ovrCompositorLayer_Union;
|
||||
|
||||
enum { ovrMaxLayerCount = 1 };
|
||||
@ -33,60 +33,60 @@ typedef struct {
|
||||
} ovrJava;
|
||||
|
||||
typedef struct {
|
||||
XrSwapchain Handle;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
XrSwapchain Handle;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
} ovrSwapChain;
|
||||
|
||||
typedef struct {
|
||||
int Width;
|
||||
int Height;
|
||||
uint32_t TextureSwapChainLength;
|
||||
uint32_t TextureSwapChainIndex;
|
||||
ovrSwapChain ColorSwapChain;
|
||||
XrSwapchainImageOpenGLESKHR* ColorSwapChainImage;
|
||||
unsigned int* DepthBuffers;
|
||||
unsigned int* FrameBuffers;
|
||||
int Width;
|
||||
int Height;
|
||||
uint32_t TextureSwapChainLength;
|
||||
uint32_t TextureSwapChainIndex;
|
||||
ovrSwapChain ColorSwapChain;
|
||||
XrSwapchainImageOpenGLESKHR* ColorSwapChainImage;
|
||||
unsigned int* DepthBuffers;
|
||||
unsigned int* FrameBuffers;
|
||||
} ovrFramebuffer;
|
||||
|
||||
typedef struct {
|
||||
ovrFramebuffer FrameBuffer[ovrMaxNumEyes];
|
||||
ovrFramebuffer FrameBuffer[ovrMaxNumEyes];
|
||||
} ovrRenderer;
|
||||
|
||||
typedef struct {
|
||||
int Active;
|
||||
XrPosef Pose;
|
||||
int Active;
|
||||
XrPosef Pose;
|
||||
} ovrTrackedController;
|
||||
|
||||
typedef struct {
|
||||
int Focused;
|
||||
int Focused;
|
||||
|
||||
XrInstance Instance;
|
||||
XrSession Session;
|
||||
XrViewConfigurationProperties ViewportConfig;
|
||||
XrViewConfigurationView ViewConfigurationView[ovrMaxNumEyes];
|
||||
XrSystemId SystemId;
|
||||
XrSpace HeadSpace;
|
||||
XrSpace StageSpace;
|
||||
XrSpace FakeStageSpace;
|
||||
XrSpace CurrentSpace;
|
||||
int SessionActive;
|
||||
XrInstance Instance;
|
||||
XrSession Session;
|
||||
XrViewConfigurationProperties ViewportConfig;
|
||||
XrViewConfigurationView ViewConfigurationView[ovrMaxNumEyes];
|
||||
XrSystemId SystemId;
|
||||
XrSpace HeadSpace;
|
||||
XrSpace StageSpace;
|
||||
XrSpace FakeStageSpace;
|
||||
XrSpace CurrentSpace;
|
||||
int SessionActive;
|
||||
|
||||
int SwapInterval;
|
||||
// These threads will be marked as performance threads.
|
||||
int MainThreadTid;
|
||||
int RenderThreadTid;
|
||||
ovrCompositorLayer_Union Layers[ovrMaxLayerCount];
|
||||
int LayerCount;
|
||||
int SwapInterval;
|
||||
// These threads will be marked as performance threads.
|
||||
int MainThreadTid;
|
||||
int RenderThreadTid;
|
||||
ovrCompositorLayer_Union Layers[ovrMaxLayerCount];
|
||||
int LayerCount;
|
||||
|
||||
int TouchPadDownLastFrame;
|
||||
ovrRenderer Renderer;
|
||||
ovrTrackedController TrackedController[2];
|
||||
int TouchPadDownLastFrame;
|
||||
ovrRenderer Renderer;
|
||||
ovrTrackedController TrackedController[2];
|
||||
} ovrApp;
|
||||
|
||||
|
||||
typedef struct {
|
||||
float M[4][4];
|
||||
float M[4][4];
|
||||
} ovrMatrix4f;
|
||||
|
||||
typedef struct {
|
||||
|
818
VR/VRInput.cpp
818
VR/VRInput.cpp
@ -41,7 +41,7 @@ float vibration_channel_duration[2] = {0.0f, 0.0f};
|
||||
float vibration_channel_intensity[2] = {0.0f, 0.0f};
|
||||
|
||||
float radians(float deg) {
|
||||
return (deg * M_PI) / 180.0;
|
||||
return (deg * M_PI) / 180.0;
|
||||
}
|
||||
|
||||
unsigned long sys_timeBase = 0;
|
||||
@ -63,511 +63,511 @@ int milliseconds(void) {
|
||||
#endif
|
||||
|
||||
XrVector3f normalizeVec(XrVector3f vec) {
|
||||
float xxyyzz = vec.x*vec.x + vec.y*vec.y + vec.z*vec.z;
|
||||
float xxyyzz = vec.x*vec.x + vec.y*vec.y + vec.z*vec.z;
|
||||
|
||||
XrVector3f result;
|
||||
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||
result.x = vec.x * invLength;
|
||||
result.y = vec.y * invLength;
|
||||
result.z = vec.z * invLength;
|
||||
return result;
|
||||
XrVector3f result;
|
||||
float invLength = 1.0f / sqrtf(xxyyzz);
|
||||
result.x = vec.x * invLength;
|
||||
result.y = vec.y * invLength;
|
||||
result.z = vec.z * invLength;
|
||||
return result;
|
||||
}
|
||||
|
||||
void GetAnglesFromVectors(const XrVector3f forward, const XrVector3f right, const XrVector3f up, vec3_t angles) {
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
sp = -forward.z;
|
||||
sp = -forward.z;
|
||||
|
||||
float cp_x_cy = forward.x;
|
||||
float cp_x_sy = forward.y;
|
||||
float cp_x_sr = -right.z;
|
||||
float cp_x_cr = up.z;
|
||||
float cp_x_cy = forward.x;
|
||||
float cp_x_sy = forward.y;
|
||||
float cp_x_sr = -right.z;
|
||||
float cp_x_cr = up.z;
|
||||
|
||||
float yaw = atan2(cp_x_sy, cp_x_cy);
|
||||
float roll = atan2(cp_x_sr, cp_x_cr);
|
||||
float yaw = atan2(cp_x_sy, cp_x_cy);
|
||||
float roll = atan2(cp_x_sr, cp_x_cr);
|
||||
|
||||
cy = cos(yaw);
|
||||
sy = sin(yaw);
|
||||
cr = cos(roll);
|
||||
sr = sin(roll);
|
||||
cy = cos(yaw);
|
||||
sy = sin(yaw);
|
||||
cr = cos(roll);
|
||||
sr = sin(roll);
|
||||
|
||||
if (fabs(cy) > EPSILON) {
|
||||
cp = cp_x_cy / cy;
|
||||
} else if (fabs(sy) > EPSILON) {
|
||||
cp = cp_x_sy / sy;
|
||||
} else if (fabs(sr) > EPSILON) {
|
||||
cp = cp_x_sr / sr;
|
||||
} else if (fabs(cr) > EPSILON) {
|
||||
cp = cp_x_cr / cr;
|
||||
} else {
|
||||
cp = cos(asin(sp));
|
||||
}
|
||||
if (fabs(cy) > EPSILON) {
|
||||
cp = cp_x_cy / cy;
|
||||
} else if (fabs(sy) > EPSILON) {
|
||||
cp = cp_x_sy / sy;
|
||||
} else if (fabs(sr) > EPSILON) {
|
||||
cp = cp_x_sr / sr;
|
||||
} else if (fabs(cr) > EPSILON) {
|
||||
cp = cp_x_cr / cr;
|
||||
} else {
|
||||
cp = cos(asin(sp));
|
||||
}
|
||||
|
||||
float pitch = atan2(sp, cp);
|
||||
float pitch = atan2(sp, cp);
|
||||
|
||||
angles[0] = pitch / (M_PI*2.f / 360.f);
|
||||
angles[1] = yaw / (M_PI*2.f / 360.f);
|
||||
angles[2] = roll / (M_PI*2.f / 360.f);
|
||||
angles[0] = pitch / (M_PI*2.f / 360.f);
|
||||
angles[1] = yaw / (M_PI*2.f / 360.f);
|
||||
angles[2] = roll / (M_PI*2.f / 360.f);
|
||||
}
|
||||
|
||||
void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out) {
|
||||
|
||||
ovrMatrix4f mat = ovrMatrix4f_CreateFromQuaternion( &q );
|
||||
ovrMatrix4f mat = ovrMatrix4f_CreateFromQuaternion( &q );
|
||||
|
||||
if (rotation[0] != 0.0f || rotation[1] != 0.0f || rotation[2] != 0.0f) {
|
||||
ovrMatrix4f rot = ovrMatrix4f_CreateRotation(radians(rotation[0]), radians(rotation[1]), radians(rotation[2]));
|
||||
mat = ovrMatrix4f_Multiply(&mat, &rot);
|
||||
}
|
||||
if (rotation[0] != 0.0f || rotation[1] != 0.0f || rotation[2] != 0.0f) {
|
||||
ovrMatrix4f rot = ovrMatrix4f_CreateRotation(radians(rotation[0]), radians(rotation[1]), radians(rotation[2]));
|
||||
mat = ovrMatrix4f_Multiply(&mat, &rot);
|
||||
}
|
||||
|
||||
XrVector4f v1 = {0, 0, -1, 0};
|
||||
XrVector4f v2 = {1, 0, 0, 0};
|
||||
XrVector4f v3 = {0, 1, 0, 0};
|
||||
XrVector4f v1 = {0, 0, -1, 0};
|
||||
XrVector4f v2 = {1, 0, 0, 0};
|
||||
XrVector4f v3 = {0, 1, 0, 0};
|
||||
|
||||
XrVector4f forwardInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v1);
|
||||
XrVector4f rightInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v2);
|
||||
XrVector4f upInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v3);
|
||||
XrVector4f forwardInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v1);
|
||||
XrVector4f rightInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v2);
|
||||
XrVector4f upInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v3);
|
||||
|
||||
XrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y};
|
||||
XrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y};
|
||||
XrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y};
|
||||
XrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y};
|
||||
XrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y};
|
||||
XrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y};
|
||||
|
||||
XrVector3f forwardNormal = normalizeVec(forward);
|
||||
XrVector3f rightNormal = normalizeVec(right);
|
||||
XrVector3f upNormal = normalizeVec(up);
|
||||
XrVector3f forwardNormal = normalizeVec(forward);
|
||||
XrVector3f rightNormal = normalizeVec(right);
|
||||
XrVector3f upNormal = normalizeVec(up);
|
||||
|
||||
GetAnglesFromVectors(forwardNormal, rightNormal, upNormal, out);
|
||||
GetAnglesFromVectors(forwardNormal, rightNormal, upNormal, out);
|
||||
}
|
||||
|
||||
void VR_Vibrate( int duration, int chan, float intensity ) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int channel = (i + 1) & chan;
|
||||
if (channel) {
|
||||
if (vibration_channel_duration[channel-1] > 0.0f)
|
||||
return;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int channel = (i + 1) & chan;
|
||||
if (channel) {
|
||||
if (vibration_channel_duration[channel-1] > 0.0f)
|
||||
return;
|
||||
|
||||
if (vibration_channel_duration[channel-1] == -1.0f && duration != 0.0f)
|
||||
return;
|
||||
if (vibration_channel_duration[channel-1] == -1.0f && duration != 0.0f)
|
||||
return;
|
||||
|
||||
vibration_channel_duration[channel-1] = duration;
|
||||
vibration_channel_intensity[channel-1] = intensity;
|
||||
}
|
||||
}
|
||||
vibration_channel_duration[channel-1] = duration;
|
||||
vibration_channel_intensity[channel-1] = intensity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VR_processHaptics() {
|
||||
float lastFrameTime = 0.0f;
|
||||
float timestamp = (float)(milliseconds( ));
|
||||
float frametime = timestamp - lastFrameTime;
|
||||
lastFrameTime = timestamp;
|
||||
float lastFrameTime = 0.0f;
|
||||
float timestamp = (float)(milliseconds( ));
|
||||
float frametime = timestamp - lastFrameTime;
|
||||
lastFrameTime = timestamp;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (vibration_channel_duration[i] > 0.0f ||
|
||||
vibration_channel_duration[i] == -1.0f) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (vibration_channel_duration[i] > 0.0f ||
|
||||
vibration_channel_duration[i] == -1.0f) {
|
||||
|
||||
// fire haptics using output action
|
||||
XrHapticVibration vibration = {};
|
||||
vibration.type = XR_TYPE_HAPTIC_VIBRATION;
|
||||
vibration.next = NULL;
|
||||
vibration.amplitude = vibration_channel_intensity[i];
|
||||
vibration.duration = ToXrTime(vibration_channel_duration[i]);
|
||||
vibration.frequency = 3000;
|
||||
XrHapticActionInfo hapticActionInfo = {};
|
||||
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
|
||||
hapticActionInfo.next = NULL;
|
||||
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
|
||||
OXR(xrApplyHapticFeedback(VR_GetEngine()->appState.Session, &hapticActionInfo, (const XrHapticBaseHeader*)&vibration));
|
||||
// fire haptics using output action
|
||||
XrHapticVibration vibration = {};
|
||||
vibration.type = XR_TYPE_HAPTIC_VIBRATION;
|
||||
vibration.next = NULL;
|
||||
vibration.amplitude = vibration_channel_intensity[i];
|
||||
vibration.duration = ToXrTime(vibration_channel_duration[i]);
|
||||
vibration.frequency = 3000;
|
||||
XrHapticActionInfo hapticActionInfo = {};
|
||||
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
|
||||
hapticActionInfo.next = NULL;
|
||||
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
|
||||
OXR(xrApplyHapticFeedback(VR_GetEngine()->appState.Session, &hapticActionInfo, (const XrHapticBaseHeader*)&vibration));
|
||||
|
||||
if (vibration_channel_duration[i] != -1.0f) {
|
||||
vibration_channel_duration[i] -= frametime;
|
||||
if (vibration_channel_duration[i] != -1.0f) {
|
||||
vibration_channel_duration[i] -= frametime;
|
||||
|
||||
if (vibration_channel_duration[i] < 0.0f) {
|
||||
vibration_channel_duration[i] = 0.0f;
|
||||
vibration_channel_intensity[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Stop haptics
|
||||
XrHapticActionInfo hapticActionInfo = {};
|
||||
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
|
||||
hapticActionInfo.next = NULL;
|
||||
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
|
||||
OXR(xrStopHapticFeedback(VR_GetEngine()->appState.Session, &hapticActionInfo));
|
||||
}
|
||||
}
|
||||
if (vibration_channel_duration[i] < 0.0f) {
|
||||
vibration_channel_duration[i] = 0.0f;
|
||||
vibration_channel_intensity[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Stop haptics
|
||||
XrHapticActionInfo hapticActionInfo = {};
|
||||
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
|
||||
hapticActionInfo.next = NULL;
|
||||
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
|
||||
OXR(xrStopHapticFeedback(VR_GetEngine()->appState.Session, &hapticActionInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XrSpace CreateActionSpace(XrAction poseAction, XrPath subactionPath) {
|
||||
XrActionSpaceCreateInfo asci = {};
|
||||
asci.type = XR_TYPE_ACTION_SPACE_CREATE_INFO;
|
||||
asci.action = poseAction;
|
||||
asci.poseInActionSpace.orientation.w = 1.0f;
|
||||
asci.subactionPath = subactionPath;
|
||||
XrSpace actionSpace = XR_NULL_HANDLE;
|
||||
OXR(xrCreateActionSpace(VR_GetEngine()->appState.Session, &asci, &actionSpace));
|
||||
return actionSpace;
|
||||
XrActionSpaceCreateInfo asci = {};
|
||||
asci.type = XR_TYPE_ACTION_SPACE_CREATE_INFO;
|
||||
asci.action = poseAction;
|
||||
asci.poseInActionSpace.orientation.w = 1.0f;
|
||||
asci.subactionPath = subactionPath;
|
||||
XrSpace actionSpace = XR_NULL_HANDLE;
|
||||
OXR(xrCreateActionSpace(VR_GetEngine()->appState.Session, &asci, &actionSpace));
|
||||
return actionSpace;
|
||||
}
|
||||
|
||||
XrActionSuggestedBinding ActionSuggestedBinding(XrAction action, const char* bindingString) {
|
||||
XrActionSuggestedBinding asb;
|
||||
asb.action = action;
|
||||
XrPath bindingPath;
|
||||
OXR(xrStringToPath(VR_GetEngine()->appState.Instance, bindingString, &bindingPath));
|
||||
asb.binding = bindingPath;
|
||||
return asb;
|
||||
XrActionSuggestedBinding asb;
|
||||
asb.action = action;
|
||||
XrPath bindingPath;
|
||||
OXR(xrStringToPath(VR_GetEngine()->appState.Instance, bindingString, &bindingPath));
|
||||
asb.binding = bindingPath;
|
||||
return asb;
|
||||
}
|
||||
|
||||
XrActionSet CreateActionSet(int priority, const char* name, const char* localizedName) {
|
||||
XrActionSetCreateInfo asci = {};
|
||||
asci.type = XR_TYPE_ACTION_SET_CREATE_INFO;
|
||||
asci.next = NULL;
|
||||
asci.priority = priority;
|
||||
strcpy(asci.actionSetName, name);
|
||||
strcpy(asci.localizedActionSetName, localizedName);
|
||||
XrActionSet actionSet = XR_NULL_HANDLE;
|
||||
OXR(xrCreateActionSet(VR_GetEngine()->appState.Instance, &asci, &actionSet));
|
||||
return actionSet;
|
||||
XrActionSetCreateInfo asci = {};
|
||||
asci.type = XR_TYPE_ACTION_SET_CREATE_INFO;
|
||||
asci.next = NULL;
|
||||
asci.priority = priority;
|
||||
strcpy(asci.actionSetName, name);
|
||||
strcpy(asci.localizedActionSetName, localizedName);
|
||||
XrActionSet actionSet = XR_NULL_HANDLE;
|
||||
OXR(xrCreateActionSet(VR_GetEngine()->appState.Instance, &asci, &actionSet));
|
||||
return actionSet;
|
||||
}
|
||||
|
||||
XrAction CreateAction(
|
||||
XrActionSet actionSet,
|
||||
XrActionType type,
|
||||
const char* actionName,
|
||||
const char* localizedName,
|
||||
int countSubactionPaths,
|
||||
XrPath* subactionPaths) {
|
||||
XrActionSet actionSet,
|
||||
XrActionType type,
|
||||
const char* actionName,
|
||||
const char* localizedName,
|
||||
int countSubactionPaths,
|
||||
XrPath* subactionPaths) {
|
||||
|
||||
XrActionCreateInfo aci = {};
|
||||
aci.type = XR_TYPE_ACTION_CREATE_INFO;
|
||||
aci.next = NULL;
|
||||
aci.actionType = type;
|
||||
if (countSubactionPaths > 0) {
|
||||
aci.countSubactionPaths = countSubactionPaths;
|
||||
aci.subactionPaths = subactionPaths;
|
||||
}
|
||||
strcpy(aci.actionName, actionName);
|
||||
strcpy(aci.localizedActionName, localizedName ? localizedName : actionName);
|
||||
XrAction action = XR_NULL_HANDLE;
|
||||
OXR(xrCreateAction(actionSet, &aci, &action));
|
||||
return action;
|
||||
XrActionCreateInfo aci = {};
|
||||
aci.type = XR_TYPE_ACTION_CREATE_INFO;
|
||||
aci.next = NULL;
|
||||
aci.actionType = type;
|
||||
if (countSubactionPaths > 0) {
|
||||
aci.countSubactionPaths = countSubactionPaths;
|
||||
aci.subactionPaths = subactionPaths;
|
||||
}
|
||||
strcpy(aci.actionName, actionName);
|
||||
strcpy(aci.localizedActionName, localizedName ? localizedName : actionName);
|
||||
XrAction action = XR_NULL_HANDLE;
|
||||
OXR(xrCreateAction(actionSet, &aci, &action));
|
||||
return action;
|
||||
}
|
||||
|
||||
int ActionPoseIsActive(XrAction action, XrPath subactionPath) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
getInfo.subactionPath = subactionPath;
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStatePose state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_POSE;
|
||||
OXR(xrGetActionStatePose(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state.isActive != XR_FALSE;
|
||||
XrActionStatePose state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_POSE;
|
||||
OXR(xrGetActionStatePose(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state.isActive != XR_FALSE;
|
||||
}
|
||||
|
||||
XrActionStateFloat GetActionStateFloat(XrAction action) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
|
||||
XrActionStateFloat state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_FLOAT;
|
||||
XrActionStateFloat state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_FLOAT;
|
||||
|
||||
OXR(xrGetActionStateFloat(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state;
|
||||
OXR(xrGetActionStateFloat(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state;
|
||||
}
|
||||
|
||||
XrActionStateBoolean GetActionStateBoolean(XrAction action) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
|
||||
XrActionStateBoolean state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_BOOLEAN;
|
||||
XrActionStateBoolean state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_BOOLEAN;
|
||||
|
||||
OXR(xrGetActionStateBoolean(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state;
|
||||
OXR(xrGetActionStateBoolean(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state;
|
||||
}
|
||||
|
||||
XrActionStateVector2f GetActionStateVector2(XrAction action) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
|
||||
XrActionStateVector2f state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_VECTOR2F;
|
||||
XrActionStateVector2f state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_VECTOR2F;
|
||||
|
||||
OXR(xrGetActionStateVector2f(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state;
|
||||
OXR(xrGetActionStateVector2f(VR_GetEngine()->appState.Session, &getInfo, &state));
|
||||
return state;
|
||||
}
|
||||
|
||||
void IN_VRInit( engine_t *engine ) {
|
||||
if (inputInitialized)
|
||||
return;
|
||||
if (inputInitialized)
|
||||
return;
|
||||
|
||||
// Actions
|
||||
runningActionSet = CreateActionSet(1, "running_action_set", "Action Set used on main loop");
|
||||
indexLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_left", "Index left", 0, NULL);
|
||||
indexRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_right", "Index right", 0, NULL);
|
||||
menuAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "menu_action", "Menu", 0, NULL);
|
||||
buttonAAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_a", "Button A", 0, NULL);
|
||||
buttonBAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_b", "Button B", 0, NULL);
|
||||
buttonXAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_x", "Button X", 0, NULL);
|
||||
buttonYAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_y", "Button Y", 0, NULL);
|
||||
gripLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_left", "Grip left", 0, NULL);
|
||||
gripRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_right", "Grip right", 0, NULL);
|
||||
moveOnLeftJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_left_joy", "Move on left Joy", 0, NULL);
|
||||
moveOnRightJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_right_joy", "Move on right Joy", 0, NULL);
|
||||
thumbstickLeftClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_left", "Thumbstick left", 0, NULL);
|
||||
thumbstickRightClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_right", "Thumbstick right", 0, NULL);
|
||||
vibrateLeftFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_left_feedback", "Vibrate Left Controller Feedback", 0, NULL);
|
||||
vibrateRightFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_right_feedback", "Vibrate Right Controller Feedback", 0, NULL);
|
||||
// Actions
|
||||
runningActionSet = CreateActionSet(1, "running_action_set", "Action Set used on main loop");
|
||||
indexLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_left", "Index left", 0, NULL);
|
||||
indexRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_right", "Index right", 0, NULL);
|
||||
menuAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "menu_action", "Menu", 0, NULL);
|
||||
buttonAAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_a", "Button A", 0, NULL);
|
||||
buttonBAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_b", "Button B", 0, NULL);
|
||||
buttonXAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_x", "Button X", 0, NULL);
|
||||
buttonYAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_y", "Button Y", 0, NULL);
|
||||
gripLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_left", "Grip left", 0, NULL);
|
||||
gripRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_right", "Grip right", 0, NULL);
|
||||
moveOnLeftJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_left_joy", "Move on left Joy", 0, NULL);
|
||||
moveOnRightJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_right_joy", "Move on right Joy", 0, NULL);
|
||||
thumbstickLeftClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_left", "Thumbstick left", 0, NULL);
|
||||
thumbstickRightClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_right", "Thumbstick right", 0, NULL);
|
||||
vibrateLeftFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_left_feedback", "Vibrate Left Controller Feedback", 0, NULL);
|
||||
vibrateRightFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_right_feedback", "Vibrate Right Controller Feedback", 0, NULL);
|
||||
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/user/hand/left", &leftHandPath));
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/user/hand/right", &rightHandPath));
|
||||
handPoseLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_left", NULL, 1, &leftHandPath);
|
||||
handPoseRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_right", NULL, 1, &rightHandPath);
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/user/hand/left", &leftHandPath));
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/user/hand/right", &rightHandPath));
|
||||
handPoseLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_left", NULL, 1, &leftHandPath);
|
||||
handPoseRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_right", NULL, 1, &rightHandPath);
|
||||
|
||||
XrPath interactionProfilePath = XR_NULL_PATH;
|
||||
XrPath interactionProfilePathTouch = XR_NULL_PATH;
|
||||
XrPath interactionProfilePathKHRSimple = XR_NULL_PATH;
|
||||
XrPath interactionProfilePath = XR_NULL_PATH;
|
||||
XrPath interactionProfilePathTouch = XR_NULL_PATH;
|
||||
XrPath interactionProfilePathKHRSimple = XR_NULL_PATH;
|
||||
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/interaction_profiles/oculus/touch_controller", &interactionProfilePathTouch));
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/interaction_profiles/khr/simple_controller", &interactionProfilePathKHRSimple));
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/interaction_profiles/oculus/touch_controller", &interactionProfilePathTouch));
|
||||
OXR(xrStringToPath(engine->appState.Instance, "/interaction_profiles/khr/simple_controller", &interactionProfilePathKHRSimple));
|
||||
|
||||
// Toggle this to force simple as a first choice, otherwise use it as a last resort
|
||||
if (useSimpleProfile) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
|
||||
interactionProfilePath = interactionProfilePathKHRSimple;
|
||||
} else {
|
||||
// Query Set
|
||||
XrActionSet queryActionSet = CreateActionSet(1, "query_action_set", "Action Set used to query device caps");
|
||||
XrAction dummyAction = CreateAction(queryActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "dummy_action", "Dummy Action", 0, NULL);
|
||||
// Toggle this to force simple as a first choice, otherwise use it as a last resort
|
||||
if (useSimpleProfile) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
|
||||
interactionProfilePath = interactionProfilePathKHRSimple;
|
||||
} else {
|
||||
// Query Set
|
||||
XrActionSet queryActionSet = CreateActionSet(1, "query_action_set", "Action Set used to query device caps");
|
||||
XrAction dummyAction = CreateAction(queryActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "dummy_action", "Dummy Action", 0, NULL);
|
||||
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[1];
|
||||
int currBinding = 0;
|
||||
bindings[currBinding++] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/system/click");
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[1];
|
||||
int currBinding = 0;
|
||||
bindings[currBinding++] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/system/click");
|
||||
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {};
|
||||
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||
suggestedBindings.next = NULL;
|
||||
suggestedBindings.suggestedBindings = bindings;
|
||||
suggestedBindings.countSuggestedBindings = currBinding;
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {};
|
||||
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||
suggestedBindings.next = NULL;
|
||||
suggestedBindings.suggestedBindings = bindings;
|
||||
suggestedBindings.countSuggestedBindings = currBinding;
|
||||
|
||||
// Try all
|
||||
suggestedBindings.interactionProfile = interactionProfilePathTouch;
|
||||
XrResult suggestTouchResult = xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings);
|
||||
OXR(suggestTouchResult);
|
||||
// Try all
|
||||
suggestedBindings.interactionProfile = interactionProfilePathTouch;
|
||||
XrResult suggestTouchResult = xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings);
|
||||
OXR(suggestTouchResult);
|
||||
|
||||
if (XR_SUCCESS == suggestTouchResult) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for QUEST controller");
|
||||
interactionProfilePath = interactionProfilePathTouch;
|
||||
}
|
||||
if (XR_SUCCESS == suggestTouchResult) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for QUEST controller");
|
||||
interactionProfilePath = interactionProfilePathTouch;
|
||||
}
|
||||
|
||||
if (interactionProfilePath == XR_NULL_PATH) {
|
||||
// Simple as a fallback
|
||||
bindings[0] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/select/click");
|
||||
suggestedBindings.interactionProfile = interactionProfilePathKHRSimple;
|
||||
XrResult suggestKHRSimpleResult = xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings);
|
||||
OXR(suggestKHRSimpleResult);
|
||||
if (XR_SUCCESS == suggestKHRSimpleResult) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
|
||||
interactionProfilePath = interactionProfilePathKHRSimple;
|
||||
} else {
|
||||
ALOGE("xrSuggestInteractionProfileBindings did NOT find any bindings.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (interactionProfilePath == XR_NULL_PATH) {
|
||||
// Simple as a fallback
|
||||
bindings[0] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/select/click");
|
||||
suggestedBindings.interactionProfile = interactionProfilePathKHRSimple;
|
||||
XrResult suggestKHRSimpleResult = xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings);
|
||||
OXR(suggestKHRSimpleResult);
|
||||
if (XR_SUCCESS == suggestKHRSimpleResult) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
|
||||
interactionProfilePath = interactionProfilePathKHRSimple;
|
||||
} else {
|
||||
ALOGE("xrSuggestInteractionProfileBindings did NOT find any bindings.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action creation
|
||||
{
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[32]; // large enough for all profiles
|
||||
int currBinding = 0;
|
||||
// Action creation
|
||||
{
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[32]; // large enough for all profiles
|
||||
int currBinding = 0;
|
||||
|
||||
{
|
||||
if (interactionProfilePath == interactionProfilePathTouch) {
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/trigger");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/trigger");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(menuAction, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/left/input/x/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonYAction, "/user/hand/left/input/y/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/right/input/a/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonBAction, "/user/hand/right/input/b/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(gripLeftAction, "/user/hand/left/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(gripRightAction, "/user/hand/right/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnLeftJoystickAction, "/user/hand/left/input/thumbstick");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnRightJoystickAction, "/user/hand/right/input/thumbstick");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickLeftClickAction, "/user/hand/left/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickRightClickAction, "/user/hand/right/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
|
||||
}
|
||||
{
|
||||
if (interactionProfilePath == interactionProfilePathTouch) {
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/trigger");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/trigger");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(menuAction, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/left/input/x/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonYAction, "/user/hand/left/input/y/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/right/input/a/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonBAction, "/user/hand/right/input/b/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(gripLeftAction, "/user/hand/left/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(gripRightAction, "/user/hand/right/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnLeftJoystickAction, "/user/hand/left/input/thumbstick");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnRightJoystickAction, "/user/hand/right/input/thumbstick");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickLeftClickAction, "/user/hand/left/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickRightClickAction, "/user/hand/right/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
|
||||
}
|
||||
|
||||
if (interactionProfilePath == interactionProfilePathKHRSimple) {
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/select/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/select/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/right/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
|
||||
}
|
||||
}
|
||||
if (interactionProfilePath == interactionProfilePathKHRSimple) {
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/select/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/select/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/right/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
|
||||
}
|
||||
}
|
||||
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {};
|
||||
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||
suggestedBindings.next = NULL;
|
||||
suggestedBindings.interactionProfile = interactionProfilePath;
|
||||
suggestedBindings.suggestedBindings = bindings;
|
||||
suggestedBindings.countSuggestedBindings = currBinding;
|
||||
OXR(xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings));
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {};
|
||||
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||
suggestedBindings.next = NULL;
|
||||
suggestedBindings.interactionProfile = interactionProfilePath;
|
||||
suggestedBindings.suggestedBindings = bindings;
|
||||
suggestedBindings.countSuggestedBindings = currBinding;
|
||||
OXR(xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings));
|
||||
|
||||
// Enumerate actions
|
||||
XrPath actionPathsBuffer[32];
|
||||
char stringBuffer[256];
|
||||
XrAction actionsToEnumerate[] = {
|
||||
indexLeftAction,
|
||||
indexRightAction,
|
||||
menuAction,
|
||||
buttonAAction,
|
||||
buttonBAction,
|
||||
buttonXAction,
|
||||
buttonYAction,
|
||||
gripLeftAction,
|
||||
gripRightAction,
|
||||
moveOnLeftJoystickAction,
|
||||
moveOnRightJoystickAction,
|
||||
thumbstickLeftClickAction,
|
||||
thumbstickRightClickAction,
|
||||
vibrateLeftFeedback,
|
||||
vibrateRightFeedback,
|
||||
handPoseLeftAction,
|
||||
handPoseRightAction
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(actionsToEnumerate) / sizeof(actionsToEnumerate[0]); ++i) {
|
||||
XrBoundSourcesForActionEnumerateInfo enumerateInfo = {};
|
||||
enumerateInfo.type = XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO;
|
||||
enumerateInfo.next = NULL;
|
||||
enumerateInfo.action = actionsToEnumerate[i];
|
||||
// Enumerate actions
|
||||
XrPath actionPathsBuffer[32];
|
||||
char stringBuffer[256];
|
||||
XrAction actionsToEnumerate[] = {
|
||||
indexLeftAction,
|
||||
indexRightAction,
|
||||
menuAction,
|
||||
buttonAAction,
|
||||
buttonBAction,
|
||||
buttonXAction,
|
||||
buttonYAction,
|
||||
gripLeftAction,
|
||||
gripRightAction,
|
||||
moveOnLeftJoystickAction,
|
||||
moveOnRightJoystickAction,
|
||||
thumbstickLeftClickAction,
|
||||
thumbstickRightClickAction,
|
||||
vibrateLeftFeedback,
|
||||
vibrateRightFeedback,
|
||||
handPoseLeftAction,
|
||||
handPoseRightAction
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(actionsToEnumerate) / sizeof(actionsToEnumerate[0]); ++i) {
|
||||
XrBoundSourcesForActionEnumerateInfo enumerateInfo = {};
|
||||
enumerateInfo.type = XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO;
|
||||
enumerateInfo.next = NULL;
|
||||
enumerateInfo.action = actionsToEnumerate[i];
|
||||
|
||||
// Get Count
|
||||
uint32_t countOutput = 0;
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
engine->appState.Session, &enumerateInfo, 0 /* request size */, &countOutput, NULL));
|
||||
ALOGV(
|
||||
"xrEnumerateBoundSourcesForAction action=%lld count=%u",
|
||||
(long long)enumerateInfo.action,
|
||||
countOutput);
|
||||
// Get Count
|
||||
uint32_t countOutput = 0;
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
engine->appState.Session, &enumerateInfo, 0 /* request size */, &countOutput, NULL));
|
||||
ALOGV(
|
||||
"xrEnumerateBoundSourcesForAction action=%lld count=%u",
|
||||
(long long)enumerateInfo.action,
|
||||
countOutput);
|
||||
|
||||
if (countOutput < 32) {
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
engine->appState.Session, &enumerateInfo, 32, &countOutput, actionPathsBuffer));
|
||||
for (uint32_t a = 0; a < countOutput; ++a) {
|
||||
XrInputSourceLocalizedNameGetInfo nameGetInfo = {};
|
||||
nameGetInfo.type = XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO;
|
||||
nameGetInfo.next = NULL;
|
||||
nameGetInfo.sourcePath = actionPathsBuffer[a];
|
||||
nameGetInfo.whichComponents = XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT |
|
||||
XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT |
|
||||
XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT;
|
||||
if (countOutput < 32) {
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
engine->appState.Session, &enumerateInfo, 32, &countOutput, actionPathsBuffer));
|
||||
for (uint32_t a = 0; a < countOutput; ++a) {
|
||||
XrInputSourceLocalizedNameGetInfo nameGetInfo = {};
|
||||
nameGetInfo.type = XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO;
|
||||
nameGetInfo.next = NULL;
|
||||
nameGetInfo.sourcePath = actionPathsBuffer[a];
|
||||
nameGetInfo.whichComponents = XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT |
|
||||
XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT |
|
||||
XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT;
|
||||
|
||||
uint32_t stringCount = 0u;
|
||||
OXR(xrGetInputSourceLocalizedName(
|
||||
engine->appState.Session, &nameGetInfo, 0, &stringCount, NULL));
|
||||
if (stringCount < 256) {
|
||||
OXR(xrGetInputSourceLocalizedName(
|
||||
engine->appState.Session, &nameGetInfo, 256, &stringCount, stringBuffer));
|
||||
char pathStr[256];
|
||||
uint32_t strLen = 0;
|
||||
OXR(xrPathToString(
|
||||
engine->appState.Instance,
|
||||
actionPathsBuffer[a],
|
||||
(uint32_t)sizeof(pathStr),
|
||||
&strLen,
|
||||
pathStr));
|
||||
ALOGV(
|
||||
" -> path = %lld `%s` -> `%s`",
|
||||
(long long)actionPathsBuffer[a],
|
||||
pathStr,
|
||||
stringBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inputInitialized = 1;
|
||||
uint32_t stringCount = 0u;
|
||||
OXR(xrGetInputSourceLocalizedName(
|
||||
engine->appState.Session, &nameGetInfo, 0, &stringCount, NULL));
|
||||
if (stringCount < 256) {
|
||||
OXR(xrGetInputSourceLocalizedName(
|
||||
engine->appState.Session, &nameGetInfo, 256, &stringCount, stringBuffer));
|
||||
char pathStr[256];
|
||||
uint32_t strLen = 0;
|
||||
OXR(xrPathToString(
|
||||
engine->appState.Instance,
|
||||
actionPathsBuffer[a],
|
||||
(uint32_t)sizeof(pathStr),
|
||||
&strLen,
|
||||
pathStr));
|
||||
ALOGV(
|
||||
" -> path = %lld `%s` -> `%s`",
|
||||
(long long)actionPathsBuffer[a],
|
||||
pathStr,
|
||||
stringBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inputInitialized = 1;
|
||||
}
|
||||
|
||||
void IN_VRInputFrame( engine_t* engine ) {
|
||||
// Attach to session
|
||||
if (!actionsAttached) {
|
||||
XrSessionActionSetsAttachInfo attachInfo = {};
|
||||
attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
|
||||
attachInfo.next = NULL;
|
||||
attachInfo.countActionSets = 1;
|
||||
attachInfo.actionSets = &runningActionSet;
|
||||
OXR(xrAttachSessionActionSets(engine->appState.Session, &attachInfo));
|
||||
actionsAttached = 1;
|
||||
}
|
||||
// Attach to session
|
||||
if (!actionsAttached) {
|
||||
XrSessionActionSetsAttachInfo attachInfo = {};
|
||||
attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
|
||||
attachInfo.next = NULL;
|
||||
attachInfo.countActionSets = 1;
|
||||
attachInfo.actionSets = &runningActionSet;
|
||||
OXR(xrAttachSessionActionSets(engine->appState.Session, &attachInfo));
|
||||
actionsAttached = 1;
|
||||
}
|
||||
|
||||
// sync action data
|
||||
XrActiveActionSet activeActionSet = {};
|
||||
activeActionSet.actionSet = runningActionSet;
|
||||
activeActionSet.subactionPath = XR_NULL_PATH;
|
||||
// sync action data
|
||||
XrActiveActionSet activeActionSet = {};
|
||||
activeActionSet.actionSet = runningActionSet;
|
||||
activeActionSet.subactionPath = XR_NULL_PATH;
|
||||
|
||||
XrActionsSyncInfo syncInfo = {};
|
||||
syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO;
|
||||
syncInfo.next = NULL;
|
||||
syncInfo.countActiveActionSets = 1;
|
||||
syncInfo.activeActionSets = &activeActionSet;
|
||||
OXR(xrSyncActions(engine->appState.Session, &syncInfo));
|
||||
XrActionsSyncInfo syncInfo = {};
|
||||
syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO;
|
||||
syncInfo.next = NULL;
|
||||
syncInfo.countActiveActionSets = 1;
|
||||
syncInfo.activeActionSets = &activeActionSet;
|
||||
OXR(xrSyncActions(engine->appState.Session, &syncInfo));
|
||||
|
||||
// query input action states
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.next = NULL;
|
||||
getInfo.subactionPath = XR_NULL_PATH;
|
||||
// query input action states
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.next = NULL;
|
||||
getInfo.subactionPath = XR_NULL_PATH;
|
||||
|
||||
VR_processHaptics();
|
||||
VR_processHaptics();
|
||||
|
||||
if (leftControllerAimSpace == XR_NULL_HANDLE) {
|
||||
leftControllerAimSpace = CreateActionSpace(handPoseLeftAction, leftHandPath);
|
||||
}
|
||||
if (rightControllerAimSpace == XR_NULL_HANDLE) {
|
||||
rightControllerAimSpace = CreateActionSpace(handPoseRightAction, rightHandPath);
|
||||
}
|
||||
if (leftControllerAimSpace == XR_NULL_HANDLE) {
|
||||
leftControllerAimSpace = CreateActionSpace(handPoseLeftAction, leftHandPath);
|
||||
}
|
||||
if (rightControllerAimSpace == XR_NULL_HANDLE) {
|
||||
rightControllerAimSpace = CreateActionSpace(handPoseRightAction, rightHandPath);
|
||||
}
|
||||
|
||||
//button mapping
|
||||
lButtons = 0;
|
||||
if (GetActionStateBoolean(menuAction).currentState) lButtons |= ovrButton_Enter;
|
||||
if (GetActionStateBoolean(buttonXAction).currentState) lButtons |= ovrButton_X;
|
||||
if (GetActionStateBoolean(buttonYAction).currentState) lButtons |= ovrButton_Y;
|
||||
if (GetActionStateBoolean(indexLeftAction).currentState) lButtons |= ovrButton_Trigger;
|
||||
if (GetActionStateFloat(gripLeftAction).currentState > 0.5f) lButtons |= ovrButton_GripTrigger;
|
||||
if (GetActionStateBoolean(thumbstickLeftClickAction).currentState) lButtons |= ovrButton_LThumb;
|
||||
rButtons = 0;
|
||||
if (GetActionStateBoolean(buttonAAction).currentState) rButtons |= ovrButton_A;
|
||||
if (GetActionStateBoolean(buttonBAction).currentState) rButtons |= ovrButton_B;
|
||||
if (GetActionStateBoolean(indexRightAction).currentState) rButtons |= ovrButton_Trigger;
|
||||
if (GetActionStateFloat(gripRightAction).currentState > 0.5f) rButtons |= ovrButton_GripTrigger;
|
||||
if (GetActionStateBoolean(thumbstickRightClickAction).currentState) rButtons |= ovrButton_RThumb;
|
||||
//button mapping
|
||||
lButtons = 0;
|
||||
if (GetActionStateBoolean(menuAction).currentState) lButtons |= ovrButton_Enter;
|
||||
if (GetActionStateBoolean(buttonXAction).currentState) lButtons |= ovrButton_X;
|
||||
if (GetActionStateBoolean(buttonYAction).currentState) lButtons |= ovrButton_Y;
|
||||
if (GetActionStateBoolean(indexLeftAction).currentState) lButtons |= ovrButton_Trigger;
|
||||
if (GetActionStateFloat(gripLeftAction).currentState > 0.5f) lButtons |= ovrButton_GripTrigger;
|
||||
if (GetActionStateBoolean(thumbstickLeftClickAction).currentState) lButtons |= ovrButton_LThumb;
|
||||
rButtons = 0;
|
||||
if (GetActionStateBoolean(buttonAAction).currentState) rButtons |= ovrButton_A;
|
||||
if (GetActionStateBoolean(buttonBAction).currentState) rButtons |= ovrButton_B;
|
||||
if (GetActionStateBoolean(indexRightAction).currentState) rButtons |= ovrButton_Trigger;
|
||||
if (GetActionStateFloat(gripRightAction).currentState > 0.5f) rButtons |= ovrButton_GripTrigger;
|
||||
if (GetActionStateBoolean(thumbstickRightClickAction).currentState) rButtons |= ovrButton_RThumb;
|
||||
|
||||
//thumbstick
|
||||
moveJoystickState[0] = GetActionStateVector2(moveOnLeftJoystickAction);
|
||||
moveJoystickState[1] = GetActionStateVector2(moveOnRightJoystickAction);
|
||||
if (moveJoystickState[0].currentState.x > 0.5) lButtons |= ovrButton_Right;
|
||||
if (moveJoystickState[0].currentState.x < -0.5) lButtons |= ovrButton_Left;
|
||||
if (moveJoystickState[0].currentState.y > 0.5) lButtons |= ovrButton_Up;
|
||||
if (moveJoystickState[0].currentState.y < -0.5) lButtons |= ovrButton_Down;
|
||||
if (moveJoystickState[1].currentState.x > 0.5) rButtons |= ovrButton_Right;
|
||||
if (moveJoystickState[1].currentState.x < -0.5) rButtons |= ovrButton_Left;
|
||||
if (moveJoystickState[1].currentState.y > 0.5) rButtons |= ovrButton_Up;
|
||||
if (moveJoystickState[1].currentState.y < -0.5) rButtons |= ovrButton_Down;
|
||||
//thumbstick
|
||||
moveJoystickState[0] = GetActionStateVector2(moveOnLeftJoystickAction);
|
||||
moveJoystickState[1] = GetActionStateVector2(moveOnRightJoystickAction);
|
||||
if (moveJoystickState[0].currentState.x > 0.5) lButtons |= ovrButton_Right;
|
||||
if (moveJoystickState[0].currentState.x < -0.5) lButtons |= ovrButton_Left;
|
||||
if (moveJoystickState[0].currentState.y > 0.5) lButtons |= ovrButton_Up;
|
||||
if (moveJoystickState[0].currentState.y < -0.5) lButtons |= ovrButton_Down;
|
||||
if (moveJoystickState[1].currentState.x > 0.5) rButtons |= ovrButton_Right;
|
||||
if (moveJoystickState[1].currentState.x < -0.5) rButtons |= ovrButton_Left;
|
||||
if (moveJoystickState[1].currentState.y > 0.5) rButtons |= ovrButton_Up;
|
||||
if (moveJoystickState[1].currentState.y < -0.5) rButtons |= ovrButton_Down;
|
||||
|
||||
lastframetime = in_vrEventTime;
|
||||
in_vrEventTime = milliseconds( );
|
||||
|
40
VR/VRInput.h
40
VR/VRInput.h
@ -10,29 +10,29 @@
|
||||
typedef float vec3_t[3];
|
||||
|
||||
typedef enum ovrButton_ {
|
||||
ovrButton_A = 0x00000001, // Set for trigger pulled on the Gear VR and Go Controllers
|
||||
ovrButton_B = 0x00000002,
|
||||
ovrButton_RThumb = 0x00000004,
|
||||
ovrButton_RShoulder = 0x00000008,
|
||||
ovrButton_A = 0x00000001, // Set for trigger pulled on the Gear VR and Go Controllers
|
||||
ovrButton_B = 0x00000002,
|
||||
ovrButton_RThumb = 0x00000004,
|
||||
ovrButton_RShoulder = 0x00000008,
|
||||
|
||||
ovrButton_X = 0x00000100,
|
||||
ovrButton_Y = 0x00000200,
|
||||
ovrButton_LThumb = 0x00000400,
|
||||
ovrButton_LShoulder = 0x00000800,
|
||||
ovrButton_X = 0x00000100,
|
||||
ovrButton_Y = 0x00000200,
|
||||
ovrButton_LThumb = 0x00000400,
|
||||
ovrButton_LShoulder = 0x00000800,
|
||||
|
||||
ovrButton_Up = 0x00010000,
|
||||
ovrButton_Down = 0x00020000,
|
||||
ovrButton_Left = 0x00040000,
|
||||
ovrButton_Right = 0x00080000,
|
||||
ovrButton_Enter = 0x00100000, //< Set for touchpad click on the Go Controller, menu
|
||||
// button on Left Quest Controller
|
||||
ovrButton_Back = 0x00200000, //< Back button on the Go Controller (only set when
|
||||
// a short press comes up)
|
||||
ovrButton_GripTrigger = 0x04000000, //< grip trigger engaged
|
||||
ovrButton_Trigger = 0x20000000, //< Index Trigger engaged
|
||||
ovrButton_Joystick = 0x80000000, //< Click of the Joystick
|
||||
ovrButton_Up = 0x00010000,
|
||||
ovrButton_Down = 0x00020000,
|
||||
ovrButton_Left = 0x00040000,
|
||||
ovrButton_Right = 0x00080000,
|
||||
ovrButton_Enter = 0x00100000, //< Set for touchpad click on the Go Controller, menu
|
||||
// button on Left Quest Controller
|
||||
ovrButton_Back = 0x00200000, //< Back button on the Go Controller (only set when
|
||||
// a short press comes up)
|
||||
ovrButton_GripTrigger = 0x04000000, //< grip trigger engaged
|
||||
ovrButton_Trigger = 0x20000000, //< Index Trigger engaged
|
||||
ovrButton_Joystick = 0x80000000, //< Click of the Joystick
|
||||
|
||||
ovrButton_EnumSize = 0x7fffffff
|
||||
ovrButton_EnumSize = 0x7fffffff
|
||||
} ovrButton;
|
||||
|
||||
void IN_VRInit( engine_t *engine );
|
||||
|
@ -24,100 +24,100 @@ vec3_t hmdposition;
|
||||
extern float radians(float deg);
|
||||
|
||||
void VR_UpdateStageBounds(ovrApp* pappState) {
|
||||
XrExtent2Df stageBounds = {};
|
||||
XrExtent2Df stageBounds = {};
|
||||
|
||||
XrResult result;
|
||||
OXR(result = xrGetReferenceSpaceBoundsRect(
|
||||
pappState->Session, XR_REFERENCE_SPACE_TYPE_STAGE, &stageBounds));
|
||||
if (result != XR_SUCCESS) {
|
||||
ALOGV("Stage bounds query failed: using small defaults");
|
||||
stageBounds.width = 1.0f;
|
||||
stageBounds.height = 1.0f;
|
||||
XrResult result;
|
||||
OXR(result = xrGetReferenceSpaceBoundsRect(
|
||||
pappState->Session, XR_REFERENCE_SPACE_TYPE_STAGE, &stageBounds));
|
||||
if (result != XR_SUCCESS) {
|
||||
ALOGV("Stage bounds query failed: using small defaults");
|
||||
stageBounds.width = 1.0f;
|
||||
stageBounds.height = 1.0f;
|
||||
|
||||
pappState->CurrentSpace = pappState->FakeStageSpace;
|
||||
}
|
||||
pappState->CurrentSpace = pappState->FakeStageSpace;
|
||||
}
|
||||
|
||||
ALOGV("Stage bounds: width = %f, depth %f", stageBounds.width, stageBounds.height);
|
||||
ALOGV("Stage bounds: width = %f, depth %f", stageBounds.width, stageBounds.height);
|
||||
}
|
||||
|
||||
void VR_GetResolution(engine_t* engine, int *pWidth, int *pHeight) {
|
||||
static int width = 0;
|
||||
static int height = 0;
|
||||
|
||||
|
||||
if (engine) {
|
||||
// Enumerate the viewport configurations.
|
||||
uint32_t viewportConfigTypeCount = 0;
|
||||
OXR(xrEnumerateViewConfigurations(
|
||||
engine->appState.Instance, engine->appState.SystemId, 0, &viewportConfigTypeCount, NULL));
|
||||
// Enumerate the viewport configurations.
|
||||
uint32_t viewportConfigTypeCount = 0;
|
||||
OXR(xrEnumerateViewConfigurations(
|
||||
engine->appState.Instance, engine->appState.SystemId, 0, &viewportConfigTypeCount, NULL));
|
||||
|
||||
XrViewConfigurationType* viewportConfigurationTypes =
|
||||
(XrViewConfigurationType*)malloc(viewportConfigTypeCount * sizeof(XrViewConfigurationType));
|
||||
XrViewConfigurationType* viewportConfigurationTypes =
|
||||
(XrViewConfigurationType*)malloc(viewportConfigTypeCount * sizeof(XrViewConfigurationType));
|
||||
|
||||
OXR(xrEnumerateViewConfigurations(
|
||||
engine->appState.Instance,
|
||||
engine->appState.SystemId,
|
||||
viewportConfigTypeCount,
|
||||
&viewportConfigTypeCount,
|
||||
viewportConfigurationTypes));
|
||||
OXR(xrEnumerateViewConfigurations(
|
||||
engine->appState.Instance,
|
||||
engine->appState.SystemId,
|
||||
viewportConfigTypeCount,
|
||||
&viewportConfigTypeCount,
|
||||
viewportConfigurationTypes));
|
||||
|
||||
ALOGV("Available Viewport Configuration Types: %d", viewportConfigTypeCount);
|
||||
ALOGV("Available Viewport Configuration Types: %d", viewportConfigTypeCount);
|
||||
|
||||
for (uint32_t i = 0; i < viewportConfigTypeCount; i++) {
|
||||
const XrViewConfigurationType viewportConfigType = viewportConfigurationTypes[i];
|
||||
for (uint32_t i = 0; i < viewportConfigTypeCount; i++) {
|
||||
const XrViewConfigurationType viewportConfigType = viewportConfigurationTypes[i];
|
||||
|
||||
ALOGV(
|
||||
"Viewport configuration type %d : %s",
|
||||
viewportConfigType,
|
||||
viewportConfigType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO ? "Selected" : "");
|
||||
ALOGV(
|
||||
"Viewport configuration type %d : %s",
|
||||
viewportConfigType,
|
||||
viewportConfigType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO ? "Selected" : "");
|
||||
|
||||
XrViewConfigurationProperties viewportConfig;
|
||||
viewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
||||
OXR(xrGetViewConfigurationProperties(
|
||||
engine->appState.Instance, engine->appState.SystemId, viewportConfigType, &viewportConfig));
|
||||
ALOGV(
|
||||
"FovMutable=%s ConfigurationType %d",
|
||||
viewportConfig.fovMutable ? "true" : "false",
|
||||
viewportConfig.viewConfigurationType);
|
||||
XrViewConfigurationProperties viewportConfig;
|
||||
viewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
||||
OXR(xrGetViewConfigurationProperties(
|
||||
engine->appState.Instance, engine->appState.SystemId, viewportConfigType, &viewportConfig));
|
||||
ALOGV(
|
||||
"FovMutable=%s ConfigurationType %d",
|
||||
viewportConfig.fovMutable ? "true" : "false",
|
||||
viewportConfig.viewConfigurationType);
|
||||
|
||||
uint32_t viewCount;
|
||||
OXR(xrEnumerateViewConfigurationViews(
|
||||
engine->appState.Instance, engine->appState.SystemId, viewportConfigType, 0, &viewCount, NULL));
|
||||
uint32_t viewCount;
|
||||
OXR(xrEnumerateViewConfigurationViews(
|
||||
engine->appState.Instance, engine->appState.SystemId, viewportConfigType, 0, &viewCount, NULL));
|
||||
|
||||
if (viewCount > 0) {
|
||||
XrViewConfigurationView* elements =
|
||||
(XrViewConfigurationView*)malloc(viewCount * sizeof(XrViewConfigurationView));
|
||||
if (viewCount > 0) {
|
||||
XrViewConfigurationView* elements =
|
||||
(XrViewConfigurationView*)malloc(viewCount * sizeof(XrViewConfigurationView));
|
||||
|
||||
for (uint32_t e = 0; e < viewCount; e++) {
|
||||
elements[e].type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
|
||||
elements[e].next = NULL;
|
||||
}
|
||||
for (uint32_t e = 0; e < viewCount; e++) {
|
||||
elements[e].type = XR_TYPE_VIEW_CONFIGURATION_VIEW;
|
||||
elements[e].next = NULL;
|
||||
}
|
||||
|
||||
OXR(xrEnumerateViewConfigurationViews(
|
||||
engine->appState.Instance,
|
||||
engine->appState.SystemId,
|
||||
viewportConfigType,
|
||||
viewCount,
|
||||
&viewCount,
|
||||
elements));
|
||||
OXR(xrEnumerateViewConfigurationViews(
|
||||
engine->appState.Instance,
|
||||
engine->appState.SystemId,
|
||||
viewportConfigType,
|
||||
viewCount,
|
||||
&viewCount,
|
||||
elements));
|
||||
|
||||
// Cache the view config properties for the selected config type.
|
||||
if (viewportConfigType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO) {
|
||||
assert(viewCount == ovrMaxNumEyes);
|
||||
for (uint32_t e = 0; e < viewCount; e++) {
|
||||
engine->appState.ViewConfigurationView[e] = elements[e];
|
||||
}
|
||||
}
|
||||
// Cache the view config properties for the selected config type.
|
||||
if (viewportConfigType == XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO) {
|
||||
assert(viewCount == ovrMaxNumEyes);
|
||||
for (uint32_t e = 0; e < viewCount; e++) {
|
||||
engine->appState.ViewConfigurationView[e] = elements[e];
|
||||
}
|
||||
}
|
||||
|
||||
free(elements);
|
||||
} else {
|
||||
ALOGE("Empty viewport configuration type: %d", viewCount);
|
||||
}
|
||||
}
|
||||
free(elements);
|
||||
} else {
|
||||
ALOGE("Empty viewport configuration type: %d", viewCount);
|
||||
}
|
||||
}
|
||||
|
||||
free(viewportConfigurationTypes);
|
||||
free(viewportConfigurationTypes);
|
||||
|
||||
*pWidth = width = engine->appState.ViewConfigurationView[0].recommendedImageRectWidth;
|
||||
*pHeight = height = engine->appState.ViewConfigurationView[0].recommendedImageRectHeight;
|
||||
*pWidth = width = engine->appState.ViewConfigurationView[0].recommendedImageRectWidth;
|
||||
*pHeight = height = engine->appState.ViewConfigurationView[0].recommendedImageRectHeight;
|
||||
} else {
|
||||
//use cached values
|
||||
*pWidth = width;
|
||||
@ -127,326 +127,326 @@ void VR_GetResolution(engine_t* engine, int *pWidth, int *pHeight) {
|
||||
|
||||
void VR_Recenter(engine_t* engine) {
|
||||
|
||||
// Calculate recenter reference
|
||||
XrReferenceSpaceCreateInfo spaceCreateInfo = {};
|
||||
spaceCreateInfo.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
|
||||
if (engine->appState.CurrentSpace != XR_NULL_HANDLE) {
|
||||
XrSpaceLocation loc = {};
|
||||
loc.type = XR_TYPE_SPACE_LOCATION;
|
||||
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc));
|
||||
vec3_t rotation = {0, 0, 0};
|
||||
QuatToYawPitchRoll(loc.pose.orientation, rotation, hmdorientation);
|
||||
// Calculate recenter reference
|
||||
XrReferenceSpaceCreateInfo spaceCreateInfo = {};
|
||||
spaceCreateInfo.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
|
||||
if (engine->appState.CurrentSpace != XR_NULL_HANDLE) {
|
||||
XrSpaceLocation loc = {};
|
||||
loc.type = XR_TYPE_SPACE_LOCATION;
|
||||
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc));
|
||||
vec3_t rotation = {0, 0, 0};
|
||||
QuatToYawPitchRoll(loc.pose.orientation, rotation, hmdorientation);
|
||||
|
||||
recenterYaw += radians(hmdorientation[YAW]);
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.x = 0;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.y = sin(recenterYaw / 2);
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.z = 0;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.w = cos(recenterYaw / 2);
|
||||
}
|
||||
recenterYaw += radians(hmdorientation[YAW]);
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.x = 0;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.y = sin(recenterYaw / 2);
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.z = 0;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.w = cos(recenterYaw / 2);
|
||||
}
|
||||
|
||||
// Delete previous space instances
|
||||
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
|
||||
OXR(xrDestroySpace(engine->appState.StageSpace));
|
||||
}
|
||||
if (engine->appState.FakeStageSpace != XR_NULL_HANDLE) {
|
||||
OXR(xrDestroySpace(engine->appState.FakeStageSpace));
|
||||
}
|
||||
// Delete previous space instances
|
||||
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
|
||||
OXR(xrDestroySpace(engine->appState.StageSpace));
|
||||
}
|
||||
if (engine->appState.FakeStageSpace != XR_NULL_HANDLE) {
|
||||
OXR(xrDestroySpace(engine->appState.FakeStageSpace));
|
||||
}
|
||||
|
||||
// Create a default stage space to use if SPACE_TYPE_STAGE is not
|
||||
// supported, or calls to xrGetReferenceSpaceBoundsRect fail.
|
||||
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
|
||||
spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f;
|
||||
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.FakeStageSpace));
|
||||
ALOGV("Created fake stage space from local space with offset");
|
||||
engine->appState.CurrentSpace = engine->appState.FakeStageSpace;
|
||||
// Create a default stage space to use if SPACE_TYPE_STAGE is not
|
||||
// supported, or calls to xrGetReferenceSpaceBoundsRect fail.
|
||||
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
|
||||
spaceCreateInfo.poseInReferenceSpace.position.y = -1.6750f;
|
||||
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.FakeStageSpace));
|
||||
ALOGV("Created fake stage space from local space with offset");
|
||||
engine->appState.CurrentSpace = engine->appState.FakeStageSpace;
|
||||
|
||||
if (stageSupported) {
|
||||
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
|
||||
spaceCreateInfo.poseInReferenceSpace.position.y = 0.0;
|
||||
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace));
|
||||
ALOGV("Created stage space");
|
||||
engine->appState.CurrentSpace = engine->appState.StageSpace;
|
||||
}
|
||||
if (stageSupported) {
|
||||
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE;
|
||||
spaceCreateInfo.poseInReferenceSpace.position.y = 0.0;
|
||||
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.StageSpace));
|
||||
ALOGV("Created stage space");
|
||||
engine->appState.CurrentSpace = engine->appState.StageSpace;
|
||||
}
|
||||
|
||||
// Update menu orientation
|
||||
menuYaw = 0;
|
||||
// Update menu orientation
|
||||
menuYaw = 0;
|
||||
}
|
||||
|
||||
void VR_InitRenderer( engine_t* engine ) {
|
||||
int eyeW, eyeH;
|
||||
VR_GetResolution(engine, &eyeW, &eyeH);
|
||||
VR_GetResolution(engine, &eyeW, &eyeH);
|
||||
|
||||
// Get the viewport configuration info for the chosen viewport configuration type.
|
||||
engine->appState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
||||
// Get the viewport configuration info for the chosen viewport configuration type.
|
||||
engine->appState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
||||
|
||||
OXR(xrGetViewConfigurationProperties(
|
||||
engine->appState.Instance, engine->appState.SystemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, &engine->appState.ViewportConfig));
|
||||
OXR(xrGetViewConfigurationProperties(
|
||||
engine->appState.Instance, engine->appState.SystemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, &engine->appState.ViewportConfig));
|
||||
|
||||
uint32_t numOutputSpaces = 0;
|
||||
OXR(xrEnumerateReferenceSpaces(engine->appState.Session, 0, &numOutputSpaces, NULL));
|
||||
uint32_t numOutputSpaces = 0;
|
||||
OXR(xrEnumerateReferenceSpaces(engine->appState.Session, 0, &numOutputSpaces, NULL));
|
||||
|
||||
XrReferenceSpaceType* referenceSpaces =
|
||||
(XrReferenceSpaceType*)malloc(numOutputSpaces * sizeof(XrReferenceSpaceType));
|
||||
XrReferenceSpaceType* referenceSpaces =
|
||||
(XrReferenceSpaceType*)malloc(numOutputSpaces * sizeof(XrReferenceSpaceType));
|
||||
|
||||
OXR(xrEnumerateReferenceSpaces(
|
||||
engine->appState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
|
||||
OXR(xrEnumerateReferenceSpaces(
|
||||
engine->appState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
|
||||
|
||||
for (uint32_t i = 0; i < numOutputSpaces; i++) {
|
||||
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
||||
stageSupported = GL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < numOutputSpaces; i++) {
|
||||
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
||||
stageSupported = GL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(referenceSpaces);
|
||||
free(referenceSpaces);
|
||||
|
||||
if (engine->appState.CurrentSpace == XR_NULL_HANDLE) {
|
||||
VR_Recenter(engine);
|
||||
}
|
||||
if (engine->appState.CurrentSpace == XR_NULL_HANDLE) {
|
||||
VR_Recenter(engine);
|
||||
}
|
||||
|
||||
projections = (XrView*)(malloc(ovrMaxNumEyes * sizeof(XrView)));
|
||||
projections = (XrView*)(malloc(ovrMaxNumEyes * sizeof(XrView)));
|
||||
|
||||
ovrRenderer_Create(
|
||||
engine->appState.Session,
|
||||
&engine->appState.Renderer,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectWidth,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight);
|
||||
initialized = GL_TRUE;
|
||||
ovrRenderer_Create(
|
||||
engine->appState.Session,
|
||||
&engine->appState.Renderer,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectWidth,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight);
|
||||
initialized = GL_TRUE;
|
||||
}
|
||||
|
||||
void VR_DestroyRenderer( engine_t* engine ) {
|
||||
ovrRenderer_Destroy(&engine->appState.Renderer);
|
||||
free(projections);
|
||||
initialized = GL_FALSE;
|
||||
ovrRenderer_Destroy(&engine->appState.Renderer);
|
||||
free(projections);
|
||||
initialized = GL_FALSE;
|
||||
}
|
||||
|
||||
void VR_ClearFrameBuffer( int width, int height) {
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
glViewport( 0, 0, width, height );
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
glScissor( 0, 0, width, height );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
glScissor( 0, 0, width, height );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
glScissor( 0, 0, 0, 0 );
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
glScissor( 0, 0, 0, 0 );
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
}
|
||||
|
||||
void VR_BeginFrame( engine_t* engine ) {
|
||||
GLboolean stageBoundsDirty = GL_TRUE;
|
||||
if (ovrApp_HandleXrEvents(&engine->appState)) {
|
||||
VR_Recenter(engine);
|
||||
}
|
||||
if (engine->appState.SessionActive == GL_FALSE) {
|
||||
return;
|
||||
}
|
||||
GLboolean stageBoundsDirty = GL_TRUE;
|
||||
if (ovrApp_HandleXrEvents(&engine->appState)) {
|
||||
VR_Recenter(engine);
|
||||
}
|
||||
if (engine->appState.SessionActive == GL_FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (stageBoundsDirty) {
|
||||
VR_UpdateStageBounds(&engine->appState);
|
||||
stageBoundsDirty = GL_FALSE;
|
||||
}
|
||||
if (stageBoundsDirty) {
|
||||
VR_UpdateStageBounds(&engine->appState);
|
||||
stageBoundsDirty = GL_FALSE;
|
||||
}
|
||||
|
||||
// NOTE: OpenXR does not use the concept of frame indices. Instead,
|
||||
// XrWaitFrame returns the predicted display time.
|
||||
XrFrameWaitInfo waitFrameInfo = {};
|
||||
waitFrameInfo.type = XR_TYPE_FRAME_WAIT_INFO;
|
||||
waitFrameInfo.next = NULL;
|
||||
// NOTE: OpenXR does not use the concept of frame indices. Instead,
|
||||
// XrWaitFrame returns the predicted display time.
|
||||
XrFrameWaitInfo waitFrameInfo = {};
|
||||
waitFrameInfo.type = XR_TYPE_FRAME_WAIT_INFO;
|
||||
waitFrameInfo.next = NULL;
|
||||
|
||||
frameState.type = XR_TYPE_FRAME_STATE;
|
||||
frameState.next = NULL;
|
||||
frameState.type = XR_TYPE_FRAME_STATE;
|
||||
frameState.next = NULL;
|
||||
|
||||
OXR(xrWaitFrame(engine->appState.Session, &waitFrameInfo, &frameState));
|
||||
engine->predictedDisplayTime = frameState.predictedDisplayTime;
|
||||
if (!frameState.shouldRender) {
|
||||
return;
|
||||
}
|
||||
OXR(xrWaitFrame(engine->appState.Session, &waitFrameInfo, &frameState));
|
||||
engine->predictedDisplayTime = frameState.predictedDisplayTime;
|
||||
if (!frameState.shouldRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the HMD pose, predicted for the middle of the time period during which
|
||||
// the new eye images will be displayed. The number of frames predicted ahead
|
||||
// depends on the pipeline depth of the engine and the synthesis rate.
|
||||
// The better the prediction, the less black will be pulled in at the edges.
|
||||
XrFrameBeginInfo beginFrameDesc = {};
|
||||
beginFrameDesc.type = XR_TYPE_FRAME_BEGIN_INFO;
|
||||
beginFrameDesc.next = NULL;
|
||||
OXR(xrBeginFrame(engine->appState.Session, &beginFrameDesc));
|
||||
// Get the HMD pose, predicted for the middle of the time period during which
|
||||
// the new eye images will be displayed. The number of frames predicted ahead
|
||||
// depends on the pipeline depth of the engine and the synthesis rate.
|
||||
// The better the prediction, the less black will be pulled in at the edges.
|
||||
XrFrameBeginInfo beginFrameDesc = {};
|
||||
beginFrameDesc.type = XR_TYPE_FRAME_BEGIN_INFO;
|
||||
beginFrameDesc.next = NULL;
|
||||
OXR(xrBeginFrame(engine->appState.Session, &beginFrameDesc));
|
||||
|
||||
XrViewLocateInfo projectionInfo = {};
|
||||
projectionInfo.type = XR_TYPE_VIEW_LOCATE_INFO;
|
||||
projectionInfo.viewConfigurationType = engine->appState.ViewportConfig.viewConfigurationType;
|
||||
projectionInfo.displayTime = frameState.predictedDisplayTime;
|
||||
projectionInfo.space = engine->appState.CurrentSpace;
|
||||
XrViewLocateInfo projectionInfo = {};
|
||||
projectionInfo.type = XR_TYPE_VIEW_LOCATE_INFO;
|
||||
projectionInfo.viewConfigurationType = engine->appState.ViewportConfig.viewConfigurationType;
|
||||
projectionInfo.displayTime = frameState.predictedDisplayTime;
|
||||
projectionInfo.space = engine->appState.CurrentSpace;
|
||||
|
||||
XrViewState viewState = {XR_TYPE_VIEW_STATE, NULL};
|
||||
XrViewState viewState = {XR_TYPE_VIEW_STATE, NULL};
|
||||
|
||||
uint32_t projectionCapacityInput = ovrMaxNumEyes;
|
||||
uint32_t projectionCountOutput = projectionCapacityInput;
|
||||
uint32_t projectionCapacityInput = ovrMaxNumEyes;
|
||||
uint32_t projectionCountOutput = projectionCapacityInput;
|
||||
|
||||
OXR(xrLocateViews(
|
||||
engine->appState.Session,
|
||||
&projectionInfo,
|
||||
&viewState,
|
||||
projectionCapacityInput,
|
||||
&projectionCountOutput,
|
||||
projections));
|
||||
//
|
||||
OXR(xrLocateViews(
|
||||
engine->appState.Session,
|
||||
&projectionInfo,
|
||||
&viewState,
|
||||
projectionCapacityInput,
|
||||
&projectionCountOutput,
|
||||
projections));
|
||||
//
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
invViewTransform[eye] = projections[eye].pose;
|
||||
}
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
invViewTransform[eye] = projections[eye].pose;
|
||||
}
|
||||
|
||||
// Update HMD and controllers
|
||||
vec3_t rotation = {0, 0, 0};
|
||||
QuatToYawPitchRoll(invViewTransform[0].orientation, rotation, hmdorientation);
|
||||
// Update HMD and controllers
|
||||
vec3_t rotation = {0, 0, 0};
|
||||
QuatToYawPitchRoll(invViewTransform[0].orientation, rotation, hmdorientation);
|
||||
hmdposition[0] = invViewTransform[0].position.x;
|
||||
hmdposition[1] = invViewTransform[0].position.y;
|
||||
hmdposition[2] = invViewTransform[0].position.z;
|
||||
IN_VRInputFrame(engine);
|
||||
|
||||
engine->appState.LayerCount = 0;
|
||||
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||
engine->appState.LayerCount = 0;
|
||||
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
int swapchainIndex = frameBuffer->TextureSwapChainIndex;
|
||||
int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
int swapchainIndex = frameBuffer->TextureSwapChainIndex;
|
||||
int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
|
||||
|
||||
ovrFramebuffer_Acquire(frameBuffer);
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
|
||||
}
|
||||
ovrFramebuffer_Acquire(frameBuffer);
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
|
||||
}
|
||||
}
|
||||
|
||||
void VR_EndFrame( engine_t* engine ) {
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
|
||||
// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
//TODO:ovrFramebuffer_Resolve(frameBuffer);
|
||||
ovrFramebuffer_Release(frameBuffer);
|
||||
}
|
||||
ovrFramebuffer_SetNone();
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
//TODO:ovrFramebuffer_Resolve(frameBuffer);
|
||||
ovrFramebuffer_Release(frameBuffer);
|
||||
}
|
||||
ovrFramebuffer_SetNone();
|
||||
|
||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {
|
||||
menuYaw = hmdorientation[YAW];
|
||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {
|
||||
menuYaw = hmdorientation[YAW];
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
if (vrMode == VR_MODE_MONO_6DOF) {
|
||||
frameBuffer = &engine->appState.Renderer.FrameBuffer[0];
|
||||
}
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
if (vrMode == VR_MODE_MONO_6DOF) {
|
||||
frameBuffer = &engine->appState.Renderer.FrameBuffer[0];
|
||||
}
|
||||
|
||||
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
||||
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
projection_layer_elements[eye].pose = invViewTransform[eye];
|
||||
projection_layer_elements[eye].fov = projections[eye].fov;
|
||||
memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
|
||||
projection_layer_elements[eye].type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW;
|
||||
projection_layer_elements[eye].pose = invViewTransform[eye];
|
||||
projection_layer_elements[eye].fov = projections[eye].fov;
|
||||
|
||||
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
projection_layer_elements[eye].subImage.swapchain = frameBuffer->ColorSwapChain.Handle;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.x = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.y = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.width = frameBuffer->ColorSwapChain.Width;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.height = frameBuffer->ColorSwapChain.Height;
|
||||
projection_layer_elements[eye].subImage.imageArrayIndex = 0;
|
||||
}
|
||||
memset(&projection_layer_elements[eye].subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
projection_layer_elements[eye].subImage.swapchain = frameBuffer->ColorSwapChain.Handle;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.x = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.offset.y = 0;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.width = frameBuffer->ColorSwapChain.Width;
|
||||
projection_layer_elements[eye].subImage.imageRect.extent.height = frameBuffer->ColorSwapChain.Height;
|
||||
projection_layer_elements[eye].subImage.imageArrayIndex = 0;
|
||||
}
|
||||
|
||||
XrCompositionLayerProjection projection_layer = {};
|
||||
projection_layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
|
||||
projection_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
|
||||
projection_layer.layerFlags |= XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
|
||||
projection_layer.space = engine->appState.CurrentSpace;
|
||||
projection_layer.viewCount = ovrMaxNumEyes;
|
||||
projection_layer.views = projection_layer_elements;
|
||||
XrCompositionLayerProjection projection_layer = {};
|
||||
projection_layer.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION;
|
||||
projection_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
|
||||
projection_layer.layerFlags |= XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT;
|
||||
projection_layer.space = engine->appState.CurrentSpace;
|
||||
projection_layer.viewCount = ovrMaxNumEyes;
|
||||
projection_layer.views = projection_layer_elements;
|
||||
|
||||
engine->appState.Layers[engine->appState.LayerCount++].Projection = projection_layer;
|
||||
} else if (vrMode == VR_MODE_FLAT_SCREEN) {
|
||||
engine->appState.Layers[engine->appState.LayerCount++].Projection = projection_layer;
|
||||
} else if (vrMode == VR_MODE_FLAT_SCREEN) {
|
||||
|
||||
// Build the cylinder layer
|
||||
int width = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Width;
|
||||
int height = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Height;
|
||||
XrCompositionLayerCylinderKHR cylinder_layer = {};
|
||||
cylinder_layer.type = XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR;
|
||||
cylinder_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
|
||||
cylinder_layer.space = engine->appState.CurrentSpace;
|
||||
cylinder_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH;
|
||||
memset(&cylinder_layer.subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
cylinder_layer.subImage.swapchain = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Handle;
|
||||
cylinder_layer.subImage.imageRect.offset.x = 0;
|
||||
cylinder_layer.subImage.imageRect.offset.y = 0;
|
||||
cylinder_layer.subImage.imageRect.extent.width = width;
|
||||
cylinder_layer.subImage.imageRect.extent.height = height;
|
||||
cylinder_layer.subImage.imageArrayIndex = 0;
|
||||
const XrVector3f axis = {0.0f, 1.0f, 0.0f};
|
||||
XrVector3f pos = {
|
||||
invViewTransform[0].position.x - sin(radians(menuYaw)) * 6.0f,
|
||||
invViewTransform[0].position.y,
|
||||
invViewTransform[0].position.z - cos(radians(menuYaw)) * 6.0f
|
||||
};
|
||||
cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, radians(menuYaw));
|
||||
cylinder_layer.pose.position = pos;
|
||||
cylinder_layer.radius = 12.0f;
|
||||
cylinder_layer.centralAngle = MATH_PI * 0.5f;
|
||||
cylinder_layer.aspectRatio = height / (float)width;
|
||||
// Build the cylinder layer
|
||||
int width = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Width;
|
||||
int height = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Height;
|
||||
XrCompositionLayerCylinderKHR cylinder_layer = {};
|
||||
cylinder_layer.type = XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR;
|
||||
cylinder_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
|
||||
cylinder_layer.space = engine->appState.CurrentSpace;
|
||||
cylinder_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH;
|
||||
memset(&cylinder_layer.subImage, 0, sizeof(XrSwapchainSubImage));
|
||||
cylinder_layer.subImage.swapchain = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Handle;
|
||||
cylinder_layer.subImage.imageRect.offset.x = 0;
|
||||
cylinder_layer.subImage.imageRect.offset.y = 0;
|
||||
cylinder_layer.subImage.imageRect.extent.width = width;
|
||||
cylinder_layer.subImage.imageRect.extent.height = height;
|
||||
cylinder_layer.subImage.imageArrayIndex = 0;
|
||||
const XrVector3f axis = {0.0f, 1.0f, 0.0f};
|
||||
XrVector3f pos = {
|
||||
invViewTransform[0].position.x - sin(radians(menuYaw)) * 6.0f,
|
||||
invViewTransform[0].position.y,
|
||||
invViewTransform[0].position.z - cos(radians(menuYaw)) * 6.0f
|
||||
};
|
||||
cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, radians(menuYaw));
|
||||
cylinder_layer.pose.position = pos;
|
||||
cylinder_layer.radius = 12.0f;
|
||||
cylinder_layer.centralAngle = MATH_PI * 0.5f;
|
||||
cylinder_layer.aspectRatio = height / (float)width;
|
||||
|
||||
engine->appState.Layers[engine->appState.LayerCount++].Cylinder = cylinder_layer;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
engine->appState.Layers[engine->appState.LayerCount++].Cylinder = cylinder_layer;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// Compose the layers for this frame.
|
||||
const XrCompositionLayerBaseHeader* layers[ovrMaxLayerCount] = {};
|
||||
for (int i = 0; i < engine->appState.LayerCount; i++) {
|
||||
layers[i] = (const XrCompositionLayerBaseHeader*)&engine->appState.Layers[i];
|
||||
}
|
||||
// Compose the layers for this frame.
|
||||
const XrCompositionLayerBaseHeader* layers[ovrMaxLayerCount] = {};
|
||||
for (int i = 0; i < engine->appState.LayerCount; i++) {
|
||||
layers[i] = (const XrCompositionLayerBaseHeader*)&engine->appState.Layers[i];
|
||||
}
|
||||
|
||||
XrFrameEndInfo endFrameInfo = {};
|
||||
endFrameInfo.type = XR_TYPE_FRAME_END_INFO;
|
||||
endFrameInfo.displayTime = frameState.predictedDisplayTime;
|
||||
endFrameInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
|
||||
endFrameInfo.layerCount = engine->appState.LayerCount;
|
||||
endFrameInfo.layers = layers;
|
||||
XrFrameEndInfo endFrameInfo = {};
|
||||
endFrameInfo.type = XR_TYPE_FRAME_END_INFO;
|
||||
endFrameInfo.displayTime = frameState.predictedDisplayTime;
|
||||
endFrameInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
|
||||
endFrameInfo.layerCount = engine->appState.LayerCount;
|
||||
endFrameInfo.layers = layers;
|
||||
|
||||
OXR(xrEndFrame(engine->appState.Session, &endFrameInfo));
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
frameBuffer->TextureSwapChainIndex++;
|
||||
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
|
||||
}
|
||||
OXR(xrEndFrame(engine->appState.Session, &endFrameInfo));
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
frameBuffer->TextureSwapChainIndex++;
|
||||
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
|
||||
}
|
||||
}
|
||||
|
||||
void VR_BindFramebuffer( engine_t* engine, int eye ) {
|
||||
if (!initialized) return;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
int swapchainIndex = frameBuffer->TextureSwapChainIndex;
|
||||
int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, glFramebuffer);
|
||||
if (!initialized) return;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
|
||||
int swapchainIndex = frameBuffer->TextureSwapChainIndex;
|
||||
int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, glFramebuffer);
|
||||
}
|
||||
|
||||
ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) {
|
||||
ovrMatrix4f output;
|
||||
if (matrix == VR_PROJECTION_MATRIX_HUD) {
|
||||
float hudScale = radians(15.0f);
|
||||
output = ovrMatrix4f_CreateProjectionFov(-hudScale, hudScale, hudScale, -hudScale, 1.0f, 0.0f );
|
||||
} else if ((matrix == VR_PROJECTION_MATRIX_LEFT_EYE) || (matrix == VR_PROJECTION_MATRIX_RIGHT_EYE)) {
|
||||
XrFovf fov = matrix == VR_PROJECTION_MATRIX_LEFT_EYE ? projections[0].fov : projections[1].fov;
|
||||
output = ovrMatrix4f_CreateProjectionFov(fov.angleLeft, fov.angleRight, fov.angleUp, fov.angleDown, 1.0f, 0.0f );
|
||||
} else if ((matrix == VR_PROJECTION_MATRIX_LEFT_EYE) || (matrix == VR_PROJECTION_MATRIX_RIGHT_EYE)) {
|
||||
XrPosef invView = matrix == VR_VIEW_MATRIX_LEFT_EYE ? invViewTransform[0] : invViewTransform[1];
|
||||
XrPosef view = XrPosef_Inverse(invView);
|
||||
output = ovrMatrix4f_CreateFromQuaternion(&view.orientation);
|
||||
output.M[3][0] = view.position.x;
|
||||
output.M[3][1] = view.position.y;
|
||||
output.M[3][2] = view.position.z;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
return output;
|
||||
ovrMatrix4f output;
|
||||
if (matrix == VR_PROJECTION_MATRIX_HUD) {
|
||||
float hudScale = radians(15.0f);
|
||||
output = ovrMatrix4f_CreateProjectionFov(-hudScale, hudScale, hudScale, -hudScale, 1.0f, 0.0f );
|
||||
} else if ((matrix == VR_PROJECTION_MATRIX_LEFT_EYE) || (matrix == VR_PROJECTION_MATRIX_RIGHT_EYE)) {
|
||||
XrFovf fov = matrix == VR_PROJECTION_MATRIX_LEFT_EYE ? projections[0].fov : projections[1].fov;
|
||||
output = ovrMatrix4f_CreateProjectionFov(fov.angleLeft, fov.angleRight, fov.angleUp, fov.angleDown, 1.0f, 0.0f );
|
||||
} else if ((matrix == VR_VIEW_MATRIX_LEFT_EYE) || (matrix == VR_VIEW_MATRIX_RIGHT_EYE)) {
|
||||
XrPosef invView = matrix == VR_VIEW_MATRIX_LEFT_EYE ? invViewTransform[0] : invViewTransform[1];
|
||||
XrPosef view = XrPosef_Inverse(invView);
|
||||
output = ovrMatrix4f_CreateFromQuaternion(&view.orientation);
|
||||
output.M[3][0] = view.position.x;
|
||||
output.M[3][1] = view.position.y;
|
||||
output.M[3][2] = view.position.z;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user