mirror of
https://github.com/DrBeef/JKXR.git
synced 2024-11-25 05:21:00 +00:00
We have visuals!!
OpenXR is now at least rendering the menu screen!
This commit is contained in:
parent
6a61f24048
commit
2c00a2a40f
10 changed files with 1092 additions and 524 deletions
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,8 @@ typedef struct {
|
|||
|
||||
bool using_screen_layer;
|
||||
bool third_person;
|
||||
float fov;
|
||||
float fov_x;
|
||||
float fov_y;
|
||||
bool immersive_cinematics;
|
||||
bool weapon_stabilised;
|
||||
bool right_handed;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <openxr/openxr_oculus.h>
|
||||
#include <openxr/openxr_oculus_helpers.h>
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#include "../qcommon/q_shared.h"
|
||||
|
@ -35,6 +36,30 @@
|
|||
#define ALOGV(...)
|
||||
#endif
|
||||
|
||||
extern XrPath leftHandPath;
|
||||
extern XrPath rightHandPath;
|
||||
extern XrAction handPoseLeftAction;
|
||||
extern XrAction handPoseRightAction;
|
||||
extern XrAction indexLeftAction;
|
||||
extern XrAction indexRightAction;
|
||||
extern XrAction menuAction;
|
||||
extern XrAction buttonAAction;
|
||||
extern XrAction buttonBAction;
|
||||
extern XrAction buttonXAction;
|
||||
extern XrAction buttonYAction;
|
||||
extern XrAction gripLeftAction;
|
||||
extern XrAction gripRightAction;
|
||||
extern XrAction moveOnLeftJoystickAction;
|
||||
extern XrAction moveOnRightJoystickAction;
|
||||
extern XrAction thumbstickLeftClickAction;
|
||||
extern XrAction thumbstickRightClickAction;
|
||||
extern XrAction vibrateLeftFeedback;
|
||||
extern XrAction vibrateRightFeedback;
|
||||
extern XrActionSet runningActionSet;
|
||||
extern XrSpace leftControllerAimSpace;
|
||||
extern XrSpace rightControllerAimSpace;
|
||||
extern qboolean inputInitialized;
|
||||
extern qboolean useSimpleProfile;
|
||||
|
||||
enum { ovrMaxLayerCount = 1 };
|
||||
enum { ovrMaxNumEyes = 2 };
|
||||
|
@ -93,6 +118,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
int Width;
|
||||
int Height;
|
||||
int Multisamples;
|
||||
uint32_t TextureSwapChainLength;
|
||||
uint32_t TextureSwapChainIndex;
|
||||
ovrSwapChain ColorSwapChain;
|
||||
|
@ -131,10 +157,53 @@ typedef union {
|
|||
} ovrCompositorLayer_Union;
|
||||
|
||||
#define GL(func) func;
|
||||
#define OXR(func) func;
|
||||
|
||||
// Forward declarations
|
||||
XrInstance ovrApp_GetInstance();
|
||||
|
||||
#if defined(DEBUG)
|
||||
static void
|
||||
OXR_CheckErrors(XrInstance instance, XrResult result, const char* function, bool failOnError) {
|
||||
if (XR_FAILED(result)) {
|
||||
char errorBuffer[XR_MAX_RESULT_STRING_SIZE];
|
||||
xrResultToString(instance, result, errorBuffer);
|
||||
if (failOnError) {
|
||||
ALOGE("OpenXR error: %s: %s\n", function, errorBuffer);
|
||||
} else {
|
||||
ALOGV("OpenXR error: %s: %s\n", function, errorBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define OXR(func) OXR_CheckErrors(ovrApp_GetInstance(), func, #func, true);
|
||||
#else
|
||||
#define OXR(func) OXR_CheckErrors(ovrApp_GetInstance(), func, #func, false);
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
EGLint MajorVersion;
|
||||
EGLint MinorVersion;
|
||||
EGLDisplay Display;
|
||||
EGLConfig Config;
|
||||
EGLSurface TinySurface;
|
||||
EGLSurface MainSurface;
|
||||
EGLContext Context;
|
||||
} ovrEgl;
|
||||
|
||||
/// Java details about an activity
|
||||
typedef struct ovrJava_ {
|
||||
JavaVM* Vm; //< Java Virtual Machine
|
||||
JNIEnv* Env; //< Thread specific environment
|
||||
jobject ActivityObject; //< Java activity object
|
||||
} ovrJava;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ovrJava Java;
|
||||
ovrEgl Egl;
|
||||
ANativeWindow* NativeWindow;
|
||||
bool Resumed;
|
||||
bool Focused;
|
||||
|
||||
|
@ -148,15 +217,17 @@ typedef struct
|
|||
XrSpace FakeStageSpace;
|
||||
XrSpace CurrentSpace;
|
||||
GLboolean SessionActive;
|
||||
XrPosef xfStageFromHead;
|
||||
|
||||
float currentDisplayRefreshRate;
|
||||
float* SupportedDisplayRefreshRates;
|
||||
uint32_t RequestedDisplayRefreshRateIndex;
|
||||
uint32_t NumSupportedDisplayRefreshRates;
|
||||
PFN_xrGetDisplayRefreshRateFB pfnGetDisplayRefreshRate;
|
||||
PFN_xrRequestDisplayRefreshRateFB pfnRequestDisplayRefreshRate;
|
||||
|
||||
XrTime PredictedDisplayTime;
|
||||
long long FrameIndex;
|
||||
double DisplayTime;
|
||||
int SwapInterval;
|
||||
int CpuLevel;
|
||||
int GpuLevel;
|
||||
|
@ -202,9 +273,14 @@ void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteSta
|
|||
void interactWithTouchScreen(bool reset, ovrInputStateTrackedRemote *newState, ovrInputStateTrackedRemote *oldState);
|
||||
int GetRefresh();
|
||||
|
||||
//XrAction stuff
|
||||
bool ActionPoseIsActive(XrAction action, XrPath subactionPath);
|
||||
void VR_Recenter();
|
||||
|
||||
//Called from engine code
|
||||
bool JKVR_useScreenLayer();
|
||||
void JKVR_GetScreenRes(int *width, int *height);
|
||||
void JKVR_InitActions( void );
|
||||
void JKVR_Vibrate(int duration, int channel, float intensity );
|
||||
void JKVR_Haptic(int duration, int channel, float intensity, char *description, float yaw, float height);
|
||||
void JKVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
|
||||
|
@ -217,9 +293,8 @@ void JKVR_processMessageQueue();
|
|||
void JKVR_FrameSetup();
|
||||
void JKVR_setUseScreenLayer(bool use);
|
||||
void JKVR_processHaptics();
|
||||
void JKVR_getHMDOrientation();
|
||||
void JKVR_getHMDOrientation( );
|
||||
void JKVR_getTrackedRemotesOrientation();
|
||||
void JKVR_incrementFrameIndex();
|
||||
|
||||
bool JKVR_useScreenLayer();
|
||||
void JKVR_prepareEyeBuffer(int eye );
|
||||
|
|
|
@ -62,26 +62,6 @@ void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer );
|
|||
void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer );
|
||||
|
||||
|
||||
XrView* projections;
|
||||
GLboolean stageSupported = GL_FALSE;
|
||||
|
||||
void VR_UpdateStageBounds(ovrApp* pappState) {
|
||||
XrExtent2Df stageBounds = {};
|
||||
|
||||
XrResult result;
|
||||
OXR(result = xrGetReferenceSpaceBoundsRect(
|
||||
pappState->Session, XR_REFERENCE_SPACE_TYPE_STAGE, &stageBounds));
|
||||
if (result != XR_SUCCESS) {
|
||||
ALOGV("Stage bounds query failed: using small defaults");
|
||||
stageBounds.width = 1.0f;
|
||||
stageBounds.height = 1.0f;
|
||||
|
||||
pappState->CurrentSpace = pappState->FakeStageSpace;
|
||||
}
|
||||
|
||||
ALOGV("Stage bounds: width = %f, depth %f", stageBounds.width, stageBounds.height);
|
||||
}
|
||||
|
||||
void ovrRenderer_Clear( ovrRenderer * renderer );
|
||||
void ovrRenderer_Create(XrSession session, int width, int height, ovrRenderer * renderer );
|
||||
void ovrRenderer_Destroy( ovrRenderer * renderer );
|
||||
|
|
|
@ -54,6 +54,407 @@ long long global_time;
|
|||
int ducked;
|
||||
vr_client_info_t vr;
|
||||
|
||||
extern ovrApp gAppState;
|
||||
|
||||
//OpenXR
|
||||
XrPath leftHandPath;
|
||||
XrPath rightHandPath;
|
||||
XrAction handPoseLeftAction;
|
||||
XrAction handPoseRightAction;
|
||||
XrAction indexLeftAction;
|
||||
XrAction indexRightAction;
|
||||
XrAction menuAction;
|
||||
XrAction buttonAAction;
|
||||
XrAction buttonBAction;
|
||||
XrAction buttonXAction;
|
||||
XrAction buttonYAction;
|
||||
XrAction gripLeftAction;
|
||||
XrAction gripRightAction;
|
||||
XrAction moveOnLeftJoystickAction;
|
||||
XrAction moveOnRightJoystickAction;
|
||||
XrAction thumbstickLeftClickAction;
|
||||
XrAction thumbstickRightClickAction;
|
||||
XrAction vibrateLeftFeedback;
|
||||
XrAction vibrateRightFeedback;
|
||||
XrActionSet runningActionSet;
|
||||
XrSpace leftControllerAimSpace = XR_NULL_HANDLE;
|
||||
XrSpace rightControllerAimSpace = XR_NULL_HANDLE;
|
||||
qboolean inputInitialized = qfalse;
|
||||
qboolean useSimpleProfile = qfalse;
|
||||
|
||||
|
||||
|
||||
XrSpace CreateActionSpace(XrAction poseAction, XrPath subactionPath) {
|
||||
XrActionSpaceCreateInfo asci = {};
|
||||
asci.type = XR_TYPE_ACTION_SPACE_CREATE_INFO;
|
||||
asci.action = poseAction;
|
||||
asci.poseInActionSpace.orientation.w = 1.0f;
|
||||
asci.subactionPath = subactionPath;
|
||||
XrSpace actionSpace = XR_NULL_HANDLE;
|
||||
OXR(xrCreateActionSpace(gAppState.Session, &asci, &actionSpace));
|
||||
return actionSpace;
|
||||
}
|
||||
|
||||
XrActionSuggestedBinding ActionSuggestedBinding(XrAction action, const char* bindingString) {
|
||||
XrActionSuggestedBinding asb;
|
||||
asb.action = action;
|
||||
XrPath bindingPath;
|
||||
OXR(xrStringToPath(gAppState.Instance, bindingString, &bindingPath));
|
||||
asb.binding = bindingPath;
|
||||
return asb;
|
||||
}
|
||||
|
||||
XrActionSet CreateActionSet(int priority, const char* name, const char* localizedName) {
|
||||
XrActionSetCreateInfo asci = {};
|
||||
asci.type = XR_TYPE_ACTION_SET_CREATE_INFO;
|
||||
asci.next = NULL;
|
||||
asci.priority = priority;
|
||||
strcpy(asci.actionSetName, name);
|
||||
strcpy(asci.localizedActionSetName, localizedName);
|
||||
XrActionSet actionSet = XR_NULL_HANDLE;
|
||||
OXR(xrCreateActionSet(gAppState.Instance, &asci, &actionSet));
|
||||
return actionSet;
|
||||
}
|
||||
|
||||
XrAction CreateAction(
|
||||
XrActionSet actionSet,
|
||||
XrActionType type,
|
||||
const char* actionName,
|
||||
const char* localizedName,
|
||||
int countSubactionPaths,
|
||||
XrPath* subactionPaths) {
|
||||
ALOGV("CreateAction %s, %" PRIi32, actionName, countSubactionPaths);
|
||||
|
||||
XrActionCreateInfo aci = {};
|
||||
aci.type = XR_TYPE_ACTION_CREATE_INFO;
|
||||
aci.next = NULL;
|
||||
aci.actionType = type;
|
||||
if (countSubactionPaths > 0) {
|
||||
aci.countSubactionPaths = countSubactionPaths;
|
||||
aci.subactionPaths = subactionPaths;
|
||||
}
|
||||
strcpy(aci.actionName, actionName);
|
||||
strcpy(aci.localizedActionName, localizedName ? localizedName : actionName);
|
||||
XrAction action = XR_NULL_HANDLE;
|
||||
OXR(xrCreateAction(actionSet, &aci, &action));
|
||||
return action;
|
||||
}
|
||||
|
||||
bool ActionPoseIsActive(XrAction action, XrPath subactionPath) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
getInfo.subactionPath = subactionPath;
|
||||
|
||||
XrActionStatePose state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_POSE;
|
||||
OXR(xrGetActionStatePose(gAppState.Session, &getInfo, &state));
|
||||
return state.isActive != XR_FALSE;
|
||||
}
|
||||
|
||||
XrActionStateFloat GetActionStateFloat(XrAction action) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
|
||||
XrActionStateFloat state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_FLOAT;
|
||||
|
||||
OXR(xrGetActionStateFloat(gAppState.Session, &getInfo, &state));
|
||||
return state;
|
||||
}
|
||||
|
||||
XrActionStateBoolean GetActionStateBoolean(XrAction action) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
|
||||
XrActionStateBoolean state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_BOOLEAN;
|
||||
|
||||
OXR(xrGetActionStateBoolean(gAppState.Session, &getInfo, &state));
|
||||
return state;
|
||||
}
|
||||
|
||||
XrActionStateVector2f GetActionStateVector2(XrAction action) {
|
||||
XrActionStateGetInfo getInfo = {};
|
||||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.action = action;
|
||||
|
||||
XrActionStateVector2f state = {};
|
||||
state.type = XR_TYPE_ACTION_STATE_VECTOR2F;
|
||||
|
||||
OXR(xrGetActionStateVector2f(gAppState.Session, &getInfo, &state));
|
||||
return state;
|
||||
}
|
||||
|
||||
void JKVR_InitActions( void )
|
||||
{
|
||||
// Actions
|
||||
runningActionSet = CreateActionSet(1, "running_action_set", "Action Set used on main loop");
|
||||
indexLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_left", "Index left", 0, NULL);
|
||||
indexRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_right", "Index right", 0, NULL);
|
||||
menuAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "menu_action", "Menu", 0, NULL);
|
||||
buttonAAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_a", "Button A", 0, NULL);
|
||||
buttonBAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_b", "Button B", 0, NULL);
|
||||
buttonXAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_x", "Button X", 0, NULL);
|
||||
buttonYAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_y", "Button Y", 0, NULL);
|
||||
gripLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_left", "Grip left", 0, NULL);
|
||||
gripRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_right", "Grip right", 0, NULL);
|
||||
moveOnLeftJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_left_joy", "Move on left Joy", 0, NULL);
|
||||
moveOnRightJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_right_joy", "Move on right Joy", 0, NULL);
|
||||
thumbstickLeftClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_left", "Thumbstick left", 0, NULL);
|
||||
thumbstickRightClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_right", "Thumbstick right", 0, NULL);
|
||||
vibrateLeftFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_left_feedback", "Vibrate Left Controller Feedback", 0, NULL);
|
||||
vibrateRightFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_right_feedback", "Vibrate Right Controller Feedback", 0, NULL);
|
||||
|
||||
OXR(xrStringToPath(gAppState.Instance, "/user/hand/left", &leftHandPath));
|
||||
OXR(xrStringToPath(gAppState.Instance, "/user/hand/right", &rightHandPath));
|
||||
handPoseLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_left", NULL, 1, &leftHandPath);
|
||||
handPoseRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_right", NULL, 1, &rightHandPath);
|
||||
|
||||
XrPath interactionProfilePath = XR_NULL_PATH;
|
||||
XrPath interactionProfilePathTouch = XR_NULL_PATH;
|
||||
XrPath interactionProfilePathKHRSimple = XR_NULL_PATH;
|
||||
|
||||
OXR(xrStringToPath(gAppState.Instance, "/interaction_profiles/oculus/touch_controller", &interactionProfilePathTouch));
|
||||
OXR(xrStringToPath(gAppState.Instance, "/interaction_profiles/khr/simple_controller", &interactionProfilePathKHRSimple));
|
||||
|
||||
// Toggle this to force simple as a first choice, otherwise use it as a last resort
|
||||
if (useSimpleProfile) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
|
||||
interactionProfilePath = interactionProfilePathKHRSimple;
|
||||
} else {
|
||||
// Query Set
|
||||
XrActionSet queryActionSet = CreateActionSet(1, "query_action_set", "Action Set used to query device caps");
|
||||
XrAction dummyAction = CreateAction(queryActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "dummy_action", "Dummy Action", 0, NULL);
|
||||
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[1];
|
||||
int currBinding = 0;
|
||||
bindings[currBinding++] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/system/click");
|
||||
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {};
|
||||
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||
suggestedBindings.next = NULL;
|
||||
suggestedBindings.suggestedBindings = bindings;
|
||||
suggestedBindings.countSuggestedBindings = currBinding;
|
||||
|
||||
// Try all
|
||||
suggestedBindings.interactionProfile = interactionProfilePathTouch;
|
||||
XrResult suggestTouchResult = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings);
|
||||
OXR(suggestTouchResult);
|
||||
|
||||
if (XR_SUCCESS == suggestTouchResult) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for QUEST controller");
|
||||
interactionProfilePath = interactionProfilePathTouch;
|
||||
}
|
||||
|
||||
if (interactionProfilePath == XR_NULL_PATH) {
|
||||
// Simple as a fallback
|
||||
bindings[0] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/select/click");
|
||||
suggestedBindings.interactionProfile = interactionProfilePathKHRSimple;
|
||||
XrResult suggestKHRSimpleResult = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings);
|
||||
OXR(suggestKHRSimpleResult);
|
||||
if (XR_SUCCESS == suggestKHRSimpleResult) {
|
||||
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
|
||||
interactionProfilePath = interactionProfilePathKHRSimple;
|
||||
} else {
|
||||
ALOGE("xrSuggestInteractionProfileBindings did NOT find any bindings.");
|
||||
assert(qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Action creation
|
||||
{
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[32]; // large enough for all profiles
|
||||
int currBinding = 0;
|
||||
|
||||
{
|
||||
if (interactionProfilePath == interactionProfilePathTouch) {
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/trigger");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/trigger");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(menuAction, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/left/input/x/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonYAction, "/user/hand/left/input/y/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/right/input/a/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonBAction, "/user/hand/right/input/b/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(gripLeftAction, "/user/hand/left/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(gripRightAction, "/user/hand/right/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnLeftJoystickAction, "/user/hand/left/input/thumbstick");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnRightJoystickAction, "/user/hand/right/input/thumbstick");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickLeftClickAction, "/user/hand/left/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickRightClickAction, "/user/hand/right/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
|
||||
}
|
||||
|
||||
if (interactionProfilePath == interactionProfilePathKHRSimple) {
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/select/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/select/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/right/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
|
||||
}
|
||||
}
|
||||
|
||||
XrInteractionProfileSuggestedBinding suggestedBindings = {};
|
||||
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
|
||||
suggestedBindings.next = NULL;
|
||||
suggestedBindings.interactionProfile = interactionProfilePath;
|
||||
suggestedBindings.suggestedBindings = bindings;
|
||||
suggestedBindings.countSuggestedBindings = currBinding;
|
||||
OXR(xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings));
|
||||
|
||||
// Enumerate actions
|
||||
XrPath actionPathsBuffer[32];
|
||||
char stringBuffer[256];
|
||||
XrAction actionsToEnumerate[] = {
|
||||
indexLeftAction,
|
||||
indexRightAction,
|
||||
menuAction,
|
||||
buttonAAction,
|
||||
buttonBAction,
|
||||
buttonXAction,
|
||||
buttonYAction,
|
||||
gripLeftAction,
|
||||
gripRightAction,
|
||||
moveOnLeftJoystickAction,
|
||||
moveOnRightJoystickAction,
|
||||
thumbstickLeftClickAction,
|
||||
thumbstickRightClickAction,
|
||||
vibrateLeftFeedback,
|
||||
vibrateRightFeedback,
|
||||
handPoseLeftAction,
|
||||
handPoseRightAction
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(actionsToEnumerate) / sizeof(actionsToEnumerate[0]); ++i) {
|
||||
XrBoundSourcesForActionEnumerateInfo enumerateInfo = {};
|
||||
enumerateInfo.type = XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO;
|
||||
enumerateInfo.next = NULL;
|
||||
enumerateInfo.action = actionsToEnumerate[i];
|
||||
|
||||
// Get Count
|
||||
uint32_t countOutput = 0;
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
gAppState.Session, &enumerateInfo, 0 /* request size */, &countOutput, NULL));
|
||||
ALOGV(
|
||||
"xrEnumerateBoundSourcesForAction action=%lld count=%u",
|
||||
(long long)enumerateInfo.action,
|
||||
countOutput);
|
||||
|
||||
if (countOutput < 32) {
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
gAppState.Session, &enumerateInfo, 32, &countOutput, actionPathsBuffer));
|
||||
for (uint32_t a = 0; a < countOutput; ++a) {
|
||||
XrInputSourceLocalizedNameGetInfo nameGetInfo = {};
|
||||
nameGetInfo.type = XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO;
|
||||
nameGetInfo.next = NULL;
|
||||
nameGetInfo.sourcePath = actionPathsBuffer[a];
|
||||
nameGetInfo.whichComponents = XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT |
|
||||
XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT |
|
||||
XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT;
|
||||
|
||||
uint32_t stringCount = 0u;
|
||||
OXR(xrGetInputSourceLocalizedName(
|
||||
gAppState.Session, &nameGetInfo, 0, &stringCount, NULL));
|
||||
if (stringCount < 256) {
|
||||
OXR(xrGetInputSourceLocalizedName(
|
||||
gAppState.Session, &nameGetInfo, 256, &stringCount, stringBuffer));
|
||||
char pathStr[256];
|
||||
uint32_t strLen = 0;
|
||||
OXR(xrPathToString(
|
||||
gAppState.Instance,
|
||||
actionPathsBuffer[a],
|
||||
(uint32_t)sizeof(pathStr),
|
||||
&strLen,
|
||||
pathStr));
|
||||
ALOGV(
|
||||
" -> path = %lld `%s` -> `%s`",
|
||||
(long long)actionPathsBuffer[a],
|
||||
pathStr,
|
||||
stringBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
inputInitialized = qtrue;
|
||||
}
|
||||
|
||||
|
||||
//0 = left, 1 = right
|
||||
float vibration_channel_duration[2] = {0.0f, 0.0f};
|
||||
float vibration_channel_intensity[2] = {0.0f, 0.0f};
|
||||
|
||||
void JKVR_Vibrate( int duration, int chan, float intensity )
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
int channel = (i + 1) & chan;
|
||||
if (channel)
|
||||
{
|
||||
if (vibration_channel_duration[channel-1] > 0.0f)
|
||||
return;
|
||||
|
||||
if (vibration_channel_duration[channel-1] == -1.0f && duration != 0.0f)
|
||||
return;
|
||||
|
||||
vibration_channel_duration[channel-1] = duration;
|
||||
vibration_channel_intensity[channel-1] = intensity * vr_haptic_intensity->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JKVR_processHaptics() {
|
||||
static float lastFrameTime = 0.0f;
|
||||
float timestamp = (float)(Sys_Milliseconds( ));
|
||||
float frametime = timestamp - lastFrameTime;
|
||||
lastFrameTime = timestamp;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (vibration_channel_duration[i] > 0.0f ||
|
||||
vibration_channel_duration[i] == -1.0f) {
|
||||
|
||||
// fire haptics using output action
|
||||
XrHapticVibration vibration = {};
|
||||
vibration.type = XR_TYPE_HAPTIC_VIBRATION;
|
||||
vibration.next = NULL;
|
||||
vibration.amplitude = vibration_channel_intensity[i];
|
||||
vibration.duration = ToXrTime(vibration_channel_duration[i]);
|
||||
vibration.frequency = 3000;
|
||||
XrHapticActionInfo hapticActionInfo = {};
|
||||
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
|
||||
hapticActionInfo.next = NULL;
|
||||
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
|
||||
OXR(xrApplyHapticFeedback(gAppState.Session, &hapticActionInfo, (const XrHapticBaseHeader*)&vibration));
|
||||
|
||||
if (vibration_channel_duration[i] != -1.0f) {
|
||||
vibration_channel_duration[i] -= frametime;
|
||||
|
||||
if (vibration_channel_duration[i] < 0.0f) {
|
||||
vibration_channel_duration[i] = 0.0f;
|
||||
vibration_channel_intensity[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Stop haptics
|
||||
XrHapticActionInfo hapticActionInfo = {};
|
||||
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
|
||||
hapticActionInfo.next = NULL;
|
||||
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
|
||||
OXR(xrStopHapticFeedback(gAppState.Session, &hapticActionInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//keys.h
|
||||
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );
|
||||
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
|
||||
JK3_BASE_CFLAGS = -O1 -DHAVE_GLES -DFINAL_BUILD -fexceptions -Wall -Wno-write-strings -Wno-comment -fno-caller-saves -fno-tree-vectorize -Wno-unused-but-set-variable -fvisibility=hidden
|
||||
JK3_BASE_CFLAGS = -DHAVE_GLES -DFINAL_BUILD -fexceptions -Wall -Wno-write-strings -Wno-comment -fno-caller-saves -fno-tree-vectorize -Wno-unused-but-set-variable -fvisibility=hidden
|
||||
JK3_BASE_CPPFLAGS = -fvisibility-inlines-hidden -Wno-invalid-offsetof -fvisibility=hidden
|
||||
|
||||
JK3_BASE_LDLIBS =
|
||||
|
|
|
@ -1181,7 +1181,7 @@ void CGCam_Update( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
float fov = vr && vr->immersive_cinematics ? vr->fov : client_camera.FOV;
|
||||
float fov = vr && vr->immersive_cinematics ? vr->fov_x : client_camera.FOV;
|
||||
CG_CalcFOVFromX( fov );
|
||||
}
|
||||
|
||||
|
|
|
@ -1368,7 +1368,7 @@ static qboolean CG_CalcFov( void ) {
|
|||
g_entities[cg.snap->ps.viewEntity].NPC )
|
||||
{//FIXME: looks bad when take over a jedi... but never really do that, do we?
|
||||
//fov_x = g_entities[cg.snap->ps.viewEntity].NPC->stats.hfov;
|
||||
fov_x = vr ? vr->fov : 90.0f;
|
||||
fov_x = vr ? vr->fov_x : 90.0f;
|
||||
//sanity-cap?
|
||||
if ( fov_x > 120 )
|
||||
{
|
||||
|
@ -1388,7 +1388,7 @@ static qboolean CG_CalcFov( void ) {
|
|||
else
|
||||
{
|
||||
//fov_x = 120;//FIXME: read from the NPC's fov stats?
|
||||
fov_x = vr ? vr->fov : 90.0f;
|
||||
fov_x = vr ? vr->fov_x : 90.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1413,7 +1413,7 @@ static qboolean CG_CalcFov( void ) {
|
|||
fov_x = 160;
|
||||
}*/
|
||||
|
||||
fov_x = vr ? vr->fov : 90.0f;
|
||||
fov_x = vr ? vr->fov_x : 90.0f;
|
||||
|
||||
// Disable zooming when in third person
|
||||
if ( cg.zoomMode && cg.zoomMode < 3 )//&& !cg.renderingThirdPerson ) // light amp goggles do none of the zoom silliness
|
||||
|
|
|
@ -1082,7 +1082,7 @@ void CGCam_Update( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
float fov = vr && vr->immersive_cinematics ? vr->fov : client_camera.FOV;
|
||||
float fov = vr && vr->immersive_cinematics ? vr->fov_x : client_camera.FOV;
|
||||
CG_CalcFOVFromX( fov );
|
||||
}
|
||||
|
||||
|
|
|
@ -1364,7 +1364,7 @@ static qboolean CG_CalcFov( void ) {
|
|||
g_entities[cg.snap->ps.viewEntity].NPC )
|
||||
{//FIXME: looks bad when take over a jedi... but never really do that, do we?
|
||||
//fov_x = g_entities[cg.snap->ps.viewEntity].NPC->stats.hfov;
|
||||
fov_x = vr ? vr->fov : cg_fov.value;
|
||||
fov_x = vr ? vr->fov_x : cg_fov.value;
|
||||
//sanity-cap?
|
||||
if ( fov_x > 120 )
|
||||
{
|
||||
|
@ -1384,13 +1384,13 @@ static qboolean CG_CalcFov( void ) {
|
|||
else
|
||||
{
|
||||
//fov_x = 120;//FIXME: read from the NPC's fov stats?
|
||||
fov_x = vr ? vr->fov : cg_fov.value;
|
||||
fov_x = vr ? vr->fov_x : cg_fov.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( (!cg.zoomMode || cg.zoomMode > 2) && (cg.snap->ps.forcePowersActive&(1<<FP_SPEED)) && player->client->ps.forcePowerDuration[FP_SPEED] )//cg.renderingThirdPerson &&
|
||||
{
|
||||
fov_x = CG_ForceSpeedFOV(vr ? vr->fov : cg_fov.value);
|
||||
fov_x = CG_ForceSpeedFOV(vr ? vr->fov_x : cg_fov.value);
|
||||
} else {
|
||||
/*
|
||||
// user selectable
|
||||
|
@ -1408,7 +1408,7 @@ static qboolean CG_CalcFov( void ) {
|
|||
fov_x = 160;
|
||||
}*/
|
||||
|
||||
fov_x = vr ? vr->fov : cg_fov.value;
|
||||
fov_x = vr ? vr->fov_x : cg_fov.value;
|
||||
|
||||
// Disable zooming when in third person
|
||||
if (( cg.zoomMode && cg.zoomMode < 3 ) || cg.zoomMode == 4)//&& !cg.renderingThirdPerson ) // light amp goggles do none of the zoom silliness
|
||||
|
|
Loading…
Reference in a new issue