From 0189d4bb165208bb034ac4c6fb009c1196fcc8d4 Mon Sep 17 00:00:00 2001 From: Holger Frydrych Date: Sun, 27 Aug 2023 00:29:36 +0200 Subject: [PATCH] wip Immersive ladder climbing --- .../Solution1/CryGame/GameShared.h | 3 +- .../Solution1/CryGame/ScriptObjectPlayer.cpp | 23 ++++++--- .../CryGame C++/Solution1/CryGame/VRInput.cpp | 12 +++-- .../CryGame C++/Solution1/CryGame/VRInput.h | 4 +- .../Solution1/CryGame/VRManager.cpp | 1 + .../CryGame C++/Solution1/CryGame/VRManager.h | 1 + .../CryGame C++/Solution1/CryGame/XClient.cpp | 9 +++- .../CryGame C++/Solution1/CryGame/XClient.h | 3 +- .../CryGame C++/Solution1/CryGame/XPlayer.cpp | 48 ++++++++++++++++++- .../CryGame C++/Solution1/CryGame/XPlayer.h | 6 +++ steamvr/actions.json | 8 ++-- steamvr/actions_en_us.json | 2 +- steamvr/bindings_knuckles.json | 27 +++++++---- steamvr/bindings_touch.json | 27 +++++++---- 14 files changed, 132 insertions(+), 42 deletions(-) diff --git a/Sources/CryGame C++/Solution1/CryGame/GameShared.h b/Sources/CryGame C++/Solution1/CryGame/GameShared.h index 663d3f5..b439067 100644 --- a/Sources/CryGame C++/Solution1/CryGame/GameShared.h +++ b/Sources/CryGame C++/Solution1/CryGame/GameShared.h @@ -102,7 +102,8 @@ typedef unsigned char ACTIONTYPE; #define ACTION_MOVEMODE_TOGGLE 63 #define ACTION_AIM_TOGGLE 64 #define ACTION_MOVEMODE_SWITCH 65 -#define ACTION_TWOHAND_GRIP 66 +#define ACTION_GRIP_LEFT 66 +#define ACTION_GRIP_RIGHT 67 #define PLAYER_MAX_WEAPONS 9 diff --git a/Sources/CryGame C++/Solution1/CryGame/ScriptObjectPlayer.cpp b/Sources/CryGame C++/Solution1/CryGame/ScriptObjectPlayer.cpp index 2b51346..520b072 100644 --- a/Sources/CryGame C++/Solution1/CryGame/ScriptObjectPlayer.cpp +++ b/Sources/CryGame C++/Solution1/CryGame/ScriptObjectPlayer.cpp @@ -27,6 +27,8 @@ #include "ScriptObjectVector.h" #include +#include "VRManager.h" + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -2285,8 +2287,9 @@ int CScriptObjectPlayer::UseLadder(IFunctionHandler *pH) } else { - if(onLadder!=0) + if(onLadder!=0 && !m_pPlayer->m_stats.onLadder) { + m_pPlayer->m_insideLadderVolume = true; m_pPlayer->m_PrevWeaponID=m_pPlayer->GetSelectedWeaponId(); m_pPlayer->SelectWeapon(-1); m_pPlayer->m_stats.onLadder = true; @@ -2319,10 +2322,10 @@ int CScriptObjectPlayer::UseLadder(IFunctionHandler *pH) m_pPlayer->m_vLadderAngles.Set(0,0,0); } - else + else if (onLadder == 0) { // restore speeds only if saved before - if(m_fSpeedRun) + if (m_fSpeedRun) { m_pPlayer->SetRunSpeed(m_fSpeedRun); m_pPlayer->SetWalkSpeed(m_fSpeedWalk); @@ -2330,9 +2333,17 @@ int CScriptObjectPlayer::UseLadder(IFunctionHandler *pH) m_pPlayer->SetProneSpeed(m_fSpeedProne); } - m_pPlayer->m_stats.onLadder = false; - if (m_pPlayer->m_PrevWeaponID>=0) - m_pPlayer->SelectWeapon(m_pPlayer->m_PrevWeaponID); + if (gVR->vr_immersive_ladders && m_pPlayer->m_activeHandGrabbingLadder != -1) + { + // stick to ladder until player lets go + m_pPlayer->m_insideLadderVolume = false; + } + else + { + m_pPlayer->m_stats.onLadder = false; + if (m_pPlayer->m_PrevWeaponID >= 0) + m_pPlayer->SelectWeapon(m_pPlayer->m_PrevWeaponID); + } } m_pPlayer->InitCameraTransition( CPlayer::PCM_CASUAL, true ); diff --git a/Sources/CryGame C++/Solution1/CryGame/VRInput.cpp b/Sources/CryGame C++/Solution1/CryGame/VRInput.cpp index 0eb71a1..a8b7134 100644 --- a/Sources/CryGame C++/Solution1/CryGame/VRInput.cpp +++ b/Sources/CryGame C++/Solution1/CryGame/VRInput.cpp @@ -52,6 +52,7 @@ bool VRInput::Init(CXGame* game) vr::VRInput()->GetActionHandle("/actions/default/in/binoculars", &m_defaultBinoculars); vr::VRInput()->GetActionHandle("/actions/default/in/zoomin", &m_defaultZoomIn); vr::VRInput()->GetActionHandle("/actions/default/in/zoomout", &m_defaultZoomOut); + vr::VRInput()->GetActionHandle("/actions/default/in/grip", &m_defaultGrip); vr::VRInput()->GetActionHandle("/actions/move/in/move", &m_moveMove); vr::VRInput()->GetActionHandle("/actions/move/in/continuousturn", &m_moveTurn); @@ -73,7 +74,6 @@ bool VRInput::Init(CXGame* game) vr::VRInput()->GetActionHandle("/actions/weapons/in/fire", &m_weaponsFire); InitDoubleBindAction(m_weaponsReloadFireMode, "/actions/weapons/in/reload"); InitDoubleBindAction(m_weaponsNextDrop, "/actions/weapons/in/next"); - vr::VRInput()->GetActionHandle("/actions/weapons/in/grip", &m_weaponsGrip); InitDoubleBindAction(m_weaponsGrenades, "/actions/weapons/in/grenades"); m_pGame = game; @@ -176,7 +176,8 @@ void VRInput::ProcessInputOnFoot() HandleAnalogAction(m_moveMove, 1, &CXClient::TriggerMoveFB); HandleBooleanAction(m_weaponsFire, &CXClient::TriggerFire0); HandleDoubleBindAction(m_weaponsReloadFireMode, &CXClient::TriggerReload, &CXClient::TriggerFireMode, false); - HandleBooleanAction(m_weaponsGrip, &CXClient::TriggerTwoHandedGrip); + HandleBooleanAction(m_defaultGrip, &CXClient::TriggerLeftGrip, true, m_handHandle[0]); + HandleBooleanAction(m_defaultGrip, &CXClient::TriggerRightGrip, true, m_handHandle[1]); } void VRInput::ProcessInputInVehicles() @@ -205,8 +206,9 @@ void VRInput::ProcessInputInVehicles() HandleBooleanAction(m_weaponsFire, &CXClient::TriggerFire0); HandleDoubleBindAction(m_weaponsReloadFireMode, &CXClient::TriggerReload, &CXClient::TriggerFireMode, false); HandleDoubleBindAction(m_weaponsNextDrop, &CXClient::TriggerNextWeapon, &CXClient::TriggerDropWeapon, false); - HandleBooleanAction(m_weaponsGrip, &CXClient::TriggerTwoHandedGrip); HandleDoubleBindAction(m_weaponsGrenades, &CXClient::CycleGrenade, &CXClient::TriggerFireGrenade, false); + HandleBooleanAction(m_defaultGrip, &CXClient::TriggerLeftGrip, true, m_handHandle[0]); + HandleBooleanAction(m_defaultGrip, &CXClient::TriggerRightGrip, true, m_handHandle[1]); } HandleBooleanAction(m_vehiclesLeave, &CXClient::TriggerUse, false); @@ -248,10 +250,10 @@ Matrix34 VRInput::GetControllerTransform(int hand) return OpenVRToFarCry(data.pose.mDeviceToAbsoluteTracking) * correction; } -void VRInput::HandleBooleanAction(vr::VRActionHandle_t actionHandle, TriggerFn trigger, bool continuous) +void VRInput::HandleBooleanAction(vr::VRActionHandle_t actionHandle, TriggerFn trigger, bool continuous, vr::VRInputValueHandle_t restrictToDevice) { vr::InputDigitalActionData_t actionData; - vr::VRInput()->GetDigitalActionData(actionHandle, &actionData, sizeof(vr::InputDigitalActionData_t), vr::k_ulInvalidInputValueHandle); + vr::VRInput()->GetDigitalActionData(actionHandle, &actionData, sizeof(vr::InputDigitalActionData_t), restrictToDevice); if (actionData.bActive && actionData.bState && (continuous || actionData.bChanged)) { (m_pGame->GetClient()->*trigger)(1.f, XActivationEvent()); diff --git a/Sources/CryGame C++/Solution1/CryGame/VRInput.h b/Sources/CryGame C++/Solution1/CryGame/VRInput.h index fc0d43c..edb91d6 100644 --- a/Sources/CryGame C++/Solution1/CryGame/VRInput.h +++ b/Sources/CryGame C++/Solution1/CryGame/VRInput.h @@ -40,6 +40,7 @@ class VRInput vr::VRActionHandle_t m_defaultBinoculars = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_defaultZoomIn = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_defaultZoomOut = vr::k_ulInvalidActionHandle; + vr::VRActionHandle_t m_defaultGrip = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_moveMove = vr::k_ulInvalidActionHandle; vr::VRActionHandle_t m_moveTurn = vr::k_ulInvalidActionHandle; @@ -61,12 +62,11 @@ class VRInput vr::VRActionHandle_t m_weaponsFire = vr::k_ulInvalidActionHandle; DoubleBindAction m_weaponsReloadFireMode; DoubleBindAction m_weaponsNextDrop; - vr::VRActionHandle_t m_weaponsGrip = vr::k_ulInvalidActionHandle; DoubleBindAction m_weaponsGrenades; using TriggerFn = void (CXClient::*)(float value, XActivationEvent ae); - void HandleBooleanAction(vr::VRActionHandle_t actionHandle, TriggerFn trigger, bool continuous = true); + void HandleBooleanAction(vr::VRActionHandle_t actionHandle, TriggerFn trigger, bool continuous = true, vr::VRInputValueHandle_t restrictToDevice = vr::k_ulInvalidInputValueHandle); void HandleAnalogAction(vr::VRActionHandle_t actionHandle, int axis, TriggerFn trigger); float GetFloatValue(vr::VRActionHandle_t actionHandle, int axis = 0, bool *isActive = nullptr); diff --git a/Sources/CryGame C++/Solution1/CryGame/VRManager.cpp b/Sources/CryGame C++/Solution1/CryGame/VRManager.cpp index 865d149..bd9040c 100644 --- a/Sources/CryGame C++/Solution1/CryGame/VRManager.cpp +++ b/Sources/CryGame C++/Solution1/CryGame/VRManager.cpp @@ -894,6 +894,7 @@ void VRManager::RegisterCVars() console->Register("vr_crosshair", &vr_crosshair, 1, VF_DUMPTODISK, "VR crosshair type. 0 - none, 1 - ball, 2 - laser"); console->Register("vr_movement_dir", &vr_movement_dir, -1, VF_DUMPTODISK, "Movement direction reference: -1 = head, 0 = left hand, 1 = right hand"); console->Register("vr_show_empty_hands", &vr_show_empty_hands, 1, VF_DUMPTODISK, "If enabled, draws empty player hands when appropriate"); + console->Register("vr_immersive_ladders", &vr_immersive_ladders, 1, VF_DUMPTODISK, "Climb ladders by grabbing with your hands"); vr_debug_override_rh_offset = console->CreateVariable("vr_debug_override_rh_offset", "0.0 -0.1 -0.018", VF_CHEAT); vr_debug_override_lh_offset = console->CreateVariable("vr_debug_override_lh_offset", "0.0 -0.1 -0.018", VF_CHEAT); vr_debug_override_rh_angles = console->CreateVariable("vr_debug_override_rh_angles", "0.0 0.0 0.0", VF_CHEAT); diff --git a/Sources/CryGame C++/Solution1/CryGame/VRManager.h b/Sources/CryGame C++/Solution1/CryGame/VRManager.h index b0a2c16..596f0fd 100644 --- a/Sources/CryGame C++/Solution1/CryGame/VRManager.h +++ b/Sources/CryGame C++/Solution1/CryGame/VRManager.h @@ -112,6 +112,7 @@ class VRManager int vr_crosshair; int vr_movement_dir; int vr_show_empty_hands; + int vr_immersive_ladders; ICVar* vr_debug_override_rh_offset = nullptr; ICVar* vr_debug_override_rh_angles = nullptr; ICVar* vr_debug_override_lh_offset = nullptr; diff --git a/Sources/CryGame C++/Solution1/CryGame/XClient.cpp b/Sources/CryGame C++/Solution1/CryGame/XClient.cpp index 65c29d5..fdcf931 100644 --- a/Sources/CryGame C++/Solution1/CryGame/XClient.cpp +++ b/Sources/CryGame C++/Solution1/CryGame/XClient.cpp @@ -1975,9 +1975,14 @@ void CXClient::CycleGrenade(float fValue,XActivationEvent ae) m_PlayerProcessingCmd.AddAction( ACTION_CYCLE_GRENADE ); } -void CXClient::TriggerTwoHandedGrip(float fValue, XActivationEvent ae) +void CXClient::TriggerLeftGrip(float fValue, XActivationEvent ae) { - m_PlayerProcessingCmd.AddAction(ACTION_TWOHAND_GRIP); + m_PlayerProcessingCmd.AddAction(ACTION_GRIP_LEFT); +} + +void CXClient::TriggerRightGrip(float fValue, XActivationEvent ae) +{ + m_PlayerProcessingCmd.AddAction(ACTION_GRIP_RIGHT); } void CXClient::TriggerScoreBoard(float fValue, XActivationEvent ae) diff --git a/Sources/CryGame C++/Solution1/CryGame/XClient.h b/Sources/CryGame C++/Solution1/CryGame/XClient.h index 464f064..c6ab31a 100644 --- a/Sources/CryGame C++/Solution1/CryGame/XClient.h +++ b/Sources/CryGame C++/Solution1/CryGame/XClient.h @@ -239,7 +239,8 @@ public IEntitySystemSink void TriggerWeapon14(float fValue,XActivationEvent ae); void TriggerDropWeapon(float fValue,XActivationEvent ae); void CycleGrenade(float fValue,XActivationEvent ae); - void TriggerTwoHandedGrip(float fValue, XActivationEvent ae); + void TriggerLeftGrip(float fValue, XActivationEvent ae); + void TriggerRightGrip(float fValue, XActivationEvent ae); void TriggerScoreBoard(float fValue, XActivationEvent ae); //client side diff --git a/Sources/CryGame C++/Solution1/CryGame/XPlayer.cpp b/Sources/CryGame C++/Solution1/CryGame/XPlayer.cpp index 979d36e..b3eb6c3 100644 --- a/Sources/CryGame C++/Solution1/CryGame/XPlayer.cpp +++ b/Sources/CryGame C++/Solution1/CryGame/XPlayer.cpp @@ -1898,6 +1898,46 @@ void CPlayer::ProcessMovements(CXEntityProcessingCmd &cmd, bool bScheduled) else m_stats.back_pressed = false; + if (m_stats.onLadder && gVR->vr_immersive_ladders) + { + speedxyz[2] = 0; + + bool grabbing[2] = { cmd.CheckAction(ACTION_GRIP_LEFT), cmd.CheckAction(ACTION_GRIP_RIGHT) }; + bool newActive[2] = { grabbing[0] && !m_wasGrabbingLadder[0], grabbing[1] && !m_wasGrabbingLadder[1] }; + for (int i = 0; i < 2; ++i) + { + if (newActive[i]) + { + m_activeHandGrabbingLadder = i; + m_prevLadderGrabPos = GetWorldControllerTransform(i).GetTranslation(); + } + if (m_activeHandGrabbingLadder == i) + { + Vec3 curGrabPos = GetWorldControllerTransform(i).GetTranslation(); + Vec3 diff = curGrabPos - m_prevLadderGrabPos; + speedxyz[2] = -diff.z / m_pGame->GetSystem()->GetITimer()->GetFrameTime() * 5; + if (speedxyz[2] > 0) + { + // add a bit of forward movement for dismounts at the top + speedxyz[0] = -m_psin * 0.50f; + speedxyz[1] = m_pcos * 0.50f; + } + m_prevLadderGrabPos = curGrabPos; + } + m_wasGrabbingLadder[i] = grabbing[i]; + } + if (!grabbing[0] && !grabbing[1]) + m_activeHandGrabbingLadder = -1; + + if (m_activeHandGrabbingLadder == -1 && !m_insideLadderVolume) + { + // no longer inside ladder volume and not grabbing, so let go + m_stats.onLadder = false; + if (m_PrevWeaponID >= 0) + SelectWeapon(m_PrevWeaponID); + } + } + bool bStrafe = false; if (cmd.CheckAction(ACTION_MOVE_LEFT)) //&& !m_stats.onLadder) { @@ -2040,6 +2080,9 @@ void CPlayer::ProcessMovements(CXEntityProcessingCmd &cmd, bool bScheduled) else inputspeed *= fSpeedScale; + if (m_stats.onLadder && gVR->vr_immersive_ladders && m_activeHandGrabbingLadder != -1) + inputspeed = speedxyz.Length(); + speedxyz.Normalize(); speedxyz*=inputspeed; } @@ -2250,7 +2293,8 @@ void CPlayer::ProcessWeapons(CXEntityProcessingCmd &cmd) // do not allow to use weapons and move when underwater or in a water volume, and // he is actively swimming - bool twoHandGrip = cmd.CheckAction(ACTION_TWOHAND_GRIP); + unsigned offhandGrip = m_offHand == 0 ? ACTION_GRIP_LEFT : ACTION_GRIP_RIGHT; + bool twoHandGrip = cmd.CheckAction(offhandGrip); if (m_wasTwoHandGrip != twoHandGrip && twoHandGrip) { TryEnableTwoHandedWeaponMode(); @@ -2448,7 +2492,7 @@ void CPlayer::ProcessRoomscaleMovement(CXEntityProcessingCmd& ProcessingCmd) if (!ProcessingCmd.UseMotionControls()) return; - if (GetVehicle() || m_pMountedWeapon) + if (GetVehicle() || m_pMountedWeapon || (m_stats.onLadder && gVR->vr_immersive_ladders)) return; Ang3 angles = m_pEntity->GetAngles(); diff --git a/Sources/CryGame C++/Solution1/CryGame/XPlayer.h b/Sources/CryGame C++/Solution1/CryGame/XPlayer.h index faff6a0..19b66f2 100644 --- a/Sources/CryGame C++/Solution1/CryGame/XPlayer.h +++ b/Sources/CryGame C++/Solution1/CryGame/XPlayer.h @@ -1173,6 +1173,12 @@ enum eInVehiclestate // visible bare hands CHand* m_handModel[2] = { nullptr }; + +public: + bool m_wasGrabbingLadder[2] = { false, false }; + int m_activeHandGrabbingLadder = -1; + Vec3 m_prevLadderGrabPos; + bool m_insideLadderVolume = false; }; #endif // __GAME_PLAYER_H__ diff --git a/steamvr/actions.json b/steamvr/actions.json index dbcd497..d6b2b54 100644 --- a/steamvr/actions.json +++ b/steamvr/actions.json @@ -63,6 +63,10 @@ "name" : "/actions/default/in/ZoomOut", "type" : "boolean" }, + { + "name": "/actions/default/in/Grip", + "type": "boolean" + }, { "name" : "/actions/move/in/Move", "type" : "vector2" @@ -135,10 +139,6 @@ "name": "/actions/weapons/in/Next", "type": "boolean" }, - { - "name": "/actions/weapons/in/Grip", - "type": "boolean" - }, { "name": "/actions/weapons/in/Grenades", "type": "boolean" diff --git a/steamvr/actions_en_us.json b/steamvr/actions_en_us.json index 126992d..2fba415 100644 --- a/steamvr/actions_en_us.json +++ b/steamvr/actions_en_us.json @@ -9,6 +9,7 @@ "/actions/default/in/Binoculars": "Activate binoculars", "/actions/default/in/ZoomIn": "Zoom in", "/actions/default/in/ZoomOut": "Zoom out", + "/actions/default/in/Grip": "Grab", "/actions/move": "Movement", "/actions/move/in/Move": "Move", "/actions/move/in/ContinuousTurn": "Smooth turn", @@ -21,7 +22,6 @@ "/actions/weapons/in/Fire": "Fire weapon", "/actions/weapons/in/Reload": "Reload weapon", "/actions/weapons/in/Next": "Next weapon / drop weapon", - "/actions/weapons/in/Grip": "Activate two-hand mode", "/actions/weapons/in/Grenades": "Cycle / throw grenades", "/actions/vehicles": "Vehicles", "/actions/vehicles/in/Steer": "Steer vehicle", diff --git a/steamvr/bindings_knuckles.json b/steamvr/bindings_knuckles.json index 583653a..fa88f72 100644 --- a/steamvr/bindings_knuckles.json +++ b/steamvr/bindings_knuckles.json @@ -57,6 +57,24 @@ } } }, + { + "path": "/user/hand/left/input/grip", + "mode": "button", + "inputs": { + "click": { + "output": "/actions/default/in/grip" + } + } + }, + { + "path": "/user/hand/right/input/grip", + "mode": "button", + "inputs": { + "click": { + "output": "/actions/default/in/grip" + } + } + }, { "inputs" : { "north" : { @@ -269,15 +287,6 @@ } } }, - { - "path": "/user/hand/left/input/grip", - "mode": "button", - "inputs": { - "click": { - "output": "/actions/weapons/in/grip" - } - } - }, { "path": "/user/hand/right/input/b", "mode": "button", diff --git a/steamvr/bindings_touch.json b/steamvr/bindings_touch.json index 3f3b98c..62a2a57 100644 --- a/steamvr/bindings_touch.json +++ b/steamvr/bindings_touch.json @@ -57,6 +57,24 @@ } } }, + { + "path": "/user/hand/left/input/grip", + "mode": "button", + "inputs": { + "click": { + "output": "/actions/default/in/grip" + } + } + }, + { + "path": "/user/hand/right/input/grip", + "mode": "button", + "inputs": { + "click": { + "output": "/actions/default/in/grip" + } + } + }, { "inputs" : { "north" : { @@ -269,15 +287,6 @@ } } }, - { - "path": "/user/hand/left/input/grip", - "mode": "button", - "inputs": { - "click": { - "output": "/actions/weapons/in/grip" - } - } - }, { "path": "/user/hand/right/input/b", "mode": "button",