mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-25 05:21:03 +00:00
OpenXR touch controllers completely implemented
This commit is contained in:
parent
0bf485664c
commit
b11122e368
3 changed files with 112 additions and 89 deletions
|
@ -25,14 +25,17 @@ XrAction aimPoseAction;
|
|||
XrAction gripPoseAction;
|
||||
XrAction indexLeftAction;
|
||||
XrAction indexRightAction;
|
||||
XrAction toggleAction;
|
||||
XrAction moveOnXAction;
|
||||
XrAction moveOnYAction;
|
||||
XrAction menuAction;
|
||||
XrAction buttonAAction;
|
||||
XrAction buttonBAction;
|
||||
XrAction buttonXAction;
|
||||
XrAction buttonYAction;
|
||||
XrAction gripLeftAction;
|
||||
XrAction gripRightAction;
|
||||
XrAction moveOnLeftJoystickAction;
|
||||
XrAction moveOnRightJoystickAction;
|
||||
XrAction thumbstickClickAction;
|
||||
XrAction vibrateLeftToggle;
|
||||
XrAction vibrateRightToggle;
|
||||
XrAction thumbstickLeftClickAction;
|
||||
XrAction thumbstickRightClickAction;
|
||||
XrAction vibrateLeftFeedback;
|
||||
XrAction vibrateRightFeedback;
|
||||
XrActionSet runningActionSet;
|
||||
|
@ -643,14 +646,17 @@ void IN_VRInit( void )
|
|||
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);
|
||||
toggleAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "toggle", "Toggle", 0, NULL);
|
||||
moveOnXAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "move_on_x", "Move on X", 0, NULL);
|
||||
moveOnYAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "move_on_y", "Move on Y", 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);
|
||||
thumbstickClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_click", "Thumbstick Click", 0, NULL);
|
||||
vibrateLeftToggle = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "vibrate_left", "Vibrate Left Controller", 0, NULL);
|
||||
vibrateRightToggle = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "vibrate_right", "Vibrate Right Controller", 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);
|
||||
|
||||
|
@ -716,25 +722,24 @@ void IN_VRInit( void )
|
|||
// Action creation
|
||||
{
|
||||
// Map bindings
|
||||
XrActionSuggestedBinding bindings[22]; // large enough for all profiles
|
||||
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(toggleAction, "/user/hand/left/input/x/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(toggleAction, "/user/hand/right/input/a/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnXAction, "/user/hand/left/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnXAction, "/user/hand/right/input/squeeze/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnYAction, "/user/hand/left/input/trigger/value");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(moveOnYAction, "/user/hand/right/input/trigger/value");
|
||||
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(thumbstickClickAction, "/user/hand/left/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(thumbstickClickAction, "/user/hand/right/input/thumbstick/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftToggle, "/user/hand/left/input/y/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightToggle, "/user/hand/right/input/b/click");
|
||||
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(aimPoseAction, "/user/hand/left/input/aim/pose");
|
||||
|
@ -746,8 +751,8 @@ void IN_VRInit( void )
|
|||
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(vibrateLeftToggle, "/user/hand/left/input/menu/click");
|
||||
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightToggle, "/user/hand/right/input/menu/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(aimPoseAction, "/user/hand/left/input/aim/pose");
|
||||
|
@ -766,19 +771,22 @@ void IN_VRInit( void )
|
|||
OXR(xrSuggestInteractionProfileBindings(engine->appState.Instance, &suggestedBindings));
|
||||
|
||||
// Enumerate actions
|
||||
XrPath actionPathsBuffer[16];
|
||||
XrPath actionPathsBuffer[32];
|
||||
char stringBuffer[256];
|
||||
XrAction actionsToEnumerate[] = {
|
||||
indexLeftAction,
|
||||
indexRightAction,
|
||||
toggleAction,
|
||||
moveOnXAction,
|
||||
moveOnYAction,
|
||||
menuAction,
|
||||
buttonAAction,
|
||||
buttonBAction,
|
||||
buttonXAction,
|
||||
buttonYAction,
|
||||
gripLeftAction,
|
||||
gripRightAction,
|
||||
moveOnLeftJoystickAction,
|
||||
moveOnRightJoystickAction,
|
||||
thumbstickClickAction,
|
||||
vibrateLeftToggle,
|
||||
vibrateRightToggle,
|
||||
thumbstickLeftClickAction,
|
||||
thumbstickRightClickAction,
|
||||
vibrateLeftFeedback,
|
||||
vibrateRightFeedback,
|
||||
aimPoseAction,
|
||||
|
@ -799,9 +807,9 @@ void IN_VRInit( void )
|
|||
(long long)enumerateInfo.action,
|
||||
countOutput);
|
||||
|
||||
if (countOutput < 16) {
|
||||
if (countOutput < 32) {
|
||||
OXR(xrEnumerateBoundSourcesForAction(
|
||||
engine->appState.Session, &enumerateInfo, 16, &countOutput, actionPathsBuffer));
|
||||
engine->appState.Session, &enumerateInfo, 32, &countOutput, actionPathsBuffer));
|
||||
for (uint32_t a = 0; a < countOutput; ++a) {
|
||||
XrInputSourceLocalizedNameGetInfo nameGetInfo = {};
|
||||
nameGetInfo.type = XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO;
|
||||
|
@ -841,22 +849,37 @@ static void IN_VRController( qboolean isRightController, XrPosef pose )
|
|||
{
|
||||
//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};
|
||||
if (isRightController != (vr_righthanded->integer != 0))
|
||||
if (isRightController == (vr_righthanded->integer != 0))
|
||||
{
|
||||
//Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick
|
||||
rotation[PITCH] = vr_weaponPitch->value;
|
||||
QuatToYawPitchRoll(pose.orientation, rotation, vr.weaponangles);
|
||||
|
||||
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
|
||||
VectorCopy(vr.weaponangles, vr.weaponangles_last);
|
||||
|
||||
///Weapon location relative to view
|
||||
vr.weaponposition[0] = pose.position.x;
|
||||
vr.weaponposition[1] = pose.position.y + vr_heightAdjust->value;
|
||||
vr.weaponposition[2] = pose.position.z;
|
||||
|
||||
VectorCopy(vr.weaponoffset_last[1], vr.weaponoffset_last[0]);
|
||||
VectorCopy(vr.weaponoffset, vr.weaponoffset_last[1]);
|
||||
VectorSubtract(vr.weaponposition, vr.hmdposition, vr.weaponoffset);
|
||||
} else {
|
||||
QuatToYawPitchRoll(pose.orientation, rotation, vr.offhandangles2); // used for off-hand direction mode
|
||||
rotation[PITCH] = vr_weaponPitch->value;
|
||||
QuatToYawPitchRoll(pose.orientation, rotation, vr.weaponangles);
|
||||
rotation[PITCH] = vr_weaponPitch->value;
|
||||
QuatToYawPitchRoll(pose.orientation, rotation, vr.offhandangles);
|
||||
|
||||
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
|
||||
VectorCopy(vr.weaponangles, vr.weaponangles_last);
|
||||
///location relative to view
|
||||
vr.weaponposition[0] = pose.position.x;
|
||||
vr.weaponposition[1] = pose.position.y + vr_heightAdjust->value;
|
||||
vr.weaponposition[2] = pose.position.z;
|
||||
|
||||
///Weapon location relative to view
|
||||
vr.weaponposition[0] = pose.position.x;
|
||||
vr.weaponposition[1] = pose.position.y + vr_heightAdjust->value;
|
||||
vr.weaponposition[2] = pose.position.z;
|
||||
|
||||
VectorCopy(vr.weaponoffset_last[1], vr.weaponoffset_last[0]);
|
||||
VectorCopy(vr.weaponoffset, vr.weaponoffset_last[1]);
|
||||
VectorSubtract(vr.weaponposition, vr.hmdposition, vr.weaponoffset);
|
||||
VectorCopy(vr.offhandoffset_last[1], vr.offhandoffset_last[0]);
|
||||
VectorCopy(vr.offhandoffset, vr.offhandoffset_last[1]);
|
||||
VectorSubtract(vr.offhandposition, vr.hmdposition, vr.offhandoffset);
|
||||
}
|
||||
|
||||
if (vr.virtual_screen || cl.snap.ps.pm_type == PM_INTERMISSION)
|
||||
{
|
||||
|
@ -1183,9 +1206,6 @@ static void IN_VRButtons( qboolean isRightController, uint32_t buttons )
|
|||
{
|
||||
vrController_t* controller = isRightController == qtrue ? &rightController : &leftController;
|
||||
|
||||
//TODO:
|
||||
/*
|
||||
{
|
||||
// Menu button
|
||||
if ((buttons & ovrButton_Enter) && !IN_InputActivated(&controller->buttons, ovrButton_Enter)) {
|
||||
IN_ActivateInput(&controller->buttons, ovrButton_Enter);
|
||||
|
@ -1278,7 +1298,6 @@ static void IN_VRButtons( qboolean isRightController, uint32_t buttons )
|
|||
} else {
|
||||
IN_HandleInactiveInput(&controller->buttons, ovrButton_Y, "Y", 0, qfalse);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void IN_VRInputFrame( void )
|
||||
|
@ -1400,44 +1419,22 @@ void IN_VRInputFrame( void )
|
|||
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
|
||||
getInfo.next = NULL;
|
||||
getInfo.subactionPath = XR_NULL_PATH;
|
||||
|
||||
XrActionStateBoolean toggleState = GetActionStateBoolean(toggleAction);
|
||||
XrActionStateBoolean vibrateLeftState = GetActionStateBoolean(vibrateLeftToggle);
|
||||
XrActionStateBoolean vibrateRightState = GetActionStateBoolean(vibrateRightToggle);
|
||||
XrActionStateBoolean thumbstickClickState = GetActionStateBoolean(thumbstickClickAction);
|
||||
}
|
||||
|
||||
//TODO:
|
||||
/*ovrInputCapabilityHeader capsHeader;
|
||||
uint32_t index = 0;
|
||||
for (;;) {
|
||||
ovrResult enumResult = vrapi_EnumerateInputDevices(ovr, index, &capsHeader);
|
||||
if (enumResult < 0) {
|
||||
break;
|
||||
}
|
||||
++index;
|
||||
|
||||
if (capsHeader.Type != ovrControllerType_TrackedRemote) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qboolean isRight;
|
||||
vrController_t* controller;
|
||||
if (caps.ControllerCapabilities & ovrControllerCaps_LeftHand) {
|
||||
isRight = qfalse;
|
||||
controller = &leftController;
|
||||
controllerIDs[0] = capsHeader.DeviceID;
|
||||
} else if (caps.ControllerCapabilities & ovrControllerCaps_RightHand) {
|
||||
isRight = qtrue;
|
||||
controller = &rightController;
|
||||
controllerIDs[1] = capsHeader.DeviceID;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
|
||||
IN_VRButtons(isRight, state.Buttons);
|
||||
}*/
|
||||
//button mapping
|
||||
uint32_t lButtons = 0;
|
||||
if (GetActionStateBoolean(menuAction).currentState) lButtons |= ovrButton_Enter;
|
||||
if (GetActionStateBoolean(buttonXAction).currentState) lButtons |= ovrButton_X;
|
||||
if (GetActionStateBoolean(buttonYAction).currentState) lButtons |= ovrButton_Y;
|
||||
if (GetActionStateFloat(gripLeftAction).currentState > 0.5f) lButtons |= ovrButton_GripTrigger;
|
||||
if (GetActionStateBoolean(thumbstickLeftClickAction).currentState) lButtons |= ovrButton_LThumb;
|
||||
IN_VRButtons(qfalse, lButtons);
|
||||
uint32_t rButtons = 0;
|
||||
if (GetActionStateBoolean(buttonAAction).currentState) rButtons |= ovrButton_A;
|
||||
if (GetActionStateBoolean(buttonBAction).currentState) rButtons |= ovrButton_B;
|
||||
if (GetActionStateFloat(gripRightAction).currentState > 0.5f) rButtons |= ovrButton_GripTrigger;
|
||||
if (GetActionStateBoolean(thumbstickRightClickAction).currentState) rButtons |= ovrButton_RThumb;
|
||||
IN_VRButtons(qtrue, rButtons);
|
||||
|
||||
//index finger click
|
||||
XrActionStateBoolean indexState;
|
||||
|
|
|
@ -464,11 +464,11 @@ void VR_DrawFrame( engine_t* engine ) {
|
|||
cylinder_layer.subImage.imageRect.extent.height = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Height;
|
||||
cylinder_layer.subImage.imageArrayIndex = 0;
|
||||
const XrVector3f axis = {0.0f, 1.0f, 0.0f};
|
||||
const XrVector3f pos = {xfStageFromHead.position.x, 0.0f, xfStageFromHead.position.z - 1.0f};
|
||||
const XrVector3f pos = {xfStageFromHead.position.x, -0.25f, xfStageFromHead.position.z - 1.0f};
|
||||
cylinder_layer.pose.orientation = XrQuaternionf_CreateFromVectorAngle(axis, 0);
|
||||
cylinder_layer.pose.position = pos;
|
||||
cylinder_layer.radius = 1.0f;
|
||||
cylinder_layer.centralAngle = MATH_PI * 0.75f;
|
||||
cylinder_layer.centralAngle = MATH_PI * 0.5f;
|
||||
cylinder_layer.aspectRatio = 1.0f;
|
||||
|
||||
engine->appState.Layers[engine->appState.LayerCount++].Cylinder = cylinder_layer;
|
||||
|
|
|
@ -126,6 +126,32 @@ typedef struct {
|
|||
float M[4][4];
|
||||
} ovrMatrix4f;
|
||||
|
||||
typedef enum ovrButton_ {
|
||||
ovrButton_A = 0x00000001, // Set for trigger pulled on the Gear VR and Go Controllers
|
||||
ovrButton_B = 0x00000002,
|
||||
ovrButton_RThumb = 0x00000004,
|
||||
ovrButton_RShoulder = 0x00000008,
|
||||
|
||||
ovrButton_X = 0x00000100,
|
||||
ovrButton_Y = 0x00000200,
|
||||
ovrButton_LThumb = 0x00000400,
|
||||
ovrButton_LShoulder = 0x00000800,
|
||||
|
||||
ovrButton_Up = 0x00010000,
|
||||
ovrButton_Down = 0x00020000,
|
||||
ovrButton_Left = 0x00040000,
|
||||
ovrButton_Right = 0x00080000,
|
||||
ovrButton_Enter = 0x00100000, //< Set for touchpad click on the Go Controller, menu
|
||||
// button on Left Quest Controller
|
||||
ovrButton_Back = 0x00200000, //< Back button on the Go Controller (only set when
|
||||
// a short press comes up)
|
||||
ovrButton_GripTrigger = 0x04000000, //< grip trigger engaged
|
||||
ovrButton_Trigger = 0x20000000, //< Index Trigger engaged
|
||||
ovrButton_Joystick = 0x80000000, //< Click of the Joystick
|
||||
|
||||
ovrButton_EnumSize = 0x7fffffff
|
||||
} ovrButton;
|
||||
|
||||
typedef struct {
|
||||
uint64_t frameIndex;
|
||||
ovrApp appState;
|
||||
|
|
Loading…
Reference in a new issue