1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-04-21 03:21:51 +02:00

OpenVR Action Support (Platform Agnostic Controller Support) and HMD Based Rotation (#154)

* Initial OpenVr Testing

* Enabled headtracked movement for Lara, working on fusion of manual movement and headtracked

* Added reconfigurable action mapping support via SteamVR Input Bindings

* More intuitive controlscheme for WMR, should work on all headsets and controllers compatible with OpenVR/SteamVR

* Removed debugging output and fixed formatting, did I remove all the right files?

*  Did I remove the files correctly?

* Removed unwanted files

* Delete .gitignore

* Delete OpenLara.exp

* Delete OpenLara.lib

* Delete .suo~dcb08bfe01cc839fce41c7dcf9ff7088af2fedb7

* reverted/fixed .gitignore

* Update input.h

* Update lara.h

* Update lara.h

* Update level.h

* Update OpenLara.vcxproj

* Update OpenLara.vcxproj.user

* Update main.cpp

* Update camera.h

* Update lara.h

* reverting vcxproj* and .gitignore

* Update main.cpp

* Update main.cpp

* Update main.cpp
This commit is contained in:
mrhatkat 2019-01-31 01:34:56 -05:00 committed by Timur Gagiev
parent c52e7626d5
commit f5213e31f6
10 changed files with 1381 additions and 128 deletions

View File

@ -0,0 +1,75 @@
{
"actions" : [
{
"name" : "/actions/demo/in/Left",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Right",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Up",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Down",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Jump",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Walk",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Action",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Weapon",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Roll",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Inventory",
"type" : "boolean"
},
{
"name" : "/actions/demo/in/Start",
"type" : "boolean"
}
],
"default_bindings" : [
{
"binding_url" : "system_generated_openlara_exe_binding_holographic_controller.json",
"controller_type" : "holographic_controller"
}
],
"localization" : [
{
"/actions/demo/in/Action" : "Action",
"/actions/demo/in/AnalogInput" : "Analog Input",
"/actions/demo/in/Down" : "MoveDown",
"/actions/demo/in/Hand_Left" : "Left Hand Pose",
"/actions/demo/in/Hand_Right" : "Right Hand Pose",
"/actions/demo/in/Inventory" : "Inventory",
"/actions/demo/in/Jump" : "Jump",
"/actions/demo/in/Left" : "MoveLeft",
"/actions/demo/in/Right" : "MoveRight",
"/actions/demo/in/Roll" : "Roll",
"/actions/demo/in/Start" : "Start",
"/actions/demo/in/Up" : "MoveUp",
"/actions/demo/in/Walk" : "Walk",
"/actions/demo/in/Weapon" : "Weapon",
"/actions/demo/out/haptic_left" : "Left Haptic Feedback",
"/actions/demo/out/haptic_right" : "Right Haptic Feedback",
"language_tag" : "en_US"
}
]
}

BIN
bin/openvr_api.dll Normal file

Binary file not shown.

View File

@ -0,0 +1,120 @@
{
"alias_info" : {},
"app_key" : "system.generated.openlara.exe",
"bindings" : {
"/actions/demo" : {
"sources" : [
{
"inputs" : {
"east" : {
"output" : "/actions/demo/in/right"
},
"north" : {
"output" : "/actions/demo/in/up"
},
"south" : {
"output" : "/actions/demo/in/down"
},
"west" : {
"output" : "/actions/demo/in/left"
}
},
"mode" : "dpad",
"parameters" : {
"sub_mode" : "click"
},
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"east" : {
"output" : "/actions/demo/in/right"
},
"north" : {
"output" : "/actions/demo/in/up"
},
"south" : {
"output" : "/actions/demo/in/down"
},
"west" : {
"output" : "/actions/demo/in/left"
}
},
"mode" : "dpad",
"parameters" : {
"sub_mode" : "touch"
},
"path" : "/user/hand/left/input/joystick"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/jump"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/action"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/walk"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/weapon"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/trackpad"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/start"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/application_menu"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/inventory"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/application_menu"
},
{
"inputs" : {
"click" : {
"output" : "/actions/demo/in/roll"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/grip"
}
]
}
},
"controller_type" : "holographic_controller",
"description" : "",
"name" : "OpenLaraTestWMRBinding",
"options" : {},
"simulated_actions" : []
}

View File

@ -166,8 +166,9 @@ struct Camera : ICamera {
fpHead.pos -= joint.rot * vec3(0, 48, -24);
}
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR)
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR) {
fpHead.rot = quat(vec3(1, 0, 0), PI);
}
mViewInv.identity();
mViewInv.setRot(fpHead.rot);

View File

@ -494,6 +494,7 @@ struct Viewport {
namespace Core {
float eye;
Texture* eyeTex[2];
Viewport viewport, viewportDef;
mat4 mModel, mView, mProj, mViewProj, mViewInv;
mat4 mLightProj;

View File

@ -40,6 +40,7 @@ namespace Input {
mat4 controllers[2];
vec3 zero;
bool ready;
bool down[cMAX]; // internal state for VR controllers( based on actions not buttons)
void setView(const mat4 &pL, const mat4 &pR, const mat4 &vL, const mat4 &vR) {
proj[0] = pL;
@ -212,7 +213,7 @@ namespace Input {
Core::Settings::Controls &ctrl = Core::settings.controls[j];
for (int i = 0; i < cMAX; i++) {
KeySet &c = ctrl.keys[i];
newState[j][i] = (c.key != ikNone && down[c.key]) || (c.joy != jkNone && joy[ctrl.joyIndex].down[c.joy]);
newState[j][i] = (c.key != ikNone && down[c.key]) || (c.joy != jkNone && joy[ctrl.joyIndex].down[c.joy]) || hmd.down[i]; //adding vr check with hmd[down]
}
}

View File

@ -3040,28 +3040,13 @@ struct Lara : Character {
// VR control
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR && camera->firstPerson && canFreeRotate()) {
if (!(input & WALK)) {
input &= ~(LEFT | RIGHT);
}
vec3 ang = getAngleAbs(Input::hmd.head.dir().xyz());
angle.y = ang.y;
// rotFactor = vec2(1.0f);
// ang.y = shortAngle(angle.y, ang.y);
// if (fabsf(ang.y) > 5 * DEG2RAD)
// input |= ang.y < 0.0f ? LEFT : RIGHT;
if (stand == STAND_UNDERWATER) {
input &= ~(FORTH | BACK);
angle.x = ang.x;
// ang.x = shortAngle(angle.x, ang.x);
// if (fabsf(ang.x) > 5 * DEG2RAD)
// input |= ang.x < 0.0f ? FORTH : BACK;
}
}
return input;
}
@ -3091,9 +3076,9 @@ struct Lara : Character {
|| state == STATE_MIDAS_USE
|| state == STATE_MIDAS_DEATH
// make me sick!
// || state == STATE_BACK_JUMP
// || state == STATE_LEFT_JUMP
// || state == STATE_RIGHT_JUMP
//|| state == STATE_BACK_JUMP
//|| state == STATE_LEFT_JUMP
//|| state == STATE_RIGHT_JUMP
|| animation.index == ANIM_CLIMB_2
|| animation.index == ANIM_CLIMB_3
|| animation.index == ANIM_CLIMB_JUMP;

View File

@ -2696,34 +2696,34 @@ struct Level : IGame {
}
Core::pass = Core::passCompose;
/*
if (view == 0 && Input::hmd.ready) {
Core::settings.detail.vr = true;
Core::settings.detail.stereo = Core::Settings::STEREO_VR;
Texture *oldTarget = Core::defaultTarget;
vec4 vp = Core::viewportDef;
GAPI::Texture *oldTarget = Core::defaultTarget;
Viewport vp = Core::viewportDef;
Core::defaultTarget = Core::eyeTex[0];
Core::viewportDef = vec4(0, 0, float(Core::defaultTarget->width), float(Core::defaultTarget->height));
Core::setTarget(NULL, CLEAR_ALL);
Core::viewportDef = Viewport(0, 0, float(Core::defaultTarget->width), float(Core::defaultTarget->height));
Core::setTarget(NULL,Core::defaultTarget, 0); // changing to 0 and adding defaultTarget parameter
Core::eye = -1.0f;
setup();
renderView(camera->getRoomIndex(), true);
Core::defaultTarget = Core::eyeTex[1];
Core::viewportDef = vec4(0, 0, float(Core::defaultTarget->width), float(Core::defaultTarget->height));
Core::setTarget(NULL, CLEAR_ALL);
Core::viewportDef = Viewport(0, 0, float(Core::defaultTarget->width), float(Core::defaultTarget->height));
Core::setTarget(NULL, Core::defaultTarget, 0);
Core::eye = 1.0f;
setup();
renderView(camera->getRoomIndex(), true);
Core::settings.detail.vr = false;
//Core::settings.detail.vr = false;
Core::defaultTarget = oldTarget;
Core::setTarget(NULL, CLEAR_ALL);
Core::setTarget(NULL, Core::defaultTarget, 0);
Core::viewportDef = vp;
}
*/
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON) { // left/right SBS stereo
float oldEye = Core::eye;

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
// TODO: fix clipping
// TODO: add MSAA support for render targets
// TODO: add IK for arms
// TODO: controls
// TODO: controls (WIP)
// hint to the driver to use discrete GPU
extern "C" {
@ -593,13 +593,44 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
return 0;
}
//VR Support
#ifdef VR_SUPPORT
vr::IVRSystem *hmd;
vr::IVRSystem *hmd; // vrContext
vr::IVRRenderModels* rm; // not currently in use
vr::TrackedDevicePose_t tPose[vr::k_unMaxTrackedDeviceCount];
//eye textures(eventually)
//action handles
vr::VRActionHandle_t VRcLeft = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcRight = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcUp = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcDown = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcJump = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcWalk = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcAction = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcWeapon = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcRoll = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcLook = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcInventory = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcStart = vr::k_ulInvalidActionHandle;
vr::VRActionSetHandle_t m_actionsetDemo = vr::k_ulInvalidActionSetHandle;
vr::VRInputValueHandle_t m_leftHand = vr::k_ulInvalidInputValueHandle;
vr::VRInputValueHandle_t m_rightHand = vr::k_ulInvalidInputValueHandle;
//only in select TR games
vr::VRActionHandle_t VRcDuck = vr::k_ulInvalidActionHandle;
vr::VRActionHandle_t VRcDash = vr::k_ulInvalidActionHandle;
//
vr::VRActionSetHandle_t m_actionsetTR = vr::k_ulInvalidActionSetHandle;
void vrInit() {
vr::EVRInitError eError = vr::VRInitError_None;
hmd = vr::VR_Init(&eError, vr::VRApplication_Scene);
//rm = vr::VRRenderModels(); // initialize render models interface
if (eError != vr::VRInitError_None) {
hmd = NULL;
@ -612,13 +643,36 @@ void vrInit() {
LOG("! compositor initialization failed\n");
return;
}
//set manifest
vr::VRInput()->SetActionManifestPath("C:/Users/Austin/Desktop/OpenLaraGitTest2/OpenLara/bin/TombRaidervr_actions.json"); // needs absolutepath
// get action handles
vr::VRInput()->GetActionHandle("/actions/demo/in/Left", &VRcLeft);
vr::VRInput()->GetActionHandle("/actions/demo/in/Right", &VRcRight);
vr::VRInput()->GetActionHandle("/actions/demo/in/Up", &VRcUp);
vr::VRInput()->GetActionHandle("/actions/demo/in/Down", &VRcDown);
vr::VRInput()->GetActionHandle("/actions/demo/in/Jump", &VRcJump);
vr::VRInput()->GetActionHandle("/actions/demo/in/Walk", &VRcWalk);
vr::VRInput()->GetActionHandle("/actions/demo/in/Action", &VRcAction);
vr::VRInput()->GetActionHandle("/actions/demo/in/Weapon", &VRcWeapon);
vr::VRInput()->GetActionHandle("/actions/demo/in/Roll", &VRcRoll);
vr::VRInput()->GetActionHandle("/actions/demo/in/Inventory", &VRcInventory);
vr::VRInput()->GetActionHandle("/actions/demo/in/Start", &VRcStart);
//get actionsethandle
vr::VRInput()->GetActionSetHandle("/actions/demo", &m_actionsetDemo);
//get input source handles
vr::VRInput()->GetInputSourceHandle("/user/hand/left", &m_leftHand);
vr::VRInput()->GetInputSourceHandle("/user/hand/right", &m_rightHand);
// aren't using right now
//vr::VRInput()->GetActionHandle("/actions/demo/in/TriggerHaptic", &m_actionTriggerHaptic);
//vr::VRInput()->GetActionHandle("/actions/demo/in/AnalogInput", &m_actionAnalongInput);
}
void vrInitTargets() {
uint32_t width, height;
hmd->GetRecommendedRenderTargetSize( &width, &height);
eyeTex[0] = new Texture(width, height, Texture::RGBA);
eyeTex[1] = new Texture(width, height, Texture::RGBA);
Core::eyeTex[0] = new Texture(width, height, TexFormat::FMT_RGBA);
Core::eyeTex[1] = new Texture(width, height, TexFormat::FMT_RGBA);
}
void vrFree() {
@ -639,33 +693,74 @@ mat4 convToMat4(const vr::HmdMatrix34_t &m) {
m.m[0][2], m.m[1][2], m.m[2][2], 0.0f,
m.m[0][3], m.m[1][3], m.m[2][3], 1.0f);
}
//utility function for reading digital state
bool GetDigitalActionState(vr::VRActionHandle_t action, vr::VRInputValueHandle_t *pDevicePath = nullptr)
{
vr::InputDigitalActionData_t actionData;
vr::VRInput()->GetDigitalActionData(action, &actionData, sizeof(actionData), vr::k_ulInvalidInputValueHandle);
if (pDevicePath)
{
*pDevicePath = vr::k_ulInvalidInputValueHandle;
if (actionData.bActive)
{
vr::InputOriginInfo_t originInfo;
if (vr::VRInputError_None == vr::VRInput()->GetOriginTrackedDeviceInfo(actionData.activeOrigin, &originInfo, sizeof(originInfo)))
{
*pDevicePath = originInfo.devicePath;
}
}
}
return actionData.bActive && actionData.bState;
}
void vrUpdateInput() {
void ProcessVREvent(const vr::VREvent_t &event) {
char buffer[1024] = "test";
switch (event.eventType) {
case vr::VREvent_TrackedDeviceActivated:
//SetupRenderModelForTrackedDevice( event.trackedDeviceIndex );
vr::RenderModel_t ** controllerRender;
hmd->GetStringTrackedDeviceProperty(event.trackedDeviceIndex, vr::ETrackedDeviceProperty::Prop_RenderModelName_String, buffer, 1024); // can be filled with an error,but I can't find the right type
//rm->LoadRenderModel_Async(buffer, controllerRender);
// need to process render model?
LOG("Device %u attached. Setting up render model\n", event.trackedDeviceIndex);
break;
case vr::VREvent_TrackedDeviceDeactivated:
LOG("Device %u detached.\n", event.trackedDeviceIndex);
break;
case vr::VREvent_TrackedDeviceUpdated: //not sure what to do here
LOG("Device %u updated.\n", event.trackedDeviceIndex);
break;
}
}
//taken from openvrsimpleexamples
void vrUpdateInput() { // going to use action manifest and ivr:input(Steam Vr Input) // broken
if (!hmd) return;
vr::VREvent_t event;
while (hmd->PollNextEvent(&event, sizeof(event))) {
//ProcessVREvent( event );
switch (event.eventType) {
case vr::VREvent_TrackedDeviceActivated:
//SetupRenderModelForTrackedDevice( event.trackedDeviceIndex );
LOG( "Device %u attached. Setting up render model\n", event.trackedDeviceIndex);
break;
case vr::VREvent_TrackedDeviceDeactivated:
LOG("Device %u detached.\n", event.trackedDeviceIndex);
break;
case vr::VREvent_TrackedDeviceUpdated:
LOG("Device %u updated.\n", event.trackedDeviceIndex);
break;
}
ProcessVREvent( event ); // eventually going to be the function for this while loop
}
for (vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++) {
vr::VRControllerState_t state;
if (hmd->GetControllerState(unDevice, &state, sizeof(state))) {
//m_rbShowTrackedDevice[ unDevice ] = state.ulButtonPressed == 0;
}
}
//process actions( set hmd down)
vr::VRActiveActionSet_t actionSet = { 0 };
actionSet.ulActionSet = m_actionsetDemo;
vr::VRInput()->UpdateActionState(&actionSet, sizeof(actionSet), 1);
Input::hmd.down[cUp] = GetDigitalActionState(VRcUp);
Input::hmd.down[cDown] = GetDigitalActionState(VRcDown);
Input::hmd.down[cRight] = GetDigitalActionState(VRcRight);
Input::hmd.down[cLeft] = GetDigitalActionState(VRcLeft);
Input::hmd.down[cJump] = GetDigitalActionState(VRcJump);
Input::hmd.down[cWalk] = GetDigitalActionState(VRcWalk);
Input::hmd.down[cAction] = GetDigitalActionState(VRcAction);
Input::hmd.down[cWeapon] = GetDigitalActionState(VRcWeapon);
Input::hmd.down[cRoll] = GetDigitalActionState(VRcRoll);
Input::hmd.down[cStart] = GetDigitalActionState(VRcStart);
Input::hmd.down[cInventory] = GetDigitalActionState(VRcInventory);
}
void vrUpdateView() {
@ -688,8 +783,9 @@ void vrUpdateView() {
vL.setPos(vL.getPos() * ONE_METER);
vR.setPos(vR.getPos() * ONE_METER);
Input::hmd.setView(pL, pR, vL, vR);
// pass this to Lara's rotation value
Input::hmd.head = head;
}
void vrCompose() {
@ -822,4 +918,4 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
#endif
return 0;
}
}