mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
OpenXR - Emulate mouse cursor
This commit is contained in:
parent
462174f548
commit
044d9a416b
7 changed files with 124 additions and 29 deletions
|
@ -1,6 +1,7 @@
|
||||||
#include "Common/VR/PPSSPPVR.h"
|
#include "Common/VR/PPSSPPVR.h"
|
||||||
#include "Common/VR/VRBase.h"
|
#include "Common/VR/VRBase.h"
|
||||||
#include "Common/VR/VRInput.h"
|
#include "Common/VR/VRInput.h"
|
||||||
|
#include "Common/VR/VRMath.h"
|
||||||
#include "Common/VR/VRRenderer.h"
|
#include "Common/VR/VRRenderer.h"
|
||||||
#include "Common/VR/VRTweaks.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 = {
|
static std::vector<ButtonMapping> leftControllerMapping = {
|
||||||
ButtonMapping(NKCODE_BUTTON_X, ovrButton_X),
|
ButtonMapping(NKCODE_BUTTON_X, ovrButton_X),
|
||||||
ButtonMapping(NKCODE_BUTTON_Y, ovrButton_Y),
|
ButtonMapping(NKCODE_BUTTON_Y, ovrButton_Y),
|
||||||
|
@ -61,6 +72,16 @@ static std::vector<ButtonMapping> controllerMapping[2] = {
|
||||||
leftControllerMapping,
|
leftControllerMapping,
|
||||||
rightControllerMapping
|
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 = {};
|
KeyInput keyInput = {};
|
||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
int status = IN_VRGetButtonState(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) {
|
void UpdateVRScreenKey(const KeyInput &key) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ bool IsVRBuild();
|
||||||
void InitVROnAndroid(void* vm, void* activity, int version, char* name);
|
void InitVROnAndroid(void* vm, void* activity, int version, char* name);
|
||||||
void EnterVR(bool firstStart);
|
void EnterVR(bool firstStart);
|
||||||
void GetVRResolutionPerEye(int* width, int* height);
|
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);
|
void UpdateVRScreenKey(const KeyInput &key);
|
||||||
|
|
||||||
// VR rendering integration
|
// VR rendering integration
|
||||||
|
|
|
@ -506,3 +506,12 @@ uint32_t IN_VRGetButtonState( int controllerIndex ) {
|
||||||
XrVector2f IN_VRGetJoystickState( int controllerIndex ) {
|
XrVector2f IN_VRGetJoystickState( int controllerIndex ) {
|
||||||
return moveJoystickState[controllerIndex].currentState;
|
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 );
|
void IN_VRInputFrame( engine_t* engine );
|
||||||
uint32_t IN_VRGetButtonState( int controllerIndex );
|
uint32_t IN_VRGetButtonState( int controllerIndex );
|
||||||
XrVector2f IN_VRGetJoystickState( int controllerIndex );
|
XrVector2f IN_VRGetJoystickState( int controllerIndex );
|
||||||
|
XrPosef IN_VRGetPose( int controllerIndex );
|
||||||
void INVR_Vibrate( int duration, int chan, float intensity );
|
void INVR_Vibrate( int duration, int chan, float intensity );
|
||||||
|
|
|
@ -16,9 +16,6 @@ GLboolean initialized = GL_FALSE;
|
||||||
GLboolean stageSupported = GL_FALSE;
|
GLboolean stageSupported = GL_FALSE;
|
||||||
int vrConfig[VR_CONFIG_MAX] = {};
|
int vrConfig[VR_CONFIG_MAX] = {};
|
||||||
|
|
||||||
float menuPitch = 0;
|
|
||||||
float menuYaw = 0;
|
|
||||||
float recenterYaw = 0;
|
|
||||||
XrVector3f hmdorientation;
|
XrVector3f hmdorientation;
|
||||||
XrVector3f hmdposition;
|
XrVector3f hmdposition;
|
||||||
|
|
||||||
|
@ -135,7 +132,8 @@ void VR_Recenter(engine_t* engine) {
|
||||||
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc));
|
OXR(xrLocateSpace(engine->appState.HeadSpace, engine->appState.CurrentSpace, engine->predictedDisplayTime, &loc));
|
||||||
hmdorientation = XrQuaternionf_ToEulerAngles(loc.pose.orientation);
|
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.x = 0;
|
||||||
spaceCreateInfo.poseInReferenceSpace.orientation.y = sin(recenterYaw / 2);
|
spaceCreateInfo.poseInReferenceSpace.orientation.y = sin(recenterYaw / 2);
|
||||||
spaceCreateInfo.poseInReferenceSpace.orientation.z = 0;
|
spaceCreateInfo.poseInReferenceSpace.orientation.z = 0;
|
||||||
|
@ -171,8 +169,8 @@ void VR_Recenter(engine_t* engine) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update menu orientation
|
// Update menu orientation
|
||||||
menuPitch = hmdorientation.x;
|
vrConfig[VR_CONFIG_MENU_PITCH] = (int)hmdorientation.x;
|
||||||
menuYaw = 0;
|
vrConfig[VR_CONFIG_MENU_YAW] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
||||||
|
@ -182,6 +180,8 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
||||||
|
|
||||||
int eyeW, eyeH;
|
int eyeW, eyeH;
|
||||||
VR_GetResolution(engine, &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.
|
// Get the viewport configuration info for the chosen viewport configuration type.
|
||||||
engine->appState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
engine->appState.ViewportConfig.type = XR_TYPE_VIEW_CONFIGURATION_PROPERTIES;
|
||||||
|
@ -321,15 +321,26 @@ void VR_EndFrame( engine_t* engine ) {
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
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* frameBuffer = &engine->appState.Renderer.FrameBuffer;
|
||||||
//ovrFramebuffer_Resolve(frameBuffer);
|
//ovrFramebuffer_Resolve(frameBuffer);
|
||||||
ovrFramebuffer_Release(frameBuffer);
|
ovrFramebuffer_Release(frameBuffer);
|
||||||
ovrFramebuffer_SetNone();
|
ovrFramebuffer_SetNone();
|
||||||
|
|
||||||
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
|
||||||
int vrMode = vrConfig[VR_CONFIG_MODE];
|
|
||||||
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {
|
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++) {
|
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
|
||||||
int imageLayer = 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.width = width;
|
||||||
cylinder_layer.subImage.imageRect.extent.height = height;
|
cylinder_layer.subImage.imageRect.extent.height = height;
|
||||||
cylinder_layer.subImage.imageArrayIndex = 0;
|
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 = {
|
XrVector3f pos = {
|
||||||
invViewTransform[0].position.x - sin(ToRadians(menuYaw)) * distance,
|
invViewTransform[0].position.x - sin(menuYaw) * distance,
|
||||||
invViewTransform[0].position.y,
|
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 pitch = XrQuaternionf_CreateFromVectorAngle({1, 0, 0}, -menuPitch);
|
||||||
XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, ToRadians(menuYaw));
|
XrQuaternionf yaw = XrQuaternionf_CreateFromVectorAngle({0, 1, 0}, menuYaw);
|
||||||
cylinder_layer.pose.orientation = XrQuaternionf_Multiply(pitch, yaw);
|
cylinder_layer.pose.orientation = XrQuaternionf_Multiply(pitch, yaw);
|
||||||
cylinder_layer.pose.position = pos;
|
cylinder_layer.pose.position = pos;
|
||||||
cylinder_layer.radius = 12.0f;
|
cylinder_layer.radius = 12.0f;
|
||||||
|
|
|
@ -4,19 +4,22 @@
|
||||||
#include "VRMath.h"
|
#include "VRMath.h"
|
||||||
|
|
||||||
enum VRConfig {
|
enum VRConfig {
|
||||||
VR_CONFIG_MODE,
|
//switching between 2D and 3D
|
||||||
VR_CONFIG_6DOF_ENABLED,
|
VR_CONFIG_MODE, VR_CONFIG_3D_GEOMETRY_COUNT, VR_CONFIG_FORCE_2D,
|
||||||
VR_CONFIG_6DOF_SCALE,
|
//camera setup
|
||||||
VR_CONFIG_MIRROR_AXIS_X,
|
VR_CONFIG_FOV_SCALE, VR_CONFIG_CANVAS_DISTANCE,
|
||||||
VR_CONFIG_MIRROR_AXIS_Y,
|
//6DoF
|
||||||
VR_CONFIG_MIRROR_AXIS_Z,
|
VR_CONFIG_6DOF_ENABLED, VR_CONFIG_6DOF_SCALE,
|
||||||
VR_CONFIG_MIRROR_PITCH,
|
VR_CONFIG_MIRROR_AXIS_X, VR_CONFIG_MIRROR_AXIS_Y, VR_CONFIG_MIRROR_AXIS_Z,
|
||||||
VR_CONFIG_MIRROR_YAW,
|
VR_CONFIG_MIRROR_PITCH, VR_CONFIG_MIRROR_YAW, VR_CONFIG_MIRROR_ROLL,
|
||||||
VR_CONFIG_MIRROR_ROLL,
|
//2D canvas positioning
|
||||||
VR_CONFIG_3D_GEOMETRY_COUNT,
|
VR_CONFIG_MENU_PITCH, VR_CONFIG_MENU_YAW, VR_CONFIG_RECENTER_YAW,
|
||||||
VR_CONFIG_FOV_SCALE,
|
//mouse cursor
|
||||||
VR_CONFIG_FORCE_2D,
|
VR_CONFIG_MOUSE_SIZE, VR_CONFIG_MOUSE_X, VR_CONFIG_MOUSE_Y,
|
||||||
VR_CONFIG_CANVAS_DISTANCE,
|
//viewport size
|
||||||
|
VR_CONFIG_VIEWPORT_WIDTH, VR_CONFIG_VIEWPORT_HEIGHT,
|
||||||
|
|
||||||
|
//end
|
||||||
VR_CONFIG_MAX
|
VR_CONFIG_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1066,7 +1066,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsVRBuild()) {
|
if (IsVRBuild()) {
|
||||||
UpdateVRInput(NativeKey, g_Config.bHapticFeedback);
|
UpdateVRInput(NativeKey, NativeTouch, g_Config.bHapticFeedback, dp_xscale, dp_yscale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue