early start on this OpenXR - doesn't build yet

This commit is contained in:
Simon 2022-12-04 11:46:32 +00:00
parent 257382adcd
commit 58a115d4b1
13 changed files with 1023 additions and 493 deletions

View file

@ -34,18 +34,10 @@ Copyright : Copyright 2015 Oculus VR, LLC. All Rights reserved.
#define GL_GLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES
#include <GLES/gl2ext.h> #include <GLES/gl2ext.h>
#include "VrApi.h"
#include "VrApi_Helpers.h"
#include "VrApi_SystemUtils.h"
#include "VrApi_Input.h"
#include "VrApi_Types.h"
extern "C" { extern "C" {
#include "src/gl/loader.h" #include "src/gl/loader.h"
} }
//#include <SDL2/SDL.h>
//#include <SDL2/SDL_main.h>
#include <client/client.h> #include <client/client.h>
#include "VrCompositor.h" #include "VrCompositor.h"
@ -111,8 +103,16 @@ struct arg_end *end;
char **argv; char **argv;
int argc=0; int argc=0;
extern cvar_t *r_lefthand;
extern cvar_t *cl_paused; const char* const requiredExtensionNames[] = {
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME,
XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME,
XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME,
XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME};
const uint32_t numRequiredExtensions =
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);
/* /*
================================================================================ ================================================================================
@ -486,26 +486,25 @@ ovrFramebuffer
*/ */
static void ovrFramebuffer_Clear( ovrFramebuffer * frameBuffer ) static void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
{
frameBuffer->Width = 0; frameBuffer->Width = 0;
frameBuffer->Height = 0; frameBuffer->Height = 0;
frameBuffer->Multisamples = 0;
frameBuffer->TextureSwapChainLength = 0; frameBuffer->TextureSwapChainLength = 0;
frameBuffer->TextureSwapChainIndex = 0; frameBuffer->TextureSwapChainIndex = 0;
frameBuffer->ColorTextureSwapChain = NULL; frameBuffer->ColorSwapChain.Handle = XR_NULL_HANDLE;
frameBuffer->ColorSwapChain.Width = 0;
frameBuffer->ColorSwapChain.Height = 0;
frameBuffer->ColorSwapChainImage = NULL;
frameBuffer->DepthBuffers = NULL; frameBuffer->DepthBuffers = NULL;
frameBuffer->FrameBuffers = NULL; frameBuffer->FrameBuffers = NULL;
} }
static bool ovrFramebuffer_Create( ovrFramebuffer * frameBuffer, const GLenum colorFormat, const int width, const int height, const int multisamples ) static bool ovrFramebuffer_Create( XrSession session,
ovrFramebuffer * frameBuffer, const GLenum colorFormat, const int width, const int height )
{ {
frameBuffer->Width = width; frameBuffer->Width = width;
frameBuffer->Height = height; frameBuffer->Height = height;
frameBuffer->Multisamples = multisamples;
frameBuffer->ColorTextureSwapChain = vrapi_CreateTextureSwapChain3( VRAPI_TEXTURE_TYPE_2D, colorFormat, frameBuffer->Width, frameBuffer->Height, 1, 3 );
frameBuffer->TextureSwapChainLength = vrapi_GetTextureSwapChainLength( frameBuffer->ColorTextureSwapChain );
frameBuffer->DepthBuffers = (GLuint *)malloc( frameBuffer->TextureSwapChainLength * sizeof( GLuint ) ); frameBuffer->DepthBuffers = (GLuint *)malloc( frameBuffer->TextureSwapChainLength * sizeof( GLuint ) );
frameBuffer->FrameBuffers = (GLuint *)malloc( frameBuffer->TextureSwapChainLength * sizeof( GLuint ) ); frameBuffer->FrameBuffers = (GLuint *)malloc( frameBuffer->TextureSwapChainLength * sizeof( GLuint ) );
@ -514,20 +513,56 @@ static bool ovrFramebuffer_Create( ovrFramebuffer * frameBuffer, const GLenum co
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT = PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT =
(PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)eglGetProcAddress("glFramebufferTexture2DMultisampleEXT"); (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
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 = 2;
swapChainCreateInfo.mipCount = 1;
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));
// 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));
for ( int i = 0; i < frameBuffer->TextureSwapChainLength; i++ ) for ( int i = 0; i < frameBuffer->TextureSwapChainLength; i++ )
{ {
// Create the color buffer texture. // Create the color buffer texture.
const GLuint colorTexture = vrapi_GetTextureSwapChainHandle( frameBuffer->ColorTextureSwapChain, i ); const GLuint colorTexture = frameBuffer->ColorSwapChainImage[i].image;
GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i])); GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i]));
GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i])); GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, multisamples, GL_DEPTH_COMPONENT24, width, height)); GL(glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 1, GL_DEPTH_COMPONENT24, width, height));
GL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); GL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
// Create the frame buffer. // Create the frame buffer.
GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i])); GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i]));
GL(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->FrameBuffers[i])); GL(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer->FrameBuffers[i]));
GL(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0, multisamples)); GL(glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0, 1));
GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i])); GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i]));
GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER)); GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER));
@ -653,13 +688,10 @@ void ovrRenderer_Clear( ovrRenderer * renderer )
} }
void ovrRenderer_Create( int width, int height, ovrRenderer * renderer, const ovrJava * java ) void ovrRenderer_Create( int width, int height, ovrRenderer * renderer )
{ {
renderer->NumBuffers = VRAPI_FRAME_LAYER_EYE_MAX; renderer->NumBuffers = VRAPI_FRAME_LAYER_EYE_MAX;
//Now using a symmetrical render target, based on the horizontal FOV
vr.fov = vrapi_GetSystemPropertyInt( java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y);
// Create the render Textures. // Create the render Textures.
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ ) for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
{ {
@ -669,11 +701,6 @@ void ovrRenderer_Create( int width, int height, ovrRenderer * renderer, const ov
height, height,
NUM_MULTI_SAMPLES ); NUM_MULTI_SAMPLES );
} }
// Setup the projection matrix.
renderer->ProjectionMatrix = ovrMatrix4f_CreateProjectionFov(
vr.fov, vr.fov, 0.0f, 0.0f, 1.0f, 0.0f );
} }
void ovrRenderer_Destroy( ovrRenderer * renderer ) void ovrRenderer_Destroy( ovrRenderer * renderer )
@ -766,7 +793,7 @@ void GetAnglesFromVectors(const ovrVector3f forward, const ovrVector3f right, co
} }
void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out) { void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out) {
ovrMatrix4f mat = ovrMatrix4f_CreateFromQuaternion( &q ); ovrMatrix4f mat = ovrMatrix4f_CreateFromQuaternion( &q );
@ -776,24 +803,23 @@ void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out) {
mat = ovrMatrix4f_Multiply(&mat, &rot); mat = ovrMatrix4f_Multiply(&mat, &rot);
} }
ovrVector4f v1 = {0, 0, -1, 0}; XrVector4f v1 = {0, 0, -1, 0};
ovrVector4f v2 = {1, 0, 0, 0}; XrVector4f v2 = {1, 0, 0, 0};
ovrVector4f v3 = {0, 1, 0, 0}; XrVector4f v3 = {0, 1, 0, 0};
ovrVector4f forwardInVRSpace = ovrVector4f_MultiplyMatrix4f(&mat, &v1); XrVector4f forwardInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v1);
ovrVector4f rightInVRSpace = ovrVector4f_MultiplyMatrix4f(&mat, &v2); XrVector4f rightInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v2);
ovrVector4f upInVRSpace = ovrVector4f_MultiplyMatrix4f(&mat, &v3); XrVector4f upInVRSpace = XrVector4f_MultiplyMatrix4f(&mat, &v3);
ovrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y}; XrVector3f forward = {-forwardInVRSpace.z, -forwardInVRSpace.x, forwardInVRSpace.y};
ovrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y}; XrVector3f right = {-rightInVRSpace.z, -rightInVRSpace.x, rightInVRSpace.y};
ovrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y}; XrVector3f up = {-upInVRSpace.z, -upInVRSpace.x, upInVRSpace.y};
ovrVector3f forwardNormal = normalizeVec(forward); XrVector3f forwardNormal = normalizeVec(forward);
ovrVector3f rightNormal = normalizeVec(right); XrVector3f rightNormal = normalizeVec(right);
ovrVector3f upNormal = normalizeVec(up); XrVector3f upNormal = normalizeVec(up);
GetAnglesFromVectors(forwardNormal, rightNormal, upNormal, out); GetAnglesFromVectors(forwardNormal, rightNormal, upNormal, out);
return;
} }
void updateHMDOrientation() void updateHMDOrientation()
@ -938,52 +964,32 @@ ovrRenderThread
*/ */
/*
================================================================================
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));
typedef struct memset(&app->ViewConfigurationView, 0, ovrMaxNumEyes * sizeof(XrViewConfigurationView));
{ app->SystemId = XR_NULL_SYSTEM_ID;
ovrJava Java; app->HeadSpace = XR_NULL_HANDLE;
ovrEgl Egl; app->StageSpace = XR_NULL_HANDLE;
ANativeWindow * NativeWindow; app->FakeStageSpace = XR_NULL_HANDLE;
bool Resumed; app->CurrentSpace = XR_NULL_HANDLE;
ovrMobile * Ovr; app->SessionActive = false;
ovrScene Scene; app->SupportedDisplayRefreshRates = NULL;
long long FrameIndex; app->RequestedDisplayRefreshRateIndex = 0;
double DisplayTime; app->NumSupportedDisplayRefreshRates = 0;
int SwapInterval; app->pfnGetDisplayRefreshRate = NULL;
int CpuLevel; app->pfnRequestDisplayRefreshRate = NULL;
int GpuLevel;
int MainThreadTid;
int RenderThreadTid;
ovrLayer_Union2 Layers[ovrMaxLayerCount];
int LayerCount;
ovrRenderer Renderer;
} ovrApp;
static void ovrApp_Clear( ovrApp * app )
{
app->Java.Vm = NULL;
app->Java.Env = NULL;
app->Java.ActivityObject = NULL;
app->Ovr = NULL;
app->FrameIndex = 1;
app->DisplayTime = 0;
app->SwapInterval = 1; app->SwapInterval = 1;
app->CpuLevel = 3; memset(app->Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
app->GpuLevel = 3; app->LayerCount = 0;
app->MainThreadTid = 0; app->MainThreadTid = 0;
app->RenderThreadTid = 0; app->RenderThreadTid = 0;
ovrEgl_Clear( &app->Egl ); ovrEgl_Clear( &app->Egl );
ovrScene_Clear( &app->Scene ); ovrScene_Clear( &app->Scene );
ovrRenderer_Clear( &app->Renderer ); ovrRenderer_Clear(&app->Renderer);
} }
static void ovrApp_PushBlackFinal( ovrApp * app ) static void ovrApp_PushBlackFinal( ovrApp * app )
@ -1010,74 +1016,145 @@ static void ovrApp_PushBlackFinal( ovrApp * app )
vrapi_SubmitFrame2( app->Ovr, &frameDesc ); vrapi_SubmitFrame2( app->Ovr, &frameDesc );
} }
static void ovrApp_HandleVrModeChanges( ovrApp * app )
{
if ( app->Resumed != false && app->NativeWindow != NULL )
{
if ( app->Ovr == NULL )
{
ovrModeParms parms = vrapi_DefaultModeParms( &app->Java );
// Must reset the FLAG_FULLSCREEN window flag when using a SurfaceView
parms.Flags |= VRAPI_MODE_FLAG_RESET_WINDOW_FULLSCREEN;
parms.Flags |= VRAPI_MODE_FLAG_NATIVE_WINDOW;
parms.Display = (size_t)app->Egl.Display;
parms.WindowSurface = (size_t)app->NativeWindow;
parms.ShareContext = (size_t)app->Egl.Context;
ALOGV( " eglGetCurrentSurface( EGL_DRAW ) = %p", eglGetCurrentSurface( EGL_DRAW ) ); void ovrApp_HandleSessionStateChanges(ovrApp* app, XrSessionState state) {
if (state == XR_SESSION_STATE_READY) {
assert(app->SessionActive == false);
ALOGV( " vrapi_EnterVrMode()" ); XrSessionBeginInfo sessionBeginInfo;
memset(&sessionBeginInfo, 0, sizeof(sessionBeginInfo));
sessionBeginInfo.type = XR_TYPE_SESSION_BEGIN_INFO;
sessionBeginInfo.next = NULL;
sessionBeginInfo.primaryViewConfigurationType = app->ViewportConfig.viewConfigurationType;
app->Ovr = vrapi_EnterVrMode( &parms ); XrResult result;
OXR(result = xrBeginSession(app->Session, &sessionBeginInfo));
ALOGV( " eglGetCurrentSurface( EGL_DRAW ) = %p", eglGetCurrentSurface( EGL_DRAW ) ); app->SessionActive = (result == XR_SUCCESS);
// If entering VR mode failed then the ANativeWindow was not valid. // Set session state once we have entered VR mode and have a valid session object.
if ( app->Ovr == NULL ) if (app->SessionActive) {
{ XrPerfSettingsLevelEXT cpuPerfLevel = XR_PERF_SETTINGS_LEVEL_BOOST_EXT;
ALOGE( "Invalid ANativeWindow!" ); XrPerfSettingsLevelEXT gpuPerfLevel = XR_PERF_SETTINGS_LEVEL_BOOST_EXT;
app->NativeWindow = NULL;
PFN_xrPerfSettingsSetPerformanceLevelEXT pfnPerfSettingsSetPerformanceLevelEXT = NULL;
OXR(xrGetInstanceProcAddr(
app->Instance,
"xrPerfSettingsSetPerformanceLevelEXT",
(PFN_xrVoidFunction*)(&pfnPerfSettingsSetPerformanceLevelEXT)));
OXR(pfnPerfSettingsSetPerformanceLevelEXT(
app->Session, XR_PERF_SETTINGS_DOMAIN_CPU_EXT, cpuPerfLevel));
OXR(pfnPerfSettingsSetPerformanceLevelEXT(
app->Session, XR_PERF_SETTINGS_DOMAIN_GPU_EXT, gpuPerfLevel));
PFN_xrSetAndroidApplicationThreadKHR pfnSetAndroidApplicationThreadKHR = NULL;
OXR(xrGetInstanceProcAddr(
app->Instance,
"xrSetAndroidApplicationThreadKHR",
(PFN_xrVoidFunction*)(&pfnSetAndroidApplicationThreadKHR)));
OXR(pfnSetAndroidApplicationThreadKHR(
app->Session, XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR, app->MainThreadTid));
OXR(pfnSetAndroidApplicationThreadKHR(
app->Session, XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR, app->RenderThreadTid));
}
} else if (state == XR_SESSION_STATE_STOPPING) {
assert(app->SessionActive);
OXR(xrEndSession(app->Session));
app->SessionActive = false;
}
}
GLboolean ovrApp_HandleXrEvents(ovrApp* app) {
XrEventDataBuffer eventDataBuffer = {};
GLboolean recenter = GL_FALSE;
// 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;
} }
// Set performance parameters once we have entered VR mode and have a valid ovrMobile. switch (baseEventHeader->type) {
if ( app->Ovr != NULL ) case XR_TYPE_EVENT_DATA_EVENTS_LOST:
{ ALOGV("xrPollEvent: received XR_TYPE_EVENT_DATA_EVENTS_LOST event");
//AmmarkoV : Set our refresh rate..! break;
ovrResult result = vrapi_SetDisplayRefreshRate(app->Ovr, REFRESH); case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: {
if (result == ovrSuccess) { ALOGV("Changed refresh rate. %f Hz", REFRESH); } else const XrEventDataInstanceLossPending* instance_loss_pending_event =
{ ALOGV("Failed to change refresh rate to 90Hz Result=%d",result); } (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_DISPLAY_REFRESH_RATE_CHANGED_FB: {
const XrEventDataDisplayRefreshRateChangedFB* refresh_rate_changed_event =
(XrEventDataDisplayRefreshRateChangedFB*)(baseEventHeader);
ALOGV(
"xrPollEvent: received XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB event: fromRate %f -> toRate %f",
refresh_rate_changed_event->fromDisplayRefreshRate,
refresh_rate_changed_event->toDisplayRefreshRate);
} 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 = GL_TRUE;
} 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));
vrapi_SetClockLevels( app->Ovr, app->CpuLevel, app->GpuLevel ); switch (session_state_changed_event->state) {
ALOGV( " vrapi_SetClockLevels( %d, %d )", app->CpuLevel, app->GpuLevel ); case XR_SESSION_STATE_FOCUSED:
app->Focused = true;
vrapi_SetExtraLatencyMode(app->Ovr, VRAPI_EXTRA_LATENCY_MODE_ON); break;
ALOGV( " vrapi_SetExtraLatencyMode( %d )", VRAPI_EXTRA_LATENCY_MODE_ON ); case XR_SESSION_STATE_VISIBLE:
app->Focused = false;
vrapi_SetPerfThread( app->Ovr, VRAPI_PERF_THREAD_TYPE_MAIN, app->MainThreadTid ); break;
case XR_SESSION_STATE_READY:
ALOGV( " vrapi_SetPerfThread( MAIN, %d )", app->MainThreadTid ); case XR_SESSION_STATE_STOPPING:
ovrApp_HandleSessionStateChanges(app, session_state_changed_event->state);
vrapi_SetPerfThread( app->Ovr, VRAPI_PERF_THREAD_TYPE_RENDERER, app->RenderThreadTid ); break;
default:
ALOGV( " vrapi_SetPerfThread( RENDERER, %d )", app->RenderThreadTid ); break;
} }
} } break;
} default:
else ALOGV("xrPollEvent: Unknown event");
{ break;
if ( app->Ovr != NULL )
{
ALOGV( " eglGetCurrentSurface( EGL_DRAW ) = %p", eglGetCurrentSurface( EGL_DRAW ) );
ALOGV( " vrapi_LeaveVrMode()" );
vrapi_LeaveVrMode( app->Ovr );
app->Ovr = NULL;
ALOGV( " eglGetCurrentSurface( EGL_DRAW ) = %p", eglGetCurrentSurface( EGL_DRAW ) );
} }
} }
return recenter;
} }
@ -1448,7 +1525,7 @@ void JKVR_processMessageQueue() {
case MESSAGE_ON_SURFACE_DESTROYED: { gAppState.NativeWindow = NULL; break; } case MESSAGE_ON_SURFACE_DESTROYED: { gAppState.NativeWindow = NULL; break; }
} }
ovrApp_HandleVrModeChanges( &gAppState ); ovrApp_HandleXrEvents(&gAppState);
} }
} }
@ -1492,6 +1569,226 @@ void GL_APIENTRYP VR_GLDebugLog(GLenum source,GLenum type,GLuint id,GLenum sever
} }
} }
void VR_GetResolution(int *pWidth, int *pHeight)
{
static int width = 0;
static int height = 0;
// Enumerate the viewport configurations.
uint32_t viewportConfigTypeCount = 0;
OXR(xrEnumerateViewConfigurations(
gAppState.Instance, gAppState.SystemId, 0, &viewportConfigTypeCount, NULL));
XrViewConfigurationType* viewportConfigurationTypes =
(XrViewConfigurationType*)malloc(viewportConfigTypeCount * sizeof(XrViewConfigurationType));
OXR(xrEnumerateViewConfigurations(
gAppState.Instance,
gAppState.SystemId,
viewportConfigTypeCount,
&viewportConfigTypeCount,
viewportConfigurationTypes));
ALOGV("Available Viewport Configuration Types: %d", viewportConfigTypeCount);
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" : "");
XrViewConfigurationProperties viewportConfig;
viewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
OXR(xrGetViewConfigurationProperties(
gAppState.Instance, gAppState.SystemId, viewportConfigType, &viewportConfig));
ALOGV(
"FovMutable=%s ConfigurationType %d",
viewportConfig.fovMutable ? "true" : "false",
viewportConfig.viewConfigurationType);
uint32_t viewCount;
OXR(xrEnumerateViewConfigurationViews(
gAppState.Instance, gAppState.SystemId, viewportConfigType, 0, &viewCount, NULL));
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;
}
OXR(xrEnumerateViewConfigurationViews(
gAppState.Instance,
gAppState.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++) {
gAppState.ViewConfigurationView[e] = elements[e];
}
}
free(elements);
} else {
ALOGE("Empty viewport configuration type: %d", viewCount);
}
}
free(viewportConfigurationTypes);
*pWidth = width = gAppState.ViewConfigurationView[0].recommendedImageRectWidth;
*pHeight = height = gAppState.ViewConfigurationView[0].recommendedImageRectHeight;
}
void VR_EnterVR( ) {
if (gAppState.Session) {
Com_Printf("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();
XrSessionCreateInfo sessionCreateInfo = {};
memset(&sessionCreateInfo, 0, sizeof(sessionCreateInfo));
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
sessionCreateInfo.next = &graphicsBindingAndroidGLES;
sessionCreateInfo.createFlags = 0;
sessionCreateInfo.systemId = gAppState.SystemId;
XrResult initResult;
OXR(initResult = xrCreateSession(gAppState.Instance, &sessionCreateInfo, &gAppState.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(gAppState.Session, &spaceCreateInfo, &gAppState.HeadSpace));
}
void VR_LeaveVR( ) {
if (gAppState.Session) {
OXR(xrDestroySpace(gAppState.HeadSpace));
// StageSpace is optional.
if (gAppState.StageSpace != XR_NULL_HANDLE) {
OXR(xrDestroySpace(gAppState.StageSpace));
}
OXR(xrDestroySpace(gAppState.FakeStageSpace));
gAppState.CurrentSpace = XR_NULL_HANDLE;
OXR(xrDestroySession(gAppState.Session));
gAppState.Session = NULL;
}
}
void VR_InitRenderer( ) {
int eyeW, eyeH;
VR_GetResolution(&eyeW, &eyeH);
// Get the viewport configuration info for the chosen viewport configuration type.
gAppState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
OXR(xrGetViewConfigurationProperties(
gAppState.Instance, gAppState.SystemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, &gAppState.ViewportConfig));
// Get the supported display refresh rates for the system.
{
PFN_xrEnumerateDisplayRefreshRatesFB pfnxrEnumerateDisplayRefreshRatesFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrEnumerateDisplayRefreshRatesFB",
(PFN_xrVoidFunction*)(&pfnxrEnumerateDisplayRefreshRatesFB)));
OXR(pfnxrEnumerateDisplayRefreshRatesFB(
gAppState.Session, 0, &gAppState.NumSupportedDisplayRefreshRates, NULL));
gAppState.SupportedDisplayRefreshRates =
(float*)malloc(gAppState.NumSupportedDisplayRefreshRates * sizeof(float));
OXR(pfnxrEnumerateDisplayRefreshRatesFB(
gAppState.Session,
gAppState.NumSupportedDisplayRefreshRates,
&gAppState.NumSupportedDisplayRefreshRates,
gAppState.SupportedDisplayRefreshRates));
ALOGV("Supported Refresh Rates:");
for (uint32_t i = 0; i < gAppState.NumSupportedDisplayRefreshRates; i++) {
ALOGV("%d:%f", i, gAppState.SupportedDisplayRefreshRates[i]);
}
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrGetDisplayRefreshRateFB",
(PFN_xrVoidFunction*)(&gAppState.pfnGetDisplayRefreshRate)));
float currentDisplayRefreshRate = 0.0f;
OXR(gAppState.pfnGetDisplayRefreshRate(gAppState.Session, &currentDisplayRefreshRate));
ALOGV("Current System Display Refresh Rate: %f", currentDisplayRefreshRate);
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrRequestDisplayRefreshRateFB",
(PFN_xrVoidFunction*)(&gAppState.pfnRequestDisplayRefreshRate)));
// Test requesting the system default.
OXR(gAppState.pfnRequestDisplayRefreshRate(gAppState.Session, 0.0f));
ALOGV("Requesting system default display refresh rate");
}
uint32_t numOutputSpaces = 0;
OXR(xrEnumerateReferenceSpaces(gAppState.Session, 0, &numOutputSpaces, NULL));
XrReferenceSpaceType* referenceSpaces =
(XrReferenceSpaceType*)malloc(numOutputSpaces * sizeof(XrReferenceSpaceType));
OXR(xrEnumerateReferenceSpaces(
gAppState.Session, numOutputSpaces, &numOutputSpaces, referenceSpaces));
for (uint32_t i = 0; i < numOutputSpaces; i++) {
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
stageSupported = GL_TRUE;
break;
}
}
free(referenceSpaces);
if (gAppState.CurrentSpace == XR_NULL_HANDLE) {
VR_Recenter(engine);
}
projections = (XrView*)(malloc(ovrMaxNumEyes * sizeof(XrView)));
ovrRenderer_Create(
gAppState.Session,
&gAppState.Renderer,
gAppState.ViewConfigurationView[0].recommendedImageRectWidth,
gAppState.ViewConfigurationView[0].recommendedImageRectHeight);
}
void VR_DestroyRenderer( )
{
ovrRenderer_Destroy(&gAppState.Renderer);
free(projections);
}
void * AppThreadFunction(void * parm ) { void * AppThreadFunction(void * parm ) {
gAppThread = (ovrAppThread *) parm; gAppThread = (ovrAppThread *) parm;
@ -1507,29 +1804,87 @@ void * AppThreadFunction(void * parm ) {
openjk_initialised = false; openjk_initialised = false;
vr_screen_dist = NULL; vr_screen_dist = NULL;
const ovrInitParms initParms = vrapi_DefaultInitParms(&java);
int32_t initResult = vrapi_Initialize(&initParms);
if (initResult != VRAPI_INITIALIZE_SUCCESS) {
// If intialization failed, vrapi_* function calls will not be available.
exit(0);
}
ovrApp_Clear(&gAppState); ovrApp_Clear(&gAppState);
gAppState.Java = java; gAppState.Java = java;
// This app will handle android gamepad events itself.
vrapi_SetPropertyInt(&gAppState.Java, VRAPI_EAT_NATIVE_GAMEPAD_EVENTS, 0); 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, "JKQUest");
appInfo.applicationVersion = 0;
strcpy(appInfo.engineName, "JKQuest");
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;
XrResult initResult;
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &gAppState.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(gAppState.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;
OXR(initResult = xrGetSystem(gAppState.Instance, &systemGetInfo, &gAppState.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)));
XrGraphicsRequirementsOpenGLESKHR graphicsRequirements = {};
graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(gAppState.Instance, gAppState.SystemId, &graphicsRequirements));
//Set device defaults //Set device defaults
if (vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_DEVICE_TYPE) == VRAPI_DEVICE_TYPE_OCULUSQUEST)
{
if (SS_MULTIPLIER == 0.0f)
{
SS_MULTIPLIER = 1.0f;
}
}
else if (vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_DEVICE_TYPE) == VRAPI_DEVICE_TYPE_OCULUSQUEST2)
{
if (SS_MULTIPLIER == 0.0f) if (SS_MULTIPLIER == 0.0f)
{ {
//GB Override as refresh is now 72 by default as we decided a higher res is better as 90hz has stutters //GB Override as refresh is now 72 by default as we decided a higher res is better as 90hz has stutters
@ -1539,13 +1894,9 @@ void * AppThreadFunction(void * parm ) {
{ {
SS_MULTIPLIER = 1.5f; SS_MULTIPLIER = 1.5f;
} }
} else {
//Don't know what headset this is!? abort
return NULL;
}
//Using a symmetrical render target //Using a symmetrical render target
m_height = m_width = (int)(vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH) * SS_MULTIPLIER); VR_GetResolution(m_height, m_width);
gAppState.CpuLevel = CPU_LEVEL; gAppState.CpuLevel = CPU_LEVEL;
gAppState.GpuLevel = GPU_LEVEL; gAppState.GpuLevel = GPU_LEVEL;
@ -1560,17 +1911,9 @@ void * AppThreadFunction(void * parm ) {
JKVR_processMessageQueue(); JKVR_processMessageQueue();
} }
#ifdef ENABLE_GL_DEBUG VR_EnterVR();
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(reinterpret_cast<GLDEBUGPROC>(VR_GLDebugLog), 0);
#endif
ovrRenderer_Create(m_width, m_height, &gAppState.Renderer, &java); ovrRenderer_Create(m_width, m_height, &gAppState.Renderer, &java);
if ( gAppState.Ovr == NULL )
{
return NULL;
}
// Create the scene if not yet created. // Create the scene if not yet created.
ovrScene_Create( m_width, m_height, &gAppState.Scene, &java ); ovrScene_Create( m_width, m_height, &gAppState.Scene, &java );
@ -1823,8 +2166,8 @@ void JKVR_getHMDOrientation() {//Get orientation
// We extract Yaw, Pitch, Roll instead of directly using the orientation // We extract Yaw, Pitch, Roll instead of directly using the orientation
// to allow "additional" yaw manipulation with mouse/controller. // to allow "additional" yaw manipulation with mouse/controller.
const ovrQuatf quatHmd = tracking.HeadPose.Pose.Orientation; const ovrQuatf quatHmd = tracking.Pose.orientation;
const ovrVector3f positionHmd = tracking.HeadPose.Pose.Position; const ovrVector3f positionHmd = tracking.Pose.position;
vec3_t rotation = {0, 0, 0}; vec3_t rotation = {0, 0, 0};
QuatToYawPitchRoll(quatHmd, rotation, vr.hmdorientation); QuatToYawPitchRoll(quatHmd, rotation, vr.hmdorientation);
setHMDPosition(positionHmd.x, positionHmd.y, positionHmd.z); setHMDPosition(positionHmd.x, positionHmd.y, positionHmd.z);
@ -1869,22 +2212,21 @@ void JKVR_getTrackedRemotesOrientation() {//Get info for tracked remotes
switch (vr_control_scheme->integer) switch (vr_control_scheme->integer)
{ {
case RIGHT_HANDED_DEFAULT: case RIGHT_HANDED_DEFAULT:
HandleInput_Default(&footTrackedRemoteState_new, &footTrackedRemoteState_old, HandleInput_Default(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new, &leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
ovrButton_A, ovrButton_B, ovrButton_X, ovrButton_Y); xrButton_A, xrButton_B, xrButton_X, xrButton_Y);
break; break;
case LEFT_HANDED_DEFAULT: case LEFT_HANDED_DEFAULT:
HandleInput_Default(&footTrackedRemoteState_new, &footTrackedRemoteState_old, HandleInput_Default(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new, &rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
ovrButton_X, ovrButton_Y, ovrButton_A, ovrButton_B); xrButton_X, xrButton_Y, xrButton_A, xrButton_B);
break; break;
case WEAPON_ALIGN: /* case WEAPON_ALIGN:
HandleInput_WeaponAlign(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new, HandleInput_WeaponAlign(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new, &leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
ovrButton_A, ovrButton_B, ovrButton_X, ovrButton_Y); xrButton_A, xrButton_B, xrButton_X, xrButton_Y);
break; break;
*/
} }
} }

View file

@ -1,7 +1,18 @@
#if !defined(vrcommon_h) #if !defined(vrcommon_h)
#define vrcommon_h #define vrcommon_h
#include <VrApi_Input.h> //OpenXR
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
#define XR_USE_PLATFORM_ANDROID 1
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <jni.h>
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#include <openxr/openxr_oculus.h>
#include <openxr/openxr_oculus_helpers.h>
#include <android/log.h> #include <android/log.h>
@ -25,23 +36,158 @@
#endif #endif
enum { ovrMaxLayerCount = 1 };
enum { ovrMaxNumEyes = 2 };
typedef enum xrButton_ {
xrButton_A = 0x00000001, // Set for trigger pulled on the Gear VR and Go Controllers
xrButton_B = 0x00000002,
xrButton_RThumb = 0x00000004,
xrButton_RShoulder = 0x00000008,
xrButton_X = 0x00000100,
xrButton_Y = 0x00000200,
xrButton_LThumb = 0x00000400,
xrButton_LShoulder = 0x00000800,
xrButton_Up = 0x00010000,
xrButton_Down = 0x00020000,
xrButton_Left = 0x00040000,
xrButton_Right = 0x00080000,
xrButton_Enter = 0x00100000,
xrButton_Back = 0x00200000,
xrButton_GripTrigger = 0x04000000,
xrButton_Trigger = 0x20000000,
xrButton_Joystick = 0x80000000,
xrButton_EnumSize = 0x7fffffff
} xrButton;
typedef struct ovrInputStateTrackedRemote_ {
uint32_t Buttons;
float IndexTrigger;
float GripTrigger;
XrVector2f Joystick;
} ovrInputStateTrackedRemote;
typedef struct {
GLboolean Active;
XrPosef Pose;
XrSpaceVelocity Velocity;
} ovrTrackedController;
typedef enum control_scheme { typedef enum control_scheme {
RIGHT_HANDED_DEFAULT = 0, RIGHT_HANDED_DEFAULT = 0,
LEFT_HANDED_DEFAULT = 10, LEFT_HANDED_DEFAULT = 10,
WEAPON_ALIGN = 99 WEAPON_ALIGN = 99
} control_scheme_t; } control_scheme_t;
typedef struct {
float M[4][4];
} ovrMatrix4f;
typedef struct {
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;
GLuint* DepthBuffers;
GLuint* FrameBuffers;
} ovrFramebuffer;
/*
================================================================================
ovrRenderer
================================================================================
*/
typedef struct
{
ovrFramebuffer FrameBuffer[ovrMaxNumEyes];
ovrMatrix4f ProjectionMatrix;
int NumBuffers;
} ovrRenderer;
/*
================================================================================
ovrApp
================================================================================
*/
typedef union {
XrCompositionLayerProjection Projection;
XrCompositionLayerCylinderKHR Cylinder;
} ovrCompositorLayer_Union;
#define GL(func) func;
#define OXR(func) func;
typedef struct
{
bool Resumed;
bool Focused;
XrInstance Instance;
XrSession Session;
XrViewConfigurationProperties ViewportConfig;
XrViewConfigurationView ViewConfigurationView[ovrMaxNumEyes];
XrSystemId SystemId;
XrSpace HeadSpace;
XrSpace StageSpace;
XrSpace FakeStageSpace;
XrSpace CurrentSpace;
GLboolean SessionActive;
float* SupportedDisplayRefreshRates;
uint32_t RequestedDisplayRefreshRateIndex;
uint32_t NumSupportedDisplayRefreshRates;
PFN_xrGetDisplayRefreshRateFB pfnGetDisplayRefreshRate;
PFN_xrRequestDisplayRefreshRateFB pfnRequestDisplayRefreshRate;
long long FrameIndex;
double DisplayTime;
int SwapInterval;
int CpuLevel;
int GpuLevel;
int MainThreadTid;
int RenderThreadTid;
ovrCompositorLayer_Union Layers[ovrMaxLayerCount];
int LayerCount;
ovrRenderer Renderer;
ovrTrackedController TrackedController[2];
} ovrApp;
extern bool openjk_initialised; extern bool openjk_initialised;
extern long long global_time; extern long long global_time;
extern ovrTracking2 tracking;
extern int ducked; extern int ducked;
extern vr_client_info_t vr; extern vr_client_info_t vr;
#define DUCK_NOTDUCKED 0 void ovrTrackedController_Clear(ovrTrackedController* controller);
#define DUCK_BUTTON 1
#define DUCK_CROUCHED 2
ovrMatrix4f ovrMatrix4f_Multiply(const ovrMatrix4f* a, const ovrMatrix4f* b);
ovrMatrix4f ovrMatrix4f_CreateRotation(const float radiansX, const float radiansY, const float radiansZ);
ovrMatrix4f ovrMatrix4f_CreateFromQuaternion(const XrQuaternionf* q);
ovrMatrix4f ovrMatrix4f_CreateProjectionFov(
const float fovDegreesX,
const float fovDegreesY,
const float offsetX,
const float offsetY,
const float nearZ,
const float farZ);
XrVector4f XrVector4f_MultiplyMatrix4f(const ovrMatrix4f* a, const XrVector4f* v);
float radians(float deg); float radians(float deg);
float degrees(float rad); float degrees(float rad);
@ -51,7 +197,7 @@ float length(float x, float y);
float nonLinearFilter(float in); float nonLinearFilter(float in);
bool between(float min, float val, float max); bool between(float min, float val, float max);
void rotateAboutOrigin(float v1, float v2, float rotation, vec2_t out); void rotateAboutOrigin(float v1, float v2, float rotation, vec2_t out);
void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out); void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out);
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key); void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key);
void interactWithTouchScreen(bool reset, ovrInputStateTrackedRemote *newState, ovrInputStateTrackedRemote *oldState); void interactWithTouchScreen(bool reset, ovrInputStateTrackedRemote *newState, ovrInputStateTrackedRemote *oldState);
int GetRefresh(); int GetRefresh();

View file

@ -14,52 +14,22 @@ Filename : VrCompositor.c
#include <android/log.h> #include <android/log.h>
#include <android/window.h> // for AWINDOW_FLAG_KEEP_SCREEN_ON #include <android/window.h> // for AWINDOW_FLAG_KEEP_SCREEN_ON
//OpenXR
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
#define XR_USE_PLATFORM_ANDROID 1
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GLES3/gl3ext.h> #include <GLES3/gl3ext.h>
#include <GLES/gl2ext.h> #include <jni.h>
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#include <openxr/openxr_oculus.h>
#include <VrApi.h> #include <openxr/openxr_oculus_helpers.h>
#include <VrApi_Helpers.h>
#include "VrCompositor.h" #include "VrCompositor.h"
/*
================================================================================
renderState
================================================================================
*/
void getCurrentRenderState( renderState * state)
{
state->VertexBuffer = 0;
state->IndexBuffer = 0;
state->VertexArrayObject = 0;
state->Program = 0;
glGetIntegerv(GL_ARRAY_BUFFER, &state->VertexBuffer );
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER, &state->IndexBuffer );
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &state->VertexArrayObject );
glGetIntegerv(GL_CURRENT_PROGRAM, &state->Program );
}
void restoreRenderState( renderState * state )
{
GL( glUseProgram( state->Program ) );
GL( glBindVertexArray( state->VertexArrayObject ) );
GL( glBindBuffer( GL_ARRAY_BUFFER, state->VertexBuffer ) );
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, state->IndexBuffer ) );
}
/* /*
================================================================================ ================================================================================
@ -82,7 +52,7 @@ bool ovrScene_IsCreated( ovrScene * scene )
return scene->CreatedScene; return scene->CreatedScene;
} }
void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * java ) void ovrScene_Create( int width, int height, ovrScene * scene )
{ {
// Create Cylinder renderer // Create Cylinder renderer
{ {
@ -90,7 +60,7 @@ void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * j
scene->CylinderHeight = height; scene->CylinderHeight = height;
//Create cylinder renderer //Create cylinder renderer
ovrRenderer_Create( width, height, &scene->CylinderRenderer, java ); ovrRenderer_Create( width, height, &scene->CylinderRenderer );
} }
scene->CreatedScene = true; scene->CreatedScene = true;

View file

@ -53,17 +53,6 @@ ovrFramebuffer
================================================================================ ================================================================================
*/ */
typedef struct
{
int Width;
int Height;
int Multisamples;
int TextureSwapChainLength;
int TextureSwapChainIndex;
ovrTextureSwapChain * ColorTextureSwapChain;
GLuint * DepthBuffers;
GLuint * FrameBuffers;
} ovrFramebuffer;
void ovrFramebuffer_SetCurrent( ovrFramebuffer * frameBuffer ); void ovrFramebuffer_SetCurrent( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_Destroy( ovrFramebuffer * frameBuffer ); void ovrFramebuffer_Destroy( ovrFramebuffer * frameBuffer );
@ -72,48 +61,32 @@ void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer ); void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer );
void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer ); void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer );
/*
================================================================================
ovrRenderer XrView* projections;
GLboolean stageSupported = GL_FALSE;
================================================================================ void VR_UpdateStageBounds(ovrApp* pappState) {
*/ XrExtent2Df stageBounds = {};
typedef struct XrResult result;
{ OXR(result = xrGetReferenceSpaceBoundsRect(
ovrFramebuffer FrameBuffer[VRAPI_FRAME_LAYER_EYE_MAX]; pappState->Session, XR_REFERENCE_SPACE_TYPE_STAGE, &stageBounds));
ovrMatrix4f ProjectionMatrix; if (result != XR_SUCCESS) {
int NumBuffers; ALOGV("Stage bounds query failed: using small defaults");
} ovrRenderer; stageBounds.width = 1.0f;
stageBounds.height = 1.0f;
pappState->CurrentSpace = pappState->FakeStageSpace;
}
ALOGV("Stage bounds: width = %f, depth %f", stageBounds.width, stageBounds.height);
}
void ovrRenderer_Clear( ovrRenderer * renderer ); void ovrRenderer_Clear( ovrRenderer * renderer );
void ovrRenderer_Create( int width, int height, ovrRenderer * renderer, const ovrJava * java ); void ovrRenderer_Create(XrSession session, int width, int height, ovrRenderer * renderer );
void ovrRenderer_Destroy( ovrRenderer * renderer ); void ovrRenderer_Destroy( ovrRenderer * renderer );
/*
================================================================================
renderState
================================================================================
*/
typedef struct
{
GLint VertexBuffer;
GLint IndexBuffer;
GLint VertexArrayObject;
GLint Program;
GLint VertexShader;
GLint FragmentShader;
} renderState;
void getCurrentRenderState( renderState * state);
void restoreRenderState( renderState * state );
/* /*
================================================================================ ================================================================================
@ -186,26 +159,8 @@ typedef struct
} ovrScene; } ovrScene;
void ovrScene_Clear( ovrScene * scene ); void ovrScene_Clear( ovrScene * scene );
void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * java ); void ovrScene_Create( int width, int height, ovrScene * scene );
void ovrScene_Destroy( ovrScene * scene ); void ovrScene_Destroy( ovrScene * scene );
/*
================================================================================
ovrRenderer
================================================================================
*/
ovrLayerProjection2 ovrRenderer_RenderGroundPlaneToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
const ovrScene * scene, const ovrTracking2 * tracking );
ovrLayerProjection2 ovrRenderer_RenderToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
const ovrTracking2 * tracking );
ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
const int textureWidth, const int textureHeight,
const ovrTracking2 * tracking, float rotateYaw );
;

View file

@ -6,15 +6,13 @@
#define STABILISATION_DISTANCE 0.28 #define STABILISATION_DISTANCE 0.28
extern ovrInputStateTrackedRemote leftTrackedRemoteState_old; extern ovrInputStateTrackedRemote leftTrackedRemoteState_old;
extern ovrInputStateTrackedRemote leftTrackedRemoteState_new; extern ovrInputStateTrackedRemote leftTrackedRemoteState_new;
extern ovrTracking leftRemoteTracking_new; extern ovrTrackedController leftRemoteTracking_new;
extern ovrInputStateTrackedRemote rightTrackedRemoteState_old; extern ovrInputStateTrackedRemote rightTrackedRemoteState_old;
extern ovrInputStateTrackedRemote rightTrackedRemoteState_new; extern ovrInputStateTrackedRemote rightTrackedRemoteState_new;
extern ovrTracking rightRemoteTracking_new; extern ovrTrackedController rightRemoteTracking_new;
extern ovrInputStateGamepad footTrackedRemoteState_old;
extern ovrInputStateGamepad footTrackedRemoteState_new;
extern ovrDeviceID controllerIDs[2];
extern float remote_movementSideways; extern float remote_movementSideways;
extern float remote_movementForward; extern float remote_movementForward;
@ -25,15 +23,12 @@ extern float positional_movementForward;
void sendButtonAction(const char* action, long buttonDown); void sendButtonAction(const char* action, long buttonDown);
void sendButtonActionSimple(const char* action); void sendButtonActionSimple(const char* action);
void acquireTrackedRemotesData(ovrMobile *Ovr, double displayTime); void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTrackedController* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTrackedController* pOffTracking,
void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld,
ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 ); int domButton1, int domButton2, int offButton1, int offButton2 );
void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking, void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTrackedController* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking, ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTrackedController* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 ); int domButton1, int domButton2, int offButton1, int offButton2 );

View file

@ -7,12 +7,6 @@ Authors : Simon Brown
*************************************************************************************/ *************************************************************************************/
#include <VrApi.h>
#include <VrApi_Helpers.h>
#include <VrApi_SystemUtils.h>
#include <VrApi_Input.h>
#include <VrApi_Types.h>
#include "VrInput.h" #include "VrInput.h"
#include <qcommon/qcommon.h> #include <qcommon/qcommon.h>
@ -45,13 +39,10 @@ cvar_t *vr_gesture_triggered_use_threshold;
ovrInputStateTrackedRemote leftTrackedRemoteState_old; ovrInputStateTrackedRemote leftTrackedRemoteState_old;
ovrInputStateTrackedRemote leftTrackedRemoteState_new; ovrInputStateTrackedRemote leftTrackedRemoteState_new;
ovrTracking leftRemoteTracking_new; ovrTrackedController leftRemoteTracking_new;
ovrInputStateTrackedRemote rightTrackedRemoteState_old; ovrInputStateTrackedRemote rightTrackedRemoteState_old;
ovrInputStateTrackedRemote rightTrackedRemoteState_new; ovrInputStateTrackedRemote rightTrackedRemoteState_new;
ovrTracking rightRemoteTracking_new; ovrTrackedController rightRemoteTracking_new;
ovrInputStateGamepad footTrackedRemoteState_old;
ovrInputStateGamepad footTrackedRemoteState_new;
ovrDeviceID controllerIDs[2];
float remote_movementSideways; float remote_movementSideways;
float remote_movementForward; float remote_movementForward;
@ -60,7 +51,6 @@ float positional_movementSideways;
float positional_movementForward; float positional_movementForward;
bool openjk_initialised; bool openjk_initialised;
long long global_time; long long global_time;
ovrTracking2 tracking;
int ducked; int ducked;
vr_client_info_t vr; vr_client_info_t vr;
@ -133,58 +123,6 @@ void sendButtonAction(const char* action, long buttonDown)
Cbuf_AddText( command ); Cbuf_AddText( command );
} }
void acquireTrackedRemotesData(ovrMobile *Ovr, double displayTime) {//The amount of yaw changed by controller
for ( uint32_t i = 0; ; i++ ) {
ovrInputCapabilityHeader cap;
ovrResult result = vrapi_EnumerateInputDevices(Ovr, i, &cap);
if (result < 0) {
break;
}
if (cap.Type == ovrControllerType_Gamepad) {
ovrInputGamepadCapabilities remoteCaps;
remoteCaps.Header = cap;
if (vrapi_GetInputDeviceCapabilities(Ovr, &remoteCaps.Header) >= 0) {
// remote is connected
ovrInputStateGamepad remoteState;
remoteState.Header.ControllerType = ovrControllerType_Gamepad;
if ( vrapi_GetCurrentInputState( Ovr, cap.DeviceID, &remoteState.Header ) >= 0 )
{
// act on device state returned in remoteState
footTrackedRemoteState_new = remoteState;
}
}
}
else if (cap.Type == ovrControllerType_TrackedRemote) {
ovrTracking remoteTracking;
ovrInputStateTrackedRemote trackedRemoteState;
trackedRemoteState.Header.ControllerType = ovrControllerType_TrackedRemote;
result = vrapi_GetCurrentInputState(Ovr, cap.DeviceID, &trackedRemoteState.Header);
if (result == ovrSuccess) {
ovrInputTrackedRemoteCapabilities remoteCapabilities;
remoteCapabilities.Header = cap;
result = vrapi_GetInputDeviceCapabilities(Ovr, &remoteCapabilities.Header);
result = vrapi_GetInputTrackingState(Ovr, cap.DeviceID, displayTime,
&remoteTracking);
if (remoteCapabilities.ControllerCapabilities & ovrControllerCaps_RightHand) {
rightTrackedRemoteState_new = trackedRemoteState;
rightRemoteTracking_new = remoteTracking;
controllerIDs[1] = cap.DeviceID;
} else{
leftTrackedRemoteState_new = trackedRemoteState;
leftRemoteTracking_new = remoteTracking;
controllerIDs[0] = cap.DeviceID;
}
}
}
}
}
void PortableMouseAbs(float x,float y); void PortableMouseAbs(float x,float y);
float clamp(float _min, float _val, float _max) float clamp(float _min, float _val, float _max)
{ {
@ -203,3 +141,194 @@ void interactWithTouchScreen(bool reset, ovrInputStateTrackedRemote *newState, o
PortableMouseAbs(cursorX, cursorY); PortableMouseAbs(cursorX, cursorY);
} }
/*
================================================================================
ovrMatrix4f
================================================================================
*/
ovrMatrix4f ovrMatrix4f_CreateProjectionFov(
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 tanAngleDown = tanf(angleDown);
const float tanAngleUp = tanf(angleUp);
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 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;
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[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[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;
}
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;
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[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;
}
/// 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];
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][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);
}
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;
}
/*
================================================================================
ovrTrackedController
================================================================================
*/
void ovrTrackedController_Clear(ovrTrackedController* controller) {
controller->Active = false;
controller->Pose = XrPosef_Identity();
}

View file

@ -7,12 +7,6 @@ Authors : Simon Brown
*************************************************************************************/ *************************************************************************************/
#include <VrApi.h>
#include <VrApi_Helpers.h>
#include <VrApi_SystemUtils.h>
#include <VrApi_Input.h>
#include <VrApi_Types.h>
#include <android/keycodes.h> #include <android/keycodes.h>
#include "VrInput.h" #include "VrInput.h"
@ -35,9 +29,8 @@ static inline float AngleBetweenVectors(const vec3_t a, const vec3_t b)
return degrees(acosf(DotProduct(a, b)/(VectorLength(a) * VectorLength(b)))); return degrees(acosf(DotProduct(a, b)/(VectorLength(a) * VectorLength(b))));
} }
void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld, void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTrackedController* pDominantTracking,
ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking, ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTrackedController* pOffTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 ) int domButton1, int domButton2, int offButton1, int offButton2 )
{ {
@ -50,12 +43,12 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
static bool canUseQuickSave = false; static bool canUseQuickSave = false;
//Need this for the touch screen //Need this for the touch screen
ovrTracking * pWeapon = pDominantTracking; ovrTrackedController * pWeapon = pDominantTracking;
ovrTracking * pOff = pOffTracking; ovrTrackedController * pOff = pOffTracking;
//All this to allow stick and button switching! //All this to allow stick and button switching!
ovrVector2f *pPrimaryJoystick; XrVector2f *pPrimaryJoystick;
ovrVector2f *pSecondaryJoystick; XrVector2f *pSecondaryJoystick;
uint32_t primaryButtonsNew; uint32_t primaryButtonsNew;
uint32_t primaryButtonsOld; uint32_t primaryButtonsOld;
uint32_t secondaryButtonsNew; uint32_t secondaryButtonsNew;
@ -64,8 +57,8 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
int primaryButton2; int primaryButton2;
int secondaryButton1; int secondaryButton1;
int secondaryButton2; int secondaryButton2;
int primaryThumb = (vr_control_scheme->integer == RIGHT_HANDED_DEFAULT || vr_switch_sticks->integer) ? ovrButton_RThumb : ovrButton_LThumb; int primaryThumb = (vr_control_scheme->integer == RIGHT_HANDED_DEFAULT || vr_switch_sticks->integer) ? xrButton_RThumb : xrButton_LThumb;
int secondaryThumb = (vr_control_scheme->integer == RIGHT_HANDED_DEFAULT || vr_switch_sticks->integer) ? ovrButton_LThumb : ovrButton_RThumb; int secondaryThumb = (vr_control_scheme->integer == RIGHT_HANDED_DEFAULT || vr_switch_sticks->integer) ? xrButton_LThumb : xrButton_RThumb;
if (vr_switch_sticks->integer) if (vr_switch_sticks->integer)
{ {
// //
@ -105,10 +98,10 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
//if we are in saber block debounce, don't update the angles //if we are in saber block debounce, don't update the angles
if (vr.saberBlockDebounce < cl.serverTime) { if (vr.saberBlockDebounce < cl.serverTime) {
rotation[PITCH] = 45; rotation[PITCH] = 45;
QuatToYawPitchRoll(pWeapon->HeadPose.Pose.Orientation, rotation, vr.weaponangles_saber); QuatToYawPitchRoll(pWeapon->Pose.orientation, rotation, vr.weaponangles_saber);
} }
rotation[PITCH] = vr_weapon_pitchadjust->value; rotation[PITCH] = vr_weapon_pitchadjust->value;
QuatToYawPitchRoll(pWeapon->HeadPose.Pose.Orientation, rotation, vr.weaponangles); QuatToYawPitchRoll(pWeapon->Pose.orientation, rotation, vr.weaponangles);
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta); VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
VectorCopy(vr.weaponangles, vr.weaponangles_last); VectorCopy(vr.weaponangles, vr.weaponangles_last);
@ -119,14 +112,14 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
//GB Also set offhand angles just in case we want to use those. //GB Also set offhand angles just in case we want to use those.
vec3_t rotation_off = {0}; vec3_t rotation_off = {0};
rotation_off[PITCH] = vr_weapon_pitchadjust->value; rotation_off[PITCH] = vr_weapon_pitchadjust->value;
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation_off, vr.offhandangles); QuatToYawPitchRoll(pOff->Pose.orientation, rotation_off, vr.offhandangles);
VectorSubtract(vr.offhandangles_last, vr.offhandangles, vr.offhandangles_delta); VectorSubtract(vr.offhandangles_last, vr.offhandangles, vr.offhandangles_delta);
VectorCopy(vr.offhandangles, vr.offhandangles_last); VectorCopy(vr.offhandangles, vr.offhandangles_last);
} }
//Menu button //Menu button
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, A_ESCAPE); handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, xrButton_Enter, A_ESCAPE);
static bool resetCursor = qtrue; static bool resetCursor = qtrue;
if ( JKVR_useScreenLayer() && !vr.misc_camera /*bit of a fiddle, but if we are in a misc camera, we are in the game and shouldn't be in here*/) if ( JKVR_useScreenLayer() && !vr.misc_camera /*bit of a fiddle, but if we are in a misc camera, we are in the game and shouldn't be in here*/)
@ -135,7 +128,7 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
resetCursor = qfalse; resetCursor = qfalse;
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, A_MOUSE1); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, A_MOUSE1);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, ovrButton_Trigger, A_MOUSE1); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, xrButton_Trigger, A_MOUSE1);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, A_ESCAPE); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, A_ESCAPE);
//To skip flatscreen cinematic //To skip flatscreen cinematic
@ -148,22 +141,22 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
{ {
resetCursor = qtrue; resetCursor = qtrue;
float distance = sqrtf(powf(pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x, 2) + float distance = sqrtf(powf(pOff->Pose.position.x - pWeapon->Pose.position.x, 2) +
powf(pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y, 2) + powf(pOff->Pose.position.y - pWeapon->Pose.position.y, 2) +
powf(pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z, 2)); powf(pOff->Pose.position.z - pWeapon->Pose.position.z, 2));
float distanceToHMD = sqrtf(powf(vr.hmdposition[0] - pWeapon->HeadPose.Pose.Position.x, 2) + float distanceToHMD = sqrtf(powf(vr.hmdposition[0] - pWeapon->Pose.position.x, 2) +
powf(vr.hmdposition[1] - pWeapon->HeadPose.Pose.Position.y, 2) + powf(vr.hmdposition[1] - pWeapon->Pose.position.y, 2) +
powf(vr.hmdposition[2] - pWeapon->HeadPose.Pose.Position.z, 2)); powf(vr.hmdposition[2] - pWeapon->Pose.position.z, 2));
float distanceToHMDOff = sqrtf(powf(vr.hmdposition[0] - pOff->HeadPose.Pose.Position.x, 2) + float distanceToHMDOff = sqrtf(powf(vr.hmdposition[0] - pOff->Pose.position.x, 2) +
powf(vr.hmdposition[1] - pOff->HeadPose.Pose.Position.y, 2) + powf(vr.hmdposition[1] - pOff->Pose.position.y, 2) +
powf(vr.hmdposition[2] - pOff->HeadPose.Pose.Position.z, 2)); powf(vr.hmdposition[2] - pOff->Pose.position.z, 2));
float controllerYawHeading = 0.0f; float controllerYawHeading = 0.0f;
//Turn on weapon stabilisation? //Turn on weapon stabilisation?
bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger); bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & xrButton_GripTrigger);
if (offhandGripPushed) if (offhandGripPushed)
{ {
if (!vr.weapon_stabilised && vr.item_selector == 0 && if (!vr.weapon_stabilised && vr.item_selector == 0 &&
@ -189,7 +182,7 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
} }
dominantGripPushed = (pDominantTrackedRemoteNew->Buttons & dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
ovrButton_GripTrigger) != 0; xrButton_GripTrigger) != 0;
//Do this early so we can suppress other button actions when item selector is up //Do this early so we can suppress other button actions when item selector is up
if (dominantGripPushed) { if (dominantGripPushed) {
@ -315,23 +308,23 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp; vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp;
if (vr.saberBlockDebounce < cl.serverTime) { if (vr.saberBlockDebounce < cl.serverTime) {
VectorSet(vr.weaponposition, pWeapon->HeadPose.Pose.Position.x, VectorSet(vr.weaponposition, pWeapon->Pose.position.x,
pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z); pWeapon->Pose.position.y, pWeapon->Pose.position.z);
///Weapon location relative to view ///Weapon location relative to view
VectorSet(vr.weaponoffset, pWeapon->HeadPose.Pose.Position.x, VectorSet(vr.weaponoffset, pWeapon->Pose.position.x,
pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z); pWeapon->Pose.position.y, pWeapon->Pose.position.z);
VectorSubtract(vr.weaponoffset, vr.hmdposition, vr.weaponoffset); VectorSubtract(vr.weaponoffset, vr.hmdposition, vr.weaponoffset);
vr.weaponoffset_timestamp = Sys_Milliseconds(); vr.weaponoffset_timestamp = Sys_Milliseconds();
} }
vec3_t velocity; vec3_t velocity;
VectorSet(velocity, pWeapon->HeadPose.LinearVelocity.x, VectorSet(velocity, pWeapon->Velocity.linearVelocity.x,
pWeapon->HeadPose.LinearVelocity.y, pWeapon->HeadPose.LinearVelocity.z); pWeapon->Velocity.linearVelocity.y, pWeapon->Velocity.linearVelocity.z);
vr.primaryswingvelocity = VectorLength(velocity); vr.primaryswingvelocity = VectorLength(velocity);
VectorSet(velocity, pOff->HeadPose.LinearVelocity.x, VectorSet(velocity, pOff->Velocity.linearVelocity.x,
pOff->HeadPose.LinearVelocity.y, pOff->HeadPose.LinearVelocity.z); pOff->Velocity.linearVelocity.y, pOff->Velocity.linearVelocity.z);
vr.secondaryswingvelocity = VectorLength(velocity); vr.secondaryswingvelocity = VectorLength(velocity);
@ -444,11 +437,11 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
else else
{ {
float x = float x =
pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x; pOff->Pose.position.x - pWeapon->Pose.position.x;
float y = float y =
pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y; pOff->Pose.position.y - pWeapon->Pose.position.y;
float z = float z =
pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z; pOff->Pose.position.z - pWeapon->Pose.position.z;
float zxDist = length(x, z); float zxDist = length(x, z);
if (zxDist != 0.0f && z != 0.0f) { if (zxDist != 0.0f && z != 0.0f) {
@ -466,9 +459,7 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0; float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0;
static vec3_t downVector = {0.0, 0.0, -1.0}; static vec3_t downVector = {0.0, 0.0, -1.0};
bool bpTrackOk = pOffTracking->Status & if ((bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <=
VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked
if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <=
0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range 0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range
&& (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <= && (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <=
0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range 0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range
@ -497,16 +488,16 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
{ {
VectorCopy(vr.offhandposition[i-1], vr.offhandposition[i]); VectorCopy(vr.offhandposition[i-1], vr.offhandposition[i]);
} }
vr.offhandposition[0][0] = pOff->HeadPose.Pose.Position.x; vr.offhandposition[0][0] = pOff->Pose.position.x;
vr.offhandposition[0][1] = pOff->HeadPose.Pose.Position.y; vr.offhandposition[0][1] = pOff->Pose.position.y;
vr.offhandposition[0][2] = pOff->HeadPose.Pose.Position.z; vr.offhandposition[0][2] = pOff->Pose.position.z;
vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0]; vr.offhandoffset[0] = pOff->Pose.position.x - vr.hmdposition[0];
vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1]; vr.offhandoffset[1] = pOff->Pose.position.y - vr.hmdposition[1];
vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2]; vr.offhandoffset[2] = pOff->Pose.position.z - vr.hmdposition[2];
vec3_t rotation = {0}; vec3_t rotation = {0};
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles); QuatToYawPitchRoll(pOff->Pose.orientation, rotation, vr.offhandangles);
if (vr_walkdirection->value == 0) { if (vr_walkdirection->value == 0) {
controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW]; controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW];
@ -521,7 +512,7 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
vec3_t offhandForwardXY = {}; vec3_t offhandForwardXY = {};
float hmdToOffhandDotProduct = 0; float hmdToOffhandDotProduct = 0;
float offhandToDownAngle = 0; float offhandToDownAngle = 0;
if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 && if ((bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 &&
distanceToHMDOff <= distanceToHMDOff <=
0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range 0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range
&& (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <= && (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <=
@ -641,11 +632,11 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
previous_throwing = throwing; previous_throwing = throwing;
if (!throwing && if (!throwing &&
vr.primaryVelocityTriggeredAttack && vr.primaryVelocityTriggeredAttack &&
(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) (pDominantTrackedRemoteNew->Buttons & xrButton_Trigger))
{ {
throwing = true; throwing = true;
} }
else if (throwing && !(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) else if (throwing && !(pDominantTrackedRemoteNew->Buttons & xrButton_Trigger))
{ {
throwing = false; throwing = false;
} }
@ -657,10 +648,10 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
else if (!vr.velocitytriggered) // Don't fire velocity triggered weapons else if (!vr.velocitytriggered) // Don't fire velocity triggered weapons
{ {
//Fire Primary - Doesn't trigger the saber //Fire Primary - Doesn't trigger the saber
if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != if ((pDominantTrackedRemoteNew->Buttons & xrButton_Trigger) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) { (pDominantTrackedRemoteOld->Buttons & xrButton_Trigger)) {
firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) && firing = (pDominantTrackedRemoteNew->Buttons & xrButton_Trigger) &&
!vr.item_selector; !vr.item_selector;
sendButtonAction("+attack", firing); sendButtonAction("+attack", firing);
} }
@ -706,8 +697,8 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
//Apply a filter and quadratic scaler so small movements are easier to make //Apply a filter and quadratic scaler so small movements are easier to make
float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y); float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y);
float nlf = nonLinearFilter(dist); float nlf = nonLinearFilter(dist);
float x = (nlf * pSecondaryJoystick->x) + pFootTrackingNew->LeftJoystick.x; float x = (nlf * pSecondaryJoystick->x);
float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y; float y = (nlf * pSecondaryJoystick->y);
vr.player_moving = (fabs(x) + fabs(y)) > 0.05f; vr.player_moving = (fabs(x) + fabs(y)) > 0.05f;
@ -745,10 +736,10 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG
//Use Force - off hand trigger //Use Force - off hand trigger
{ {
if ((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) != if ((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) !=
(pOffTrackedRemoteOld->Buttons & ovrButton_Trigger)) (pOffTrackedRemoteOld->Buttons & xrButton_Trigger))
{ {
sendButtonAction("+useforce", (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger)); sendButtonAction("+useforce", (pOffTrackedRemoteNew->Buttons & xrButton_Trigger));
} }
} }

View file

@ -23,8 +23,8 @@ cvar_t *sv_cheats;
void CG_CenterPrint( const char *str, int y, int charWidth ); void CG_CenterPrint( const char *str, int y, int charWidth );
void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking, void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTrackedController* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking, ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTrackedController* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 ) int domButton1, int domButton2, int offButton1, int offButton2 )
{ {
@ -49,9 +49,9 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
//Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick //Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick
vec3_t rotation = {0}; vec3_t rotation = {0};
rotation[PITCH] = 10; rotation[PITCH] = 10;
QuatToYawPitchRoll(pDominantTracking->HeadPose.Pose.Orientation, rotation, vr.weaponangles_saber); QuatToYawPitchRoll(pDominantTracking->Pose.orientation, rotation, vr.weaponangles_saber);
rotation[PITCH] = vr_weapon_pitchadjust->value; rotation[PITCH] = vr_weapon_pitchadjust->value;
QuatToYawPitchRoll(pDominantTracking->HeadPose.Pose.Orientation, rotation, vr.weaponangles); QuatToYawPitchRoll(pDominantTracking->Pose.orientation, rotation, vr.weaponangles);
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta); VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
VectorCopy(vr.weaponangles, vr.weaponangles_last); VectorCopy(vr.weaponangles, vr.weaponangles_last);
@ -62,7 +62,7 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
} }
//Menu button //Menu button
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, A_ESCAPE); handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, xrButton_Enter, A_ESCAPE);
static bool resetCursor = qtrue; static bool resetCursor = qtrue;
if ( JKVR_useScreenLayer() ) if ( JKVR_useScreenLayer() )
@ -71,7 +71,7 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
resetCursor = qfalse; resetCursor = qfalse;
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, A_MOUSE1); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, A_MOUSE1);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, ovrButton_Trigger, A_MOUSE1); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, xrButton_Trigger, A_MOUSE1);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, A_ESCAPE); handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, A_ESCAPE);
} }
else else
@ -80,36 +80,36 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
//dominant hand stuff first //dominant hand stuff first
{ {
vr.weaponposition[0] = pDominantTracking->HeadPose.Pose.Position.x; vr.weaponposition[0] = pDominantTracking->Pose.position.x;
vr.weaponposition[1] = pDominantTracking->HeadPose.Pose.Position.y; vr.weaponposition[1] = pDominantTracking->Pose.position.y;
vr.weaponposition[2] = pDominantTracking->HeadPose.Pose.Position.z; vr.weaponposition[2] = pDominantTracking->Pose.position.z;
///Weapon location relative to view ///Weapon location relative to view
vr.weaponoffset[0] = pDominantTracking->HeadPose.Pose.Position.x - vr.hmdposition[0]; vr.weaponoffset[0] = pDominantTracking->Pose.position.x - vr.hmdposition[0];
vr.weaponoffset[1] = pDominantTracking->HeadPose.Pose.Position.y - vr.hmdposition[1]; vr.weaponoffset[1] = pDominantTracking->Pose.position.y - vr.hmdposition[1];
vr.weaponoffset[2] = pDominantTracking->HeadPose.Pose.Position.z - vr.hmdposition[2]; vr.weaponoffset[2] = pDominantTracking->Pose.position.z - vr.hmdposition[2];
vr.weaponoffset_timestamp = Sys_Milliseconds( ); vr.weaponoffset_timestamp = Sys_Milliseconds( );
} }
float controllerYawHeading = 0.0f; float controllerYawHeading = 0.0f;
//off-hand stuff //off-hand stuff
{ {
vr.offhandposition[0][0] = pOffTracking->HeadPose.Pose.Position.x; vr.offhandposition[0][0] = pOffTracking->Pose.position.x;
vr.offhandposition[0][1] = pOffTracking->HeadPose.Pose.Position.y; vr.offhandposition[0][1] = pOffTracking->Pose.position.y;
vr.offhandposition[0][2] = pOffTracking->HeadPose.Pose.Position.z; vr.offhandposition[0][2] = pOffTracking->Pose.position.z;
vr.offhandoffset[0] = pOffTracking->HeadPose.Pose.Position.x - vr.hmdposition[0]; vr.offhandoffset[0] = pOffTracking->Pose.position.x - vr.hmdposition[0];
vr.offhandoffset[1] = pOffTracking->HeadPose.Pose.Position.y - vr.hmdposition[1]; vr.offhandoffset[1] = pOffTracking->Pose.position.y - vr.hmdposition[1];
vr.offhandoffset[2] = pOffTracking->HeadPose.Pose.Position.z - vr.hmdposition[2]; vr.offhandoffset[2] = pOffTracking->Pose.position.z - vr.hmdposition[2];
vec3_t rotation = {0}; vec3_t rotation = {0};
QuatToYawPitchRoll(pOffTracking->HeadPose.Pose.Orientation, rotation, vr.offhandangles); QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, vr.offhandangles);
} }
ALOGV(" Right-Controller-Position: %f, %f, %f", ALOGV(" Right-Controller-Position: %f, %f, %f",
pDominantTracking->HeadPose.Pose.Position.x, pDominantTracking->Pose.position.x,
pDominantTracking->HeadPose.Pose.Position.y, pDominantTracking->Pose.position.y,
pDominantTracking->HeadPose.Pose.Position.z); pDominantTracking->Pose.position.z);
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the //This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
//player is facing for positional tracking //player is facing for positional tracking
@ -124,16 +124,16 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
positional_movementForward); positional_movementForward);
dominantGripPushed = (pDominantTrackedRemoteNew->Buttons & dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
ovrButton_GripTrigger) != 0; xrButton_GripTrigger) != 0;
//We need to record if we have started firing primary so that releasing trigger will stop firing, if user has pushed grip //We need to record if we have started firing primary so that releasing trigger will stop firing, if user has pushed grip
//in meantime, then it wouldn't stop the gun firing and it would get stuck //in meantime, then it wouldn't stop the gun firing and it would get stuck
if (dominantGripPushed) if (dominantGripPushed)
{ {
//Fire Secondary //Fire Secondary
if (((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != if (((pDominantTrackedRemoteNew->Buttons & xrButton_Trigger) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) (pDominantTrackedRemoteOld->Buttons & xrButton_Trigger))
&& (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) && (pDominantTrackedRemoteNew->Buttons & xrButton_Trigger))
{ {
sendButtonActionSimple("weapalt"); sendButtonActionSimple("weapalt");
} }
@ -142,15 +142,15 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
{ {
//Fire Primary //Fire Primary
if (!vr.velocitytriggered && // Don't fire velocity triggered weapons if (!vr.velocitytriggered && // Don't fire velocity triggered weapons
(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != (pDominantTrackedRemoteNew->Buttons & xrButton_Trigger) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) { (pDominantTrackedRemoteOld->Buttons & xrButton_Trigger)) {
sendButtonAction("+attack", (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)); sendButtonAction("+attack", (pDominantTrackedRemoteNew->Buttons & xrButton_Trigger));
} }
} }
bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger); bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & xrButton_GripTrigger);
if ( (offhandGripPushed != (pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) && if ( (offhandGripPushed != (pOffTrackedRemoteOld->Buttons & xrButton_GripTrigger)) &&
offhandGripPushed) offhandGripPushed)
#ifndef DEBUG #ifndef DEBUG
{ {
@ -218,9 +218,9 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
itemSwitched = false; itemSwitched = false;
} }
if (((pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick) != if (((pDominantTrackedRemoteNew->Buttons & xrButton_Joystick) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick)) && (pDominantTrackedRemoteOld->Buttons & xrButton_Joystick)) &&
(pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick)) (pDominantTrackedRemoteOld->Buttons & xrButton_Joystick))
{ {
*(items[item_index]) = 0.0; *(items[item_index]) = 0.0;
} }

View file

@ -11,6 +11,8 @@ JK3_BASE_LDLIBS =
JK3_BASE_LDLIBS += -Wl JK3_BASE_LDLIBS += -Wl
JK3_BASE_C_INCLUDES := $(OPENJK_PATH)/lib $(JK3_CODE_PATH)/client $(JK3_CODE_PATH)/server $(JK3_CODE_PATH)/libs/freetype2/include $(JK3_CODE_PATH)/common $(JK3_CODE_PATH)/gl JK3_BASE_C_INCLUDES := $(OPENJK_PATH)/lib $(JK3_CODE_PATH)/client $(JK3_CODE_PATH)/server $(JK3_CODE_PATH)/libs/freetype2/include $(JK3_CODE_PATH)/common $(JK3_CODE_PATH)/gl
JK3_BASE_C_INCLUDES += $(LOCAL_PATH)/../../../../../../OpenXR/Include
JK3_BASE_C_INCLUDES += $(LOCAL_PATH)/../../../../../../3rdParty/khronos/openxr/OpenXR-SDK/include
JK3_BASE_C_INCLUDES += $(JK3_CODE_PATH)/ $(OPENJK_PATH)/code/ $(OPENJK_PATH)/shared/ $(JK3_CODE_PATH)/ui $(OPENJK_PATH)/lib/gsl-lite/include JK3_BASE_C_INCLUDES += $(JK3_CODE_PATH)/ $(OPENJK_PATH)/code/ $(OPENJK_PATH)/shared/ $(JK3_CODE_PATH)/ui $(OPENJK_PATH)/lib/gsl-lite/include
# Jedi Outcast # Jedi Outcast

View file

@ -20,7 +20,7 @@ LOCAL_LDLIBS += -lGLESv3 -landroid -lEGL -llog -lz -lOpenSLES
LOCAL_LDLIBS += -fuse-ld=bfd LOCAL_LDLIBS += -fuse-ld=bfd
LOCAL_STATIC_LIBRARIES := sigc libzip libpng libminizip LOCAL_STATIC_LIBRARIES := sigc libzip libpng libminizip
LOCAL_SHARED_LIBRARIES := vrapi gl4es LOCAL_SHARED_LIBRARIES := openxr_loader gl4es
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
@ -124,11 +124,11 @@ JK3_SRC = \
JKVR_SRC_FILES := ${TOP_DIR}/JKVR/JKVR_SurfaceView.cpp \ JKVR_SRC_FILES := ${TOP_DIR}/JKVR/JKVR_SurfaceView.cpp \
${TOP_DIR}/JKVR/VrCompositor.cpp \
${TOP_DIR}/JKVR/VrInputCommon.cpp \ ${TOP_DIR}/JKVR/VrInputCommon.cpp \
${TOP_DIR}/JKVR/VrInputWeaponAlign.cpp \
${TOP_DIR}/JKVR/VrInputDefault.cpp \ ${TOP_DIR}/JKVR/VrInputDefault.cpp \
${TOP_DIR}/JKVR/argtable3.c ${TOP_DIR}/JKVR/argtable3.c
# ${TOP_DIR}/JKVR/VrCompositor.cpp \
# ${TOP_DIR}/JKVR/VrInputWeaponAlign.cpp \
LOCAL_SRC_FILES += $(JK3_SRC) $(JKVR_SRC_FILES) LOCAL_SRC_FILES += $(JK3_SRC) $(JKVR_SRC_FILES)
@ -137,7 +137,7 @@ include $(BUILD_SHARED_LIBRARY)
$(call import-module,VrApi/Projects/AndroidPrebuilt/jni) $(call import-module,OpenXR/Projects/AndroidPrebuilt/jni)

View file

@ -20,7 +20,7 @@ LOCAL_LDLIBS += -lGLESv3 -landroid -lEGL -llog -lz -lOpenSLES
LOCAL_LDLIBS += -fuse-ld=bfd LOCAL_LDLIBS += -fuse-ld=bfd
LOCAL_STATIC_LIBRARIES := sigc libzip libpng libminizip LOCAL_STATIC_LIBRARIES := sigc libzip libpng libminizip
LOCAL_SHARED_LIBRARIES := vrapi gl4es LOCAL_SHARED_LIBRARIES := openxr_loader gl4es
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
@ -124,11 +124,11 @@ JK3_SRC = \
JKVR_SRC_FILES := ${TOP_DIR}/JKVR/JKVR_SurfaceView.cpp \ JKVR_SRC_FILES := ${TOP_DIR}/JKVR/JKVR_SurfaceView.cpp \
${TOP_DIR}/JKVR/VrCompositor.cpp \
${TOP_DIR}/JKVR/VrInputCommon.cpp \ ${TOP_DIR}/JKVR/VrInputCommon.cpp \
${TOP_DIR}/JKVR/VrInputWeaponAlign.cpp \
${TOP_DIR}/JKVR/VrInputDefault.cpp \ ${TOP_DIR}/JKVR/VrInputDefault.cpp \
${TOP_DIR}/JKVR/argtable3.c ${TOP_DIR}/JKVR/argtable3.c
# ${TOP_DIR}/JKVR/VrCompositor.cpp \
# ${TOP_DIR}/JKVR/VrInputWeaponAlign.cpp \
LOCAL_SRC_FILES += $(JK3_SRC) $(JKVR_SRC_FILES) LOCAL_SRC_FILES += $(JK3_SRC) $(JKVR_SRC_FILES)
@ -137,7 +137,7 @@ include $(BUILD_SHARED_LIBRARY)
$(call import-module,VrApi/Projects/AndroidPrebuilt/jni) $(call import-module,OpenXR/Projects/AndroidPrebuilt/jni)

View file

@ -1,4 +1,4 @@
rootProject.projectDir = new File(settingsDir, '../../../..') rootProject.projectDir = new File(settingsDir, '../../../..')
rootProject.name = "JKQuest" rootProject.name = "JKQuest"
include ':', 'VrSamples:JKQuest:Projects:Android' include ':', ':XrSamples:JKQuest:Projects:Android'

View file

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":VrSamples:JKQuest" <module external.linked.project.id=":XrSamples:JKQuest"
external.linked.project.path="$MODULE_DIR$" external.linked.project.path="$MODULE_DIR$"
external.root.project.path="$MODULE_DIR$/Projects/Android" external.root.project.path="$MODULE_DIR$/Projects/Android"
external.system.id="GRADLE" external.system.id="GRADLE"
external.system.module.group="JKQuest.VrSamples" external.system.module.group="JKQuest.XrSamples"
external.system.module.version="unspecified" external.system.module.version="unspecified"
type="JAVA_MODULE" version="4"> type="JAVA_MODULE" version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle"> <facet type="android-gradle" name="Android-Gradle">
<configuration> <configuration>
<option name="GRADLE_PROJECT_PATH" value=":VrSamples:JKQuest" /> <option name="GRADLE_PROJECT_PATH" value=":XrSamples:JKQuest" />
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" /> <option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" />
<option name="LAST_KNOWN_AGP_VERSION" /> <option name="LAST_KNOWN_AGP_VERSION" />
</configuration> </configuration>