diff --git a/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp b/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp index e203529..8da4585 100644 --- a/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp +++ b/Projects/Android/jni/JKVR/JKVR_SurfaceView.cpp @@ -1308,8 +1308,10 @@ void JKVR_Init() vr_immersive_cinematics = Cvar_Get("vr_immersive_cinematics", "1", CVAR_ARCHIVE); vr_screen_dist = Cvar_Get( "vr_screen_dist", "2.5", CVAR_ARCHIVE); - vr_weapon_velocity_trigger = Cvar_Get( "vr_weapon_velocity_trigger", "2.3", CVAR_ARCHIVE); + vr_weapon_velocity_trigger = Cvar_Get( "vr_weapon_velocity_trigger", "2.0", CVAR_ARCHIVE); + vr_force_velocity_trigger = Cvar_Get( "vr_force_velocity_trigger", "2.0", CVAR_ARCHIVE); vr_two_handed_weapons = Cvar_Get ("vr_two_handed_weapons", "1", CVAR_ARCHIVE); + vr_force_motion_controlled = Cvar_Get ("vr_force_motion_controlled", "1", CVAR_ARCHIVE); cvar_t *expanded_menu_enabled = Cvar_Get ("expanded_menu_enabled", "0", CVAR_ARCHIVE); if (FS_FileExists("expanded_menu.pk3")) { diff --git a/Projects/Android/jni/JKVR/VrClientInfo.h b/Projects/Android/jni/JKVR/VrClientInfo.h index 21293e6..ba12f31 100644 --- a/Projects/Android/jni/JKVR/VrClientInfo.h +++ b/Projects/Android/jni/JKVR/VrClientInfo.h @@ -61,6 +61,7 @@ typedef struct { bool primaryVelocityTriggeredAttack; float secondaryswingvelocity; bool secondaryVelocityTriggeredAttack; + vec3_t secondaryVelocityTriggerLocation; vec3_t offhandangles; vec3_t offhandangles_last; // Don't use this, it is just for calculating delta! diff --git a/Projects/Android/jni/JKVR/VrCvars.h b/Projects/Android/jni/JKVR/VrCvars.h index 4f8aaa0..e3225a3 100644 --- a/Projects/Android/jni/JKVR/VrCvars.h +++ b/Projects/Android/jni/JKVR/VrCvars.h @@ -10,5 +10,7 @@ extern cvar_t *vr_switch_sticks; extern cvar_t *vr_immersive_cinematics; extern cvar_t *vr_screen_dist; extern cvar_t *vr_weapon_velocity_trigger; +extern cvar_t *vr_force_velocity_trigger; extern cvar_t *vr_two_handed_weapons; +extern cvar_t *vr_force_motion_controlled; diff --git a/Projects/Android/jni/JKVR/VrInputCommon.cpp b/Projects/Android/jni/JKVR/VrInputCommon.cpp index 37ec6a5..168ea8f 100644 --- a/Projects/Android/jni/JKVR/VrInputCommon.cpp +++ b/Projects/Android/jni/JKVR/VrInputCommon.cpp @@ -30,7 +30,9 @@ cvar_t *vr_switch_sticks; cvar_t *vr_immersive_cinematics; cvar_t *vr_screen_dist; cvar_t *vr_weapon_velocity_trigger; +cvar_t *vr_force_velocity_trigger; cvar_t *vr_two_handed_weapons; +cvar_t *vr_force_motion_controlled; ovrInputStateTrackedRemote leftTrackedRemoteState_old; ovrInputStateTrackedRemote leftTrackedRemoteState_new; diff --git a/Projects/Android/jni/JKVR/VrInputDefault.cpp b/Projects/Android/jni/JKVR/VrInputDefault.cpp index c133f54..d5170c6 100644 --- a/Projects/Android/jni/JKVR/VrInputDefault.cpp +++ b/Projects/Android/jni/JKVR/VrInputDefault.cpp @@ -264,485 +264,515 @@ void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateG } } - //if (!vr.item_selector) + //Engage scope / virtual stock if conditions are right + bool scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE); + static bool lastScopeReady = qfalse; + if (scopeready != lastScopeReady) { + if (vr.scopedweapon && !vr.scopedetached) { + if (!vr.scopeengaged && scopeready) { + ALOGV("**WEAPON EVENT** trigger scope mode"); + sendButtonActionSimple("weapalt"); + } else if (vr.scopeengaged && !scopeready) { + ALOGV("**WEAPON EVENT** disable scope mode"); + sendButtonActionSimple("weapalt"); + } + lastScopeReady = scopeready; + } + } + + //Engage scope / virtual stock (iron sight lock) if conditions are right + static bool scopeEngaged = qfalse; + if (scopeEngaged != vr.scopeengaged) { + scopeEngaged = vr.scopeengaged; + } + + //dominant hand stuff first { - //Engage scope / virtual stock if conditions are right - bool scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE); - static bool lastScopeReady = qfalse; - if (scopeready != lastScopeReady) { - if (vr.scopedweapon && !vr.scopedetached) { - if (!vr.scopeengaged && scopeready) { - ALOGV("**WEAPON EVENT** trigger scope mode"); - sendButtonActionSimple("weapalt"); - } else if (vr.scopeengaged && !scopeready) { - ALOGV("**WEAPON EVENT** disable scope mode"); - sendButtonActionSimple("weapalt"); - } - lastScopeReady = scopeready; - } + //Record recent weapon position for trajectory based stuff + for (int i = (NUM_WEAPON_SAMPLES - 1); i != 0; --i) { + VectorCopy(vr.weaponoffset_history[i - 1], vr.weaponoffset_history[i]); + vr.weaponoffset_history_timestamp[i] = vr.weaponoffset_history_timestamp[i - 1]; } + VectorCopy(vr.weaponoffset, vr.weaponoffset_history[0]); + vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp; - //Engage scope / virtual stock (iron sight lock) if conditions are right - static bool scopeEngaged = qfalse; - if (scopeEngaged != vr.scopeengaged) { - scopeEngaged = vr.scopeengaged; - } + VectorSet(vr.weaponposition, pWeapon->HeadPose.Pose.Position.x, + pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z); - //dominant hand stuff first - { - //Record recent weapon position for trajectory based stuff - for (int i = (NUM_WEAPON_SAMPLES - 1); i != 0; --i) { - VectorCopy(vr.weaponoffset_history[i - 1], vr.weaponoffset_history[i]); - vr.weaponoffset_history_timestamp[i] = vr.weaponoffset_history_timestamp[i - 1]; - } - VectorCopy(vr.weaponoffset, vr.weaponoffset_history[0]); - vr.weaponoffset_history_timestamp[0] = vr.weaponoffset_timestamp; + ///Weapon location relative to view + VectorSet(vr.weaponoffset, pWeapon->HeadPose.Pose.Position.x, + pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z); + VectorSubtract(vr.weaponoffset, vr.hmdposition, vr.weaponoffset); + vr.weaponoffset_timestamp = Sys_Milliseconds(); - VectorSet(vr.weaponposition, pWeapon->HeadPose.Pose.Position.x, - pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z); + vec3_t velocity; + VectorSet(velocity, pWeapon->HeadPose.LinearVelocity.x, + pWeapon->HeadPose.LinearVelocity.y, pWeapon->HeadPose.LinearVelocity.z); + vr.primaryswingvelocity = VectorLength(velocity); - ///Weapon location relative to view - VectorSet(vr.weaponoffset, pWeapon->HeadPose.Pose.Position.x, - pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z); - VectorSubtract(vr.weaponoffset, vr.hmdposition, vr.weaponoffset); - vr.weaponoffset_timestamp = Sys_Milliseconds(); - - vec3_t velocity; - VectorSet(velocity, pWeapon->HeadPose.LinearVelocity.x, - pWeapon->HeadPose.LinearVelocity.y, pWeapon->HeadPose.LinearVelocity.z); - vr.primaryswingvelocity = VectorLength(velocity); - - VectorSet(velocity, pOff->HeadPose.LinearVelocity.x, - pOff->HeadPose.LinearVelocity.y, pOff->HeadPose.LinearVelocity.z); - vr.secondaryswingvelocity = VectorLength(velocity); + VectorSet(velocity, pOff->HeadPose.LinearVelocity.x, + pOff->HeadPose.LinearVelocity.y, pOff->HeadPose.LinearVelocity.z); + vr.secondaryswingvelocity = VectorLength(velocity); - //For melee right hand is alt attack and left hand is attack - if (vr.weaponid == WP_MELEE) { - //Does weapon velocity trigger attack (melee) and is it fast enough - if (vr.velocitytriggered) { - static bool fired = false; - vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > - vr_weapon_velocity_trigger->value); + //For melee right hand is alt attack and left hand is attack + if (vr.weaponid == WP_MELEE) { + //Does weapon velocity trigger attack (melee) and is it fast enough + if (vr.velocitytriggered) { + static bool fired = false; + vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > + vr_weapon_velocity_trigger->value); - if (fired != vr.primaryVelocityTriggeredAttack) { - ALOGV("**WEAPON EVENT** veocity triggered %s", - vr.primaryVelocityTriggeredAttack ? "+altattack" : "-altattack"); - //normal attack is a punch with the left hand - sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack); - fired = vr.primaryVelocityTriggeredAttack; - } - } else if (vr.primaryVelocityTriggeredAttack) { - //send a stop attack as we have an unfinished velocity attack - vr.primaryVelocityTriggeredAttack = false; - ALOGV("**WEAPON EVENT** veocity triggered -altattack"); + if (fired != vr.primaryVelocityTriggeredAttack) { + ALOGV("**WEAPON EVENT** veocity triggered %s", + vr.primaryVelocityTriggeredAttack ? "+altattack" : "-altattack"); + //normal attack is a punch with the left hand sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack); + fired = vr.primaryVelocityTriggeredAttack; } + } else if (vr.primaryVelocityTriggeredAttack) { + //send a stop attack as we have an unfinished velocity attack + vr.primaryVelocityTriggeredAttack = false; + ALOGV("**WEAPON EVENT** veocity triggered -altattack"); + sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack); + } - if (vr.velocitytriggered) { - static bool fired = false; - vr.secondaryVelocityTriggeredAttack = (vr.secondaryswingvelocity > - vr_weapon_velocity_trigger->value); + if (vr.velocitytriggered) { + static bool fired = false; + vr.secondaryVelocityTriggeredAttack = (vr.secondaryswingvelocity > + vr_weapon_velocity_trigger->value); - if (fired != vr.secondaryVelocityTriggeredAttack) { - ALOGV("**WEAPON EVENT** veocity triggered %s", - vr.secondaryVelocityTriggeredAttack ? "+attack" : "-attack"); - //normal attack is a punch with the left hand - sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack); - fired = vr.secondaryVelocityTriggeredAttack; - } - } else if (vr.secondaryVelocityTriggeredAttack) { - //send a stop attack as we have an unfinished velocity attack - vr.secondaryVelocityTriggeredAttack = qfalse; - ALOGV("**WEAPON EVENT** veocity triggered -attack"); + if (fired != vr.secondaryVelocityTriggeredAttack) { + ALOGV("**WEAPON EVENT** veocity triggered %s", + vr.secondaryVelocityTriggeredAttack ? "+attack" : "-attack"); + //normal attack is a punch with the left hand sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack); + fired = vr.secondaryVelocityTriggeredAttack; } - } else if (vr.weaponid == WP_SABER) { - //Does weapon velocity trigger attack - if (vr.velocitytriggered) { - static bool fired = false; - vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > - vr_weapon_velocity_trigger->value); + } else if (vr.secondaryVelocityTriggeredAttack) { + //send a stop attack as we have an unfinished velocity attack + vr.secondaryVelocityTriggeredAttack = qfalse; + ALOGV("**WEAPON EVENT** veocity triggered -attack"); + sendButtonAction("+attack", vr.secondaryVelocityTriggeredAttack); + } + } else if (vr.weaponid == WP_SABER) { + //Does weapon velocity trigger attack + if (vr.velocitytriggered) { + static bool fired = false; + vr.primaryVelocityTriggeredAttack = (vr.primaryswingvelocity > + vr_weapon_velocity_trigger->value); - if (fired != vr.primaryVelocityTriggeredAttack) { - ALOGV("**WEAPON EVENT** veocity triggered %s", - vr.primaryVelocityTriggeredAttack ? "+attack" : "-attack"); - //normal attack is a punch with the left hand - sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack); - fired = vr.primaryVelocityTriggeredAttack; - } - } else if (vr.primaryVelocityTriggeredAttack) { - //send a stop attack as we have an unfinished velocity attack - vr.primaryVelocityTriggeredAttack = false; - ALOGV("**WEAPON EVENT** veocity triggered -attack"); + if (fired != vr.primaryVelocityTriggeredAttack) { + ALOGV("**WEAPON EVENT** veocity triggered %s", + vr.primaryVelocityTriggeredAttack ? "+attack" : "-attack"); + //normal attack is a punch with the left hand sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack); + fired = vr.primaryVelocityTriggeredAttack; } - } - - if (vr.weapon_stabilised) { - if (vr.scopeengaged || vr_virtual_stock->integer == 1) { - //offset to the appropriate eye a little bit - vec2_t xy; - rotateAboutOrigin(Cvar_VariableValue("cg_stereoSeparation") / 2.0f, 0.0f, - -vr.hmdorientation[YAW], xy); - float x = pOff->HeadPose.Pose.Position.x - (vr.hmdposition[0] + xy[0]); - float y = pOff->HeadPose.Pose.Position.y - - (vr.hmdposition[1] - 0.1f); // Use a point lower - float z = pOff->HeadPose.Pose.Position.z - (vr.hmdposition[2] + xy[1]); - float zxDist = length(x, z); - - if (zxDist != 0.0f && z != 0.0f) { - VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)), - -degrees(atan2f(x, -z)), 0); - } - } else { - float x = - pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x; - float y = - pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y; - float z = - pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z; - float zxDist = length(x, z); - - if (zxDist != 0.0f && z != 0.0f) { - VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)), - -degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / - 2.0f); //Dampen roll on stabilised weapon - } - } - } - - // Calculate if player tries to reach backpack - bool handInBackpack = false; - bool bpDistToHMDOk = false, bpWeaponHeightOk = false, bpWeaponAngleOk = false, bpHmdToWeaponAngleOk = false; - vec3_t hmdForwardXY = {}, weaponForwardXY = {}; - float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0; - static vec3_t downVector = {0.0, 0.0, -1.0}; - - bool bpTrackOk = pOffTracking->Status & - VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked - if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <= - 0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range - && (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <= - 0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range - { - AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL); - AngleVectors(vr.weaponangles, weaponForwardXY, NULL, NULL); - - float weaponToDownAngle = AngleBetweenVectors(downVector, weaponForwardXY); - // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees - if (bpWeaponAngleOk = weaponToDownAngle >= 80.0 && weaponToDownAngle <= 140.0) { - hmdForwardXY[2] = 0; - VectorNormalize(hmdForwardXY); - - weaponForwardXY[2] = 0; - VectorNormalize(weaponForwardXY); - - hmdToWeaponDotProduct = DotProduct(hmdForwardXY, weaponForwardXY); - // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0) - handInBackpack = bpHmdToWeaponAngleOk = hmdToWeaponDotProduct < 0; - } - } - - //off-hand stuff (done here as I reference it in the save state thing - { - vr.offhandposition[0] = pOff->HeadPose.Pose.Position.x; - vr.offhandposition[1] = pOff->HeadPose.Pose.Position.y; - vr.offhandposition[2] = pOff->HeadPose.Pose.Position.z; - - vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0]; - vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1]; - vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2]; - - vec3_t rotation = {0}; - QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles); - - if (vr_walkdirection->value == 0) { - controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW]; - } else { - controllerYawHeading = 0.0f; - } - } - - // Use off hand as well to trigger save condition - canUseQuickSave = false; - bool bpOffhandDistToHMDOk = false, bpOffhandHeightOk = false, bpOffhandAngleOk = false, bpHmdToOffhandAngleOk = false; - vec3_t offhandForwardXY = {}; - float hmdToOffhandDotProduct = 0; - float offhandToDownAngle = 0; - if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 && - distanceToHMDOff <= - 0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range - && (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <= - 0.10)) // 3) Offhand height in relation to HMD must be within <-0.10, 0.10> range - { - //Need to do this again as might not have done it above and cant be bothered to refactor - AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL); - AngleVectors(vr.offhandangles, offhandForwardXY, NULL, NULL); - - offhandToDownAngle = AngleBetweenVectors(downVector, offhandForwardXY); - - // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees - if (bpOffhandAngleOk = - offhandToDownAngle >= 80.0 && offhandToDownAngle <= 140.0) { - hmdForwardXY[2] = 0; - VectorNormalize(hmdForwardXY); - - offhandForwardXY[2] = 0; - VectorNormalize(offhandForwardXY); - - hmdToOffhandDotProduct = DotProduct(hmdForwardXY, offhandForwardXY); - // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0) - canUseQuickSave = bpHmdToOffhandAngleOk = hmdToOffhandDotProduct < 0; - } - } - - // Uncomment to debug offhand reaching - -/* ALOGV("Quick Save> Dist: %f | OffHandToDownAngle: %f | HandOffs: %f %f %f\nHmdHandDot: %f | HmdFwdXY: %f %f | WpnFwdXY: %f %f\nTrackOk: %i, DistOk: %i, HeightOk: %i, HnadAngleOk: %i, HmdHandDotOk: %i", - distanceToHMDOff, offhandToDownAngle, vr.offhandoffset[0], - vr.offhandoffset[1], vr.offhandoffset[2], - hmdToOffhandDotProduct, hmdForwardXY[0], hmdForwardXY[1], offhandForwardXY[0], - offhandForwardXY[1], - bpTrackOk, bpOffhandDistToHMDOk, bpOffhandHeightOk, bpOffhandAngleOk, - bpHmdToOffhandAngleOk); -*/ - - // Check quicksave - if (canUseQuickSave) { - int channel = (vr_control_scheme->integer >= 10) ? 1 : 0; - JKVR_Vibrate(40, channel, 0.5); // vibrate to let user know they can switch - - if (((pOffTrackedRemoteNew->Buttons & offButton1) != - (pOffTrackedRemoteOld->Buttons & offButton1)) && - (pOffTrackedRemoteNew->Buttons & offButton1)) { - sendButtonActionSimple("savegame quicksave"); - } - - if (((pOffTrackedRemoteNew->Buttons & offButton2) != - (pOffTrackedRemoteOld->Buttons & offButton2)) && - (pOffTrackedRemoteNew->Buttons & offButton2)) { - sendButtonActionSimple("loadgame quicksave"); - } + } else if (vr.primaryVelocityTriggeredAttack) { + //send a stop attack as we have an unfinished velocity attack + vr.primaryVelocityTriggeredAttack = false; + ALOGV("**WEAPON EVENT** veocity triggered -attack"); + sendButtonAction("+attack", vr.primaryVelocityTriggeredAttack); } } - //Right-hand specific stuff - { - //This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the - //player is facing for positional tracking + if (vr.weapon_stabilised) { + if (vr.scopeengaged || vr_virtual_stock->integer == 1) { + //offset to the appropriate eye a little bit + vec2_t xy; + rotateAboutOrigin(Cvar_VariableValue("cg_stereoSeparation") / 2.0f, 0.0f, + -vr.hmdorientation[YAW], xy); + float x = pOff->HeadPose.Pose.Position.x - (vr.hmdposition[0] + xy[0]); + float y = pOff->HeadPose.Pose.Position.y - + (vr.hmdposition[1] - 0.1f); // Use a point lower + float z = pOff->HeadPose.Pose.Position.z - (vr.hmdposition[2] + xy[1]); + float zxDist = length(x, z); - //Positional movement speed correction for when we are not hitting target framerate - static double lastframetime = 0; - int refresh = GetRefresh(); - double newframetime = GetTimeInMilliSeconds(); - float multiplier = (float) ((1000.0 / refresh) / (newframetime - lastframetime)); - lastframetime = newframetime; - - vec2_t v; - float factor = (refresh / 72.0F) * - vr_positional_factor->value; // adjust positional factor based on refresh rate - rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier, - vr.hmdposition_delta[2] * factor * multiplier, - -vr.hmdorientation[YAW], v); - positional_movementSideways = v[0]; - positional_movementForward = v[1]; - - ALOGV(" positional_movementSideways: %f, positional_movementForward: %f", - positional_movementSideways, - positional_movementForward); - - - //Jump (A Button) - if ((primaryButtonsNew & primaryButton1) != (primaryButtonsOld & primaryButton1)) { - sendButtonAction("+moveup", (primaryButtonsNew & primaryButton1)); - } - - //Alt Fire (B Button) - if ((primaryButtonsNew & primaryButton2) != (primaryButtonsOld & primaryButton2)) { - if (vr.cgzoommode > 0) - { - sendButtonActionSimple("invuse"); - } - else if (vr.weaponid == WP_SABER && vr.velocitytriggered) - { - //B button toggles saber on/off in first person - if (primaryButtonsNew & primaryButton2) { - sendButtonActionSimple("togglesaber"); - } - } - else - { - sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2)); - } - } - - - static bool firing = false; - static bool throwing = false; - - int thirdPerson = Cvar_VariableIntegerValue("cg_thirdPerson"); - - if (vr.weaponid == WP_SABER && !thirdPerson && vr.cgzoommode == 0) - { - static bool previous_throwing = false; - previous_throwing = throwing; - if (!throwing && - vr.primaryVelocityTriggeredAttack && - (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) - { - throwing = true; - } - else if (throwing && !(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) - { - throwing = false; - } - - if (previous_throwing != throwing) { - sendButtonAction("+altattack", throwing); - } - } - else if (!vr.velocitytriggered) // Don't fire velocity triggered weapons - { - //Fire Primary - Doesn't trigger the saber - if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != - (pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) { - - ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack", - (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-"); - firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger); - sendButtonAction("+attack", firing); - } - - if (throwing) - { - //if throwing is still activated here, just disable - throwing = false; - sendButtonAction("+altattack", throwing); - } - } - - - //Duck - off hand joystick - if ((secondaryButtonsNew & secondaryThumb) != - (secondaryButtonsOld & secondaryThumb)) { - - sendButtonAction("+movedown", (secondaryButtonsNew & secondaryThumb)); - } - - //Use - if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) != - (pDominantTrackedRemoteOld->Buttons & primaryThumb)) { - - sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb)); - } - } - - { - //Apply a filter and quadratic scaler so small movements are easier to make - float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y); - float nlf = nonLinearFilter(dist); - float x = (nlf * pSecondaryJoystick->x) + pFootTrackingNew->LeftJoystick.x; - float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y; - - vr.player_moving = (fabs(x) + fabs(y)) > 0.05f; - - //Adjust to be off-hand controller oriented - vec2_t v; - rotateAboutOrigin(x, y, controllerYawHeading, v); - - //Move a lot slower if scope is engaged - remote_movementSideways = - v[0] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value; - remote_movementForward = - v[1] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value; - ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", - remote_movementSideways, - remote_movementForward); - - - if (!canUseQuickSave) { - if ((secondaryButtonsNew & secondaryButton1) != - (secondaryButtonsOld & secondaryButton1)) { - //Toggle walk/run somehow?! - } - } - - //Open the datapad - if (!canUseQuickSave) { - if (((secondaryButtonsNew & secondaryButton2) != - (secondaryButtonsOld & secondaryButton2)) && - (secondaryButtonsNew & secondaryButton2)) { - Sys_QueEvent(0, SE_KEY, A_TAB, true, 0, NULL); - } - } - - //Use Force - off hand trigger - { - if ((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) != - (pOffTrackedRemoteOld->Buttons & ovrButton_Trigger)) - { - sendButtonAction("+useforce", (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger)); - } - } - - //Use smooth in 3rd person - bool usingSnapTurn = vr_turn_mode->integer == 0 || - (!vr.third_person && vr_turn_mode->integer == 1); - - static int increaseSnap = true; - if (!vr.item_selector && !vr.scopeengaged) { - if (usingSnapTurn) { - if (primaryJoystickX > 0.7f) { - if (increaseSnap) { - vr.snapTurn -= vr_turn_angle->value; - increaseSnap = false; - if (vr.snapTurn < -180.0f) { - vr.snapTurn += 360.f; - } - } - } else if (primaryJoystickX < 0.3f) { - increaseSnap = true; - } - } - - static int decreaseSnap = true; - if (usingSnapTurn) { - if (primaryJoystickX < -0.7f) { - if (decreaseSnap) { - vr.snapTurn += vr_turn_angle->value; - decreaseSnap = false; - - if (vr.snapTurn > 180.0f) { - vr.snapTurn -= 360.f; - } - } - } else if (primaryJoystickX > -0.3f) { - decreaseSnap = true; - } - } - - if (!usingSnapTurn && fabs(primaryJoystickX) > 0.1f) //smooth turn - { - vr.snapTurn -= ((vr_turn_angle->value / 10.0f) * - primaryJoystickX); - if (vr.snapTurn > 180.0f) { - vr.snapTurn -= 360.f; - } + if (zxDist != 0.0f && z != 0.0f) { + VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)), + -degrees(atan2f(x, -z)), 0); } } else { - if (fabs(primaryJoystickX) > 0.5f) { - increaseSnap = false; - } else { + float x = + pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x; + float y = + pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y; + float z = + pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z; + float zxDist = length(x, z); + + if (zxDist != 0.0f && z != 0.0f) { + VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)), + -degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / + 2.0f); //Dampen roll on stabilised weapon + } + } + } + + // Calculate if player tries to reach backpack + bool handInBackpack = false; + bool bpDistToHMDOk = false, bpWeaponHeightOk = false, bpWeaponAngleOk = false, bpHmdToWeaponAngleOk = false; + vec3_t hmdForwardXY = {}, weaponForwardXY = {}; + float weaponToDownAngle = 0, hmdToWeaponDotProduct = 0; + static vec3_t downVector = {0.0, 0.0, -1.0}; + + bool bpTrackOk = pOffTracking->Status & + VRAPI_TRACKING_STATUS_POSITION_TRACKED; // 1) Position must be tracked + if (bpTrackOk && (bpDistToHMDOk = distanceToHMD >= 0.2 && distanceToHMD <= + 0.35) // 2) Weapon-to-HMD distance must be within <0.2-0.35> range + && (bpWeaponHeightOk = vr.weaponoffset[1] >= -0.10 && vr.weaponoffset[1] <= + 0.10)) // 3) Weapon height in relation to HMD must be within <-0.10, 0.10> range + { + AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL); + AngleVectors(vr.weaponangles, weaponForwardXY, NULL, NULL); + + float weaponToDownAngle = AngleBetweenVectors(downVector, weaponForwardXY); + // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees + if (bpWeaponAngleOk = weaponToDownAngle >= 80.0 && weaponToDownAngle <= 140.0) { + hmdForwardXY[2] = 0; + VectorNormalize(hmdForwardXY); + + weaponForwardXY[2] = 0; + VectorNormalize(weaponForwardXY); + + hmdToWeaponDotProduct = DotProduct(hmdForwardXY, weaponForwardXY); + // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0) + handInBackpack = bpHmdToWeaponAngleOk = hmdToWeaponDotProduct < 0; + } + } + + //off-hand stuff (done here as I reference it in the save state thing + { + vr.offhandposition[0] = pOff->HeadPose.Pose.Position.x; + vr.offhandposition[1] = pOff->HeadPose.Pose.Position.y; + vr.offhandposition[2] = pOff->HeadPose.Pose.Position.z; + + vr.offhandoffset[0] = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0]; + vr.offhandoffset[1] = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1]; + vr.offhandoffset[2] = pOff->HeadPose.Pose.Position.z - vr.hmdposition[2]; + + vec3_t rotation = {0}; + QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation, vr.offhandangles); + + if (vr_walkdirection->value == 0) { + controllerYawHeading = vr.offhandangles[YAW] - vr.hmdorientation[YAW]; + } else { + controllerYawHeading = 0.0f; + } + } + + // Use off hand as well to trigger save condition + canUseQuickSave = false; + bool bpOffhandDistToHMDOk = false, bpOffhandHeightOk = false, bpOffhandAngleOk = false, bpHmdToOffhandAngleOk = false; + vec3_t offhandForwardXY = {}; + float hmdToOffhandDotProduct = 0; + float offhandToDownAngle = 0; + if (bpTrackOk && (bpOffhandDistToHMDOk = distanceToHMDOff >= 0.2 && + distanceToHMDOff <= + 0.35) // 2) Off-to-HMD distance must be within <0.2-0.35> range + && (bpOffhandHeightOk = vr.offhandoffset[1] >= -0.10 && vr.offhandoffset[1] <= + 0.10)) // 3) Offhand height in relation to HMD must be within <-0.10, 0.10> range + { + //Need to do this again as might not have done it above and cant be bothered to refactor + AngleVectors(vr.hmdorientation, hmdForwardXY, NULL, NULL); + AngleVectors(vr.offhandangles, offhandForwardXY, NULL, NULL); + + offhandToDownAngle = AngleBetweenVectors(downVector, offhandForwardXY); + + // 4) Angle between weapon forward vector and a down vector must be within 80-140 degrees + if (bpOffhandAngleOk = + offhandToDownAngle >= 80.0 && offhandToDownAngle <= 140.0) { + hmdForwardXY[2] = 0; + VectorNormalize(hmdForwardXY); + + offhandForwardXY[2] = 0; + VectorNormalize(offhandForwardXY); + + hmdToOffhandDotProduct = DotProduct(hmdForwardXY, offhandForwardXY); + // 5) HMD and weapon forward on XY plane must go in opposite directions (i.e. dot product < 0) + canUseQuickSave = bpHmdToOffhandAngleOk = hmdToOffhandDotProduct < 0; + } + } + + // Uncomment to debug offhand reaching + +/* ALOGV("Quick Save> Dist: %f | OffHandToDownAngle: %f | HandOffs: %f %f %f\nHmdHandDot: %f | HmdFwdXY: %f %f | WpnFwdXY: %f %f\nTrackOk: %i, DistOk: %i, HeightOk: %i, HnadAngleOk: %i, HmdHandDotOk: %i", + distanceToHMDOff, offhandToDownAngle, vr.offhandoffset[0], + vr.offhandoffset[1], vr.offhandoffset[2], + hmdToOffhandDotProduct, hmdForwardXY[0], hmdForwardXY[1], offhandForwardXY[0], + offhandForwardXY[1], + bpTrackOk, bpOffhandDistToHMDOk, bpOffhandHeightOk, bpOffhandAngleOk, + bpHmdToOffhandAngleOk); +*/ + + // Check quicksave + if (canUseQuickSave) { + int channel = (vr_control_scheme->integer >= 10) ? 1 : 0; + JKVR_Vibrate(40, channel, 0.5); // vibrate to let user know they can switch + + if (((pOffTrackedRemoteNew->Buttons & offButton1) != + (pOffTrackedRemoteOld->Buttons & offButton1)) && + (pOffTrackedRemoteNew->Buttons & offButton1)) { + sendButtonActionSimple("savegame quicksave"); + } + + if (((pOffTrackedRemoteNew->Buttons & offButton2) != + (pOffTrackedRemoteOld->Buttons & offButton2)) && + (pOffTrackedRemoteNew->Buttons & offButton2)) { + sendButtonActionSimple("loadgame quicksave"); + } + } + } + + //Right-hand specific stuff + { + //This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the + //player is facing for positional tracking + + //Positional movement speed correction for when we are not hitting target framerate + static double lastframetime = 0; + int refresh = GetRefresh(); + double newframetime = GetTimeInMilliSeconds(); + float multiplier = (float) ((1000.0 / refresh) / (newframetime - lastframetime)); + lastframetime = newframetime; + + vec2_t v; + float factor = (refresh / 72.0F) * + vr_positional_factor->value; // adjust positional factor based on refresh rate + rotateAboutOrigin(-vr.hmdposition_delta[0] * factor * multiplier, + vr.hmdposition_delta[2] * factor * multiplier, + -vr.hmdorientation[YAW], v); + positional_movementSideways = v[0]; + positional_movementForward = v[1]; + + ALOGV(" positional_movementSideways: %f, positional_movementForward: %f", + positional_movementSideways, + positional_movementForward); + + + //Jump (A Button) + if ((primaryButtonsNew & primaryButton1) != (primaryButtonsOld & primaryButton1)) { + sendButtonAction("+moveup", (primaryButtonsNew & primaryButton1)); + } + + //Alt Fire (B Button) + if ((primaryButtonsNew & primaryButton2) != (primaryButtonsOld & primaryButton2)) { + if (vr.cgzoommode > 0) + { + sendButtonActionSimple("invuse"); + } + else if (vr.weaponid == WP_SABER && vr.velocitytriggered) + { + //B button toggles saber on/off in first person + if (primaryButtonsNew & primaryButton2) { + sendButtonActionSimple("togglesaber"); + } + } + else + { + sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2)); + } + } + + + static bool firing = false; + static bool throwing = false; + + int thirdPerson = Cvar_VariableIntegerValue("cg_thirdPerson"); + + if (vr.weaponid == WP_SABER && !thirdPerson && vr.cgzoommode == 0) + { + static bool previous_throwing = false; + previous_throwing = throwing; + if (!throwing && + vr.primaryVelocityTriggeredAttack && + (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) + { + throwing = true; + } + else if (throwing && !(pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger)) + { + throwing = false; + } + + if (previous_throwing != throwing) { + sendButtonAction("+altattack", throwing); + } + } + else if (!vr.velocitytriggered) // Don't fire velocity triggered weapons + { + //Fire Primary - Doesn't trigger the saber + if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != + (pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) { + + ALOGV("**WEAPON EVENT** Not Grip Pushed %sattack", + (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) ? "+" : "-"); + firing = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger); + sendButtonAction("+attack", firing); + } + + if (throwing) + { + //if throwing is still activated here, just disable + throwing = false; + sendButtonAction("+altattack", throwing); + } + } + + + //Duck - off hand joystick + if ((secondaryButtonsNew & secondaryThumb) != + (secondaryButtonsOld & secondaryThumb)) { + + sendButtonAction("+movedown", (secondaryButtonsNew & secondaryThumb)); + } + + //Use + if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) != + (pDominantTrackedRemoteOld->Buttons & primaryThumb)) { + + sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb)); + } + } + + { + //Apply a filter and quadratic scaler so small movements are easier to make + float dist = length(pSecondaryJoystick->x, pSecondaryJoystick->y); + float nlf = nonLinearFilter(dist); + float x = (nlf * pSecondaryJoystick->x) + pFootTrackingNew->LeftJoystick.x; + float y = (nlf * pSecondaryJoystick->y) - pFootTrackingNew->LeftJoystick.y; + + vr.player_moving = (fabs(x) + fabs(y)) > 0.05f; + + //Adjust to be off-hand controller oriented + vec2_t v; + rotateAboutOrigin(x, y, controllerYawHeading, v); + + //Move a lot slower if scope is engaged + remote_movementSideways = + v[0] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value; + remote_movementForward = + v[1] * (vr.scopeengaged ? 0.3f : 1.0f) * vr_movement_multiplier->value; + ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", + remote_movementSideways, + remote_movementForward); + + + if (!canUseQuickSave) { + if ((secondaryButtonsNew & secondaryButton1) != + (secondaryButtonsOld & secondaryButton1)) { + //Toggle walk/run somehow?! + } + } + + //Open the datapad + if (!canUseQuickSave) { + if (((secondaryButtonsNew & secondaryButton2) != + (secondaryButtonsOld & secondaryButton2)) && + (secondaryButtonsNew & secondaryButton2)) { + Sys_QueEvent(0, SE_KEY, A_TAB, true, 0, NULL); + } + } + + //Use Force - off hand trigger + { + if ((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) != + (pOffTrackedRemoteOld->Buttons & ovrButton_Trigger)) + { + sendButtonAction("+useforce", (pOffTrackedRemoteNew->Buttons & ovrButton_Trigger)); + } + } + + //Use smooth in 3rd person + bool usingSnapTurn = vr_turn_mode->integer == 0 || + (!vr.third_person && vr_turn_mode->integer == 1); + + static int increaseSnap = true; + if (!vr.item_selector && !vr.scopeengaged) { + if (usingSnapTurn) { + if (primaryJoystickX > 0.7f) { + if (increaseSnap) { + vr.snapTurn -= vr_turn_angle->value; + increaseSnap = false; + if (vr.snapTurn < -180.0f) { + vr.snapTurn += 360.f; + } + } + } else if (primaryJoystickX < 0.3f) { increaseSnap = true; } } - } - updateScopeAngles(); + static int decreaseSnap = true; + if (usingSnapTurn) { + if (primaryJoystickX < -0.7f) { + if (decreaseSnap) { + vr.snapTurn += vr_turn_angle->value; + decreaseSnap = false; + + if (vr.snapTurn > 180.0f) { + vr.snapTurn -= 360.f; + } + } + } else if (primaryJoystickX > -0.3f) { + decreaseSnap = true; + } + } + + if (!usingSnapTurn && fabs(primaryJoystickX) > 0.1f) //smooth turn + { + vr.snapTurn -= ((vr_turn_angle->value / 10.0f) * + primaryJoystickX); + if (vr.snapTurn > 180.0f) { + vr.snapTurn -= 360.f; + } + } + } else { + if (fabs(primaryJoystickX) > 0.5f) { + increaseSnap = false; + } else { + increaseSnap = true; + } + } } + + //process force motion controls here + if (vr_force_motion_controlled->integer) + { + if (vr.secondaryswingvelocity > vr_force_velocity_trigger->value) + { + if (!vr.secondaryVelocityTriggeredAttack) + { + VectorCopy(vr.offhandposition, vr.secondaryVelocityTriggerLocation); + vr.secondaryVelocityTriggeredAttack = true; + } + } + else + { + if (vr.secondaryVelocityTriggeredAttack) + { + vec3_t delta1, delta2; + VectorSubtract(vr.offhandposition, vr.hmdposition, delta1); + VectorSubtract(vr.secondaryVelocityTriggerLocation, vr.hmdposition, delta2); + if (VectorLength(delta1) > VectorLength(delta2)) + { + sendButtonActionSimple("useGivenForce 3"); // PULL + } + else + { + sendButtonActionSimple("useGivenForce 4"); // PUSH + } + + vr.secondaryVelocityTriggeredAttack = false; + } + } + } + + updateScopeAngles(); } + //Save state rightTrackedRemoteState_old = rightTrackedRemoteState_new; leftTrackedRemoteState_old = leftTrackedRemoteState_new; diff --git a/Projects/Android/jni/OpenJK/codeJK2/game/g_active.cpp b/Projects/Android/jni/OpenJK/codeJK2/game/g_active.cpp index c2b37c4..c1fedf3 100644 --- a/Projects/Android/jni/OpenJK/codeJK2/game/g_active.cpp +++ b/Projects/Android/jni/OpenJK/codeJK2/game/g_active.cpp @@ -1980,6 +1980,40 @@ usually be a couple times for each server frame on fast clients. */ extern int G_FindLocalInterestPoint( gentity_t *self ); +extern void ForceGrip(gentity_t *ent); +extern void ForceLightning(gentity_t *ent); +extern void ForceTelepathy(gentity_t *ent); +extern void ForceHeal(gentity_t *ent); +extern void ForceThrowEx( gentity_t *self, qboolean pull, qboolean aimByViewAngles ); +static void ProcessGenericCmd(gentity_t *ent, byte cmd) +{ + switch(cmd) { + default: + break; + case GENCMD_FORCE_HEAL: + ForceHeal( ent ); + break; + case GENCMD_FORCE_SPEED: + ForceSpeed( ent ); + break; + case GENCMD_FORCE_THROW: + ForceThrowEx(ent, qfalse, qtrue); + break; + case GENCMD_FORCE_PULL: + ForceThrowEx(ent, qtrue, qtrue); + break; + case GENCMD_FORCE_DISTRACT: + ForceTelepathy(ent); + break; + case GENCMD_FORCE_GRIP: + ForceGrip(ent); + break; + case GENCMD_FORCE_LIGHTNING: + ForceLightning(ent); + break; + } +} + void ClientThink_real( gentity_t *ent, usercmd_t *ucmd ) { gclient_t *client; @@ -2768,6 +2802,8 @@ extern cvar_t *g_skippingcin; // perform a pmove Pmove( &pm ); + ProcessGenericCmd(ent, pm.cmd.generic_cmd); + // save results of pmove if ( ent->client->ps.eventSequence != oldEventSequence ) { diff --git a/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp b/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp index 4783acc..ed654dd 100644 --- a/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp +++ b/Projects/Android/jni/OpenJK/codeJK2/game/wp_saber.cpp @@ -5599,7 +5599,13 @@ void WP_ForceKnockdown( gentity_t *self, gentity_t *pusher, qboolean pull, qbool self->forcePushTime = level.time + 600; // let the push effect last for 600 ms } +void ForceThrowEx( gentity_t *self, qboolean pull, qboolean aimByViewAngles ); void ForceThrow( gentity_t *self, qboolean pull ) +{ + ForceThrowEx(self, pull, qfalse); +} + +void ForceThrowEx( gentity_t *self, qboolean pull, qboolean aimByViewAngles ) {//FIXME: pass in a target ent so we (an NPC) can push/pull just one targeted ent. //shove things in front of you away float dist; @@ -5721,10 +5727,11 @@ void ForceThrow( gentity_t *self, qboolean pull ) G_Sound( self, soundIndex ); vec3_t origin, angles; - if (self->client->ps.clientNum == 0 && !cg.renderingThirdPerson) + if (self->client->ps.clientNum == 0 && !cg.renderingThirdPerson && !aimByViewAngles) { BG_CalculateVROffHandPosition(origin, fwdangles); - + AngleVectors( fwdangles, forward, right, NULL ); + VectorCopy( origin, center ); } else { @@ -8178,9 +8185,7 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd self->client->ps.forceGripEntityInitialDist == ENTITYNUM_NONE) { vec3_t diff; - diff[2] = 0; - VectorSubtract2(self->client->renderInfo.handLPoint, - self->client->renderInfo.eyePoint, diff); + VectorSubtract(vr->offhandposition, vr->hmdposition, diff); self->client->ps.forceGripEntityInitialDist = VectorLength(diff); } @@ -8199,13 +8204,11 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd {//carry if (isFirstPersonPlayer) { vec3_t diff; - diff[2] = 0; - VectorSubtract2(self->client->renderInfo.handLPoint, - self->client->renderInfo.eyePoint, diff); + VectorSubtract(vr->offhandposition, vr->hmdposition, diff); float length = VectorLength(diff); - if (fabs(length - self->client->ps.forceGripEntityInitialDist) > 1.0f) { - dist += (length - self->client->ps.forceGripEntityInitialDist) * - 5.0f; + float movedLength = (length - self->client->ps.forceGripEntityInitialDist) * cg_worldScale.value; + if (fabs(movedLength) > 1.0f) { + dist += movedLength * 5.0f; } if (dist > 384) { dist = 384;