mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
OpenXR - Emulate mouse cursor
This commit is contained in:
parent
462174f548
commit
044d9a416b
@ -1,6 +1,7 @@
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
#include "Common/VR/VRBase.h"
|
||||
#include "Common/VR/VRInput.h"
|
||||
#include "Common/VR/VRMath.h"
|
||||
#include "Common/VR/VRRenderer.h"
|
||||
#include "Common/VR/VRTweaks.h"
|
||||
|
||||
@ -31,6 +32,16 @@ struct ButtonMapping {
|
||||
}
|
||||
};
|
||||
|
||||
struct MouseActivator {
|
||||
bool activate;
|
||||
ovrButton ovr;
|
||||
|
||||
MouseActivator(bool activate, ovrButton ovr) {
|
||||
this->activate = activate;
|
||||
this->ovr = ovr;
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<ButtonMapping> leftControllerMapping = {
|
||||
ButtonMapping(NKCODE_BUTTON_X, ovrButton_X),
|
||||
ButtonMapping(NKCODE_BUTTON_Y, ovrButton_Y),
|
||||
@ -61,6 +72,16 @@ static std::vector<ButtonMapping> controllerMapping[2] = {
|
||||
leftControllerMapping,
|
||||
rightControllerMapping
|
||||
};
|
||||
static int mouseController = -1;
|
||||
static bool mousePressed[] = {false, false};
|
||||
|
||||
static std::vector<MouseActivator> mouseActivators = {
|
||||
MouseActivator(true, ovrButton_Trigger),
|
||||
MouseActivator(false, ovrButton_Up),
|
||||
MouseActivator(false, ovrButton_Down),
|
||||
MouseActivator(false, ovrButton_Left),
|
||||
MouseActivator(false, ovrButton_Right),
|
||||
};
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
@ -99,7 +120,8 @@ void GetVRResolutionPerEye(int* width, int* height) {
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool haptics) {
|
||||
void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool(*NativeTouch)(const TouchInput &touch), bool haptics, float dp_xscale, float dp_yscale) {
|
||||
//buttons
|
||||
KeyInput keyInput = {};
|
||||
for (int j = 0; j < 2; j++) {
|
||||
int status = IN_VRGetButtonState(j);
|
||||
@ -125,6 +147,53 @@ void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool haptics) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//enable or disable mouse
|
||||
for (int j = 0; j < 2; j++) {
|
||||
int status = IN_VRGetButtonState(j);
|
||||
for (MouseActivator& m : mouseActivators) {
|
||||
if (status & m.ovr) {
|
||||
mouseController = m.activate ? j : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//mouse cursor
|
||||
if (mouseController >= 0) {
|
||||
//get position on screen
|
||||
XrPosef pose = IN_VRGetPose(mouseController);
|
||||
XrVector3f angles = XrQuaternionf_ToEulerAngles(pose.orientation);
|
||||
float width = (float)VR_GetConfig(VR_CONFIG_VIEWPORT_WIDTH);
|
||||
float height = (float)VR_GetConfig(VR_CONFIG_VIEWPORT_HEIGHT);
|
||||
float cx = width / 2;
|
||||
float cy = height / 2;
|
||||
float speed = (cx + cy) / 2;
|
||||
float x = cx - tan(ToRadians(angles.y - (float)VR_GetConfig(VR_CONFIG_MENU_YAW))) * speed;
|
||||
float y = cy - tan(ToRadians(angles.x)) * speed;
|
||||
|
||||
//set renderer
|
||||
VR_SetConfig(VR_CONFIG_MOUSE_X, (int)x);
|
||||
VR_SetConfig(VR_CONFIG_MOUSE_Y, (int)y);
|
||||
VR_SetConfig(VR_CONFIG_MOUSE_SIZE, 6 * (int)pow(VR_GetConfig(VR_CONFIG_CANVAS_DISTANCE), 0.25f));
|
||||
|
||||
//inform engine about the status
|
||||
TouchInput touch;
|
||||
touch.id = mouseController;
|
||||
touch.x = x * dp_xscale;
|
||||
touch.y = (height - y - 1) * dp_yscale;
|
||||
bool pressed = IN_VRGetButtonState(mouseController) & ovrButton_Trigger;
|
||||
if (mousePressed[mouseController] != pressed) {
|
||||
if (!pressed) {
|
||||
touch.flags = TOUCH_DOWN;
|
||||
NativeTouch(touch);
|
||||
touch.flags = TOUCH_UP;
|
||||
NativeTouch(touch);
|
||||
}
|
||||
mousePressed[mouseController] = pressed;
|
||||
}
|
||||
} else {
|
||||
VR_SetConfig(VR_CONFIG_MOUSE_SIZE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateVRScreenKey(const KeyInput &key) {
|
||||
|
@ -10,7 +10,7 @@ bool IsVRBuild();
|
||||
void InitVROnAndroid(void* vm, void* activity, int version, char* name);
|
||||
void EnterVR(bool firstStart);
|
||||
void GetVRResolutionPerEye(int* width, int* height);
|
||||
void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool haptics);
|
||||
void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool(*NativeTouch)(const TouchInput &touch), bool haptics, float dp_xscale, float dp_yscale);
|
||||
void UpdateVRScreenKey(const KeyInput &key);
|
||||
|
||||
// VR rendering integration
|
||||
|
@ -506,3 +506,12 @@ uint32_t IN_VRGetButtonState( int controllerIndex ) {
|
||||
XrVector2f IN_VRGetJoystickState( int controllerIndex ) {
|
||||
return moveJoystickState[controllerIndex].currentState;
|
||||
}
|
||||
|
||||
XrPosef IN_VRGetPose( int controllerIndex ) {
|
||||
engine_t* engine = VR_GetEngine();
|
||||
XrSpaceLocation loc = {};
|
||||
loc.type = XR_TYPE_SPACE_LOCATION;
|
||||
XrSpace aimSpace[] = { leftControllerAimSpace, rightControllerAimSpace };
|
||||
xrLocateSpace(aimSpace[controllerIndex], engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc);
|
||||
return loc.pose;
|
||||
}
|
||||
|
@ -32,4 +32,5 @@ void IN_VRInit( engine_t *engine );
|
||||
void IN_VRInputFrame( engine_t* engine );
|
||||
uint32_t IN_VRGetButtonState( int controllerIndex );
|
||||
XrVector2f IN_VRGetJoystickState( int controllerIndex );
|
||||
XrPosef IN_VRGetPose( int controllerIndex );
|
||||
void INVR_Vibrate( int duration, int chan, float intensity );
|
||||
|
@ -16,9 +16,6 @@ GLboolean initialized = GL_FALSE;
|
||||
GLboolean stageSupported = GL_FALSE;
|
||||
int vrConfig[VR_CONFIG_MAX] = {};
|
||||
|
||||
float menuPitch = 0;
|
||||
float menuYaw = 0;
|
||||
float recenterYaw = 0;
|
||||
XrVector3f hmdorientation;
|
||||
XrVector3f hmdposition;
|
||||
|
||||
@ -135,7 +132,8 @@ void VR_Recenter(engine_t* engine) {
|
||||
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc));
|
||||
hmdorientation = XrQuaternionf_ToEulerAngles(loc.pose.orientation);
|
||||
|
||||
recenterYaw += ToRadians(hmdorientation.y);
|
||||
vrConfig[VR_CONFIG_RECENTER_YAW] += (int)hmdorientation.y;
|
||||
float recenterYaw = ToRadians((float)vrConfig[VR_CONFIG_RECENTER_YAW]);
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.x = 0;
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.y = sin(recenterYaw / 2);
|
||||
spaceCreateInfo.poseInReferenceSpace.orientation.z = 0;
|
||||
@ -171,8 +169,8 @@ void VR_Recenter(engine_t* engine) {
|
||||
}
|
||||
|
||||
// Update menu orientation
|
||||
menuPitch = hmdorientation.x;
|
||||
menuYaw = 0;
|
||||
vrConfig[VR_CONFIG_MENU_PITCH] = (int)hmdorientation.x;
|
||||
vrConfig[VR_CONFIG_MENU_YAW] = 0;
|
||||
}
|
||||
|
||||
void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
||||
@ -182,6 +180,8 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
||||
|
||||
int eyeW, eyeH;
|
||||
VR_GetResolution(engine, &eyeW, &eyeH);
|
||||
vrConfig[VR_CONFIG_VIEWPORT_WIDTH] = eyeW;
|
||||
vrConfig[VR_CONFIG_VIEWPORT_HEIGHT] = eyeH;
|
||||
|
||||
// Get the viewport configuration info for the chosen viewport configuration type.
|
||||
engine->appState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
||||
@ -321,15 +321,26 @@ void VR_EndFrame( engine_t* engine ) {
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
// Show mouse cursor
|
||||
int vrMode = vrConfig[VR_CONFIG_MODE];
|
||||
int size = vrConfig[VR_CONFIG_MOUSE_SIZE];
|
||||
if ((vrMode == VR_MODE_FLAT_SCREEN) && (size > 0)) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(vrConfig[VR_CONFIG_MOUSE_X], vrConfig[VR_CONFIG_MOUSE_Y], size, size);
|
||||
glViewport(vrConfig[VR_CONFIG_MOUSE_X], vrConfig[VR_CONFIG_MOUSE_Y], size, size);
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||
//ovrFramebuffer_Resolve(frameBuffer);
|
||||
ovrFramebuffer_Release(frameBuffer);
|
||||
ovrFramebuffer_SetNone();
|
||||
|
||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||
int vrMode = vrConfig[VR_CONFIG_MODE];
|
||||
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {
|
||||
menuYaw = hmdorientation.y;
|
||||
vrConfig[VR_CONFIG_MENU_YAW] = (int)hmdorientation.y;
|
||||
|
||||
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||
int imageLayer = eye;
|
||||
@ -379,14 +390,16 @@ void VR_EndFrame( engine_t* engine ) {
|
||||
cylinder_layer.subImage.imageRect.extent.width = width;
|
||||
cylinder_layer.subImage.imageRect.extent.height = height;
|
||||
cylinder_layer.subImage.imageArrayIndex = 0;
|
||||
float distance = vrConfig[VR_CONFIG_CANVAS_DISTANCE];
|
||||
float distance = (float)vrConfig[VR_CONFIG_CANVAS_DISTANCE];
|
||||
float menuPitch = ToRadians((float)vrConfig[VR_CONFIG_MENU_PITCH]);
|
||||
float menuYaw = ToRadians((float)vrConfig[VR_CONFIG_MENU_YAW]);
|
||||
XrVector3f pos = {
|
||||
invViewTransform[0].position.x - sin(ToRadians(menuYaw)) * distance,
|
||||
invViewTransform[0].position.x - sin(menuYaw) * distance,
|
||||
invViewTransform[0].position.y,
|
||||
invViewTransform[0].position.z - cos(ToRadians(menuYaw)) * distance
|
||||
invViewTransform[0].position.z - cos(menuYaw) * distance
|
||||
};
|
||||
XrQuaternionf pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, -ToRadians(menuPitch));
|
||||
XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, ToRadians(menuYaw));
|
||||
XrQuaternionf pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, -menuPitch);
|
||||
XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, menuYaw);
|
||||
cylinder_layer.pose.orientation = XrQuaternionf_Multiply(pitch, yaw);
|
||||
cylinder_layer.pose.position = pos;
|
||||
cylinder_layer.radius = 12.0f;
|
||||
|
@ -4,19 +4,22 @@
|
||||
#include "VRMath.h"
|
||||
|
||||
enum VRConfig {
|
||||
VR_CONFIG_MODE,
|
||||
VR_CONFIG_6DOF_ENABLED,
|
||||
VR_CONFIG_6DOF_SCALE,
|
||||
VR_CONFIG_MIRROR_AXIS_X,
|
||||
VR_CONFIG_MIRROR_AXIS_Y,
|
||||
VR_CONFIG_MIRROR_AXIS_Z,
|
||||
VR_CONFIG_MIRROR_PITCH,
|
||||
VR_CONFIG_MIRROR_YAW,
|
||||
VR_CONFIG_MIRROR_ROLL,
|
||||
VR_CONFIG_3D_GEOMETRY_COUNT,
|
||||
VR_CONFIG_FOV_SCALE,
|
||||
VR_CONFIG_FORCE_2D,
|
||||
VR_CONFIG_CANVAS_DISTANCE,
|
||||
//switching between 2D and 3D
|
||||
VR_CONFIG_MODE, VR_CONFIG_3D_GEOMETRY_COUNT, VR_CONFIG_FORCE_2D,
|
||||
//camera setup
|
||||
VR_CONFIG_FOV_SCALE, VR_CONFIG_CANVAS_DISTANCE,
|
||||
//6DoF
|
||||
VR_CONFIG_6DOF_ENABLED, VR_CONFIG_6DOF_SCALE,
|
||||
VR_CONFIG_MIRROR_AXIS_X, VR_CONFIG_MIRROR_AXIS_Y, VR_CONFIG_MIRROR_AXIS_Z,
|
||||
VR_CONFIG_MIRROR_PITCH, VR_CONFIG_MIRROR_YAW, VR_CONFIG_MIRROR_ROLL,
|
||||
//2D canvas positioning
|
||||
VR_CONFIG_MENU_PITCH, VR_CONFIG_MENU_YAW, VR_CONFIG_RECENTER_YAW,
|
||||
//mouse cursor
|
||||
VR_CONFIG_MOUSE_SIZE, VR_CONFIG_MOUSE_X, VR_CONFIG_MOUSE_Y,
|
||||
//viewport size
|
||||
VR_CONFIG_VIEWPORT_WIDTH, VR_CONFIG_VIEWPORT_HEIGHT,
|
||||
|
||||
//end
|
||||
VR_CONFIG_MAX
|
||||
};
|
||||
|
||||
|
@ -1066,7 +1066,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env,
|
||||
}
|
||||
|
||||
if (IsVRBuild()) {
|
||||
UpdateVRInput(NativeKey, g_Config.bHapticFeedback);
|
||||
UpdateVRInput(NativeKey, NativeTouch, g_Config.bHapticFeedback, dp_xscale, dp_yscale);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user