jkxr/Projects/Android/jni/JKVR/VrInputDefault.cpp
Simon ed658dfffa Many improvements
Added cvar g_saberAutoDeflect1stPerson so saber is only ever used to deflect lasers in first person
Made selector always draw using HMD YAW so it remains in front when turning i.r.l
Updated the hand model (@baggyg)
Updated the crawler text with the patron credits
Added @MuadDib's menu changes
Aligned all weapons
Scaled the saber hilt down a little bit

Co-Authored-By: Grant Bagwell <general@grantbagwell.co.uk>
2022-10-15 00:01:40 +01:00

717 lines
34 KiB
C++

/************************************************************************************
Filename : VrInputDefault.c
Content : Handles default controller input
Created : August 2019
Authors : Simon Brown
*************************************************************************************/
#include <VrApi.h>
#include <VrApi_Helpers.h>
#include <VrApi_SystemUtils.h>
#include <VrApi_Input.h>
#include <VrApi_Types.h>
#include <android/keycodes.h>
#include "VrInput.h"
#include "VrCvars.h"
#include "qcommon/q_shared.h"
#include <qcommon/qcommon.h>
#include <client/client.h>
#include "android/sys_local.h"
#include "weapons.h"
void SV_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask, int capsule );
void JKVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
static inline float AngleBetweenVectors(const vec3_t a, const vec3_t b)
{
return degrees(acosf(DotProduct(a, b)/(VectorLength(a) * VectorLength(b))));
}
void HandleInput_Default( ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld,
ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
int domButton1, int domButton2, int offButton1, int offButton2 )
{
//Ensure handedness is set correctly
vr.right_handed = vr_control_scheme->value < 10 ||
vr_control_scheme->value == 99; // Always right-handed for weapon calibration
static bool dominantGripPushed = false;
static float dominantGripPushTime = 0.0f;
static bool canUseBackpack = false;
static bool canUseQuickSave = false;
//Need this for the touch screen
ovrTracking * pWeapon = pDominantTracking;
ovrTracking * pOff = pOffTracking;
//All this to allow stick and button switching!
ovrVector2f *pPrimaryJoystick;
ovrVector2f *pSecondaryJoystick;
uint32_t primaryButtonsNew;
uint32_t primaryButtonsOld;
uint32_t secondaryButtonsNew;
uint32_t secondaryButtonsOld;
int primaryButton1;
int primaryButton2;
int secondaryButton1;
int secondaryButton2;
int primaryThumb = vr_control_scheme->value == RIGHT_HANDED_DEFAULT ? ovrButton_RThumb : ovrButton_LThumb;
int secondaryThumb = vr_control_scheme->value == RIGHT_HANDED_DEFAULT ? ovrButton_LThumb : ovrButton_RThumb;
if (vr_switch_sticks->integer)
{
//
// This will switch the joystick and A/B/X/Y button functions only
// Move, Strafe, Turn, Jump, Crouch, Notepad, HUD mode, Weapon Switch
pSecondaryJoystick = &pDominantTrackedRemoteNew->Joystick;
pPrimaryJoystick = &pOffTrackedRemoteNew->Joystick;
secondaryButtonsNew = pDominantTrackedRemoteNew->Buttons;
secondaryButtonsOld = pDominantTrackedRemoteOld->Buttons;
primaryButtonsNew = pOffTrackedRemoteNew->Buttons;
primaryButtonsOld = pOffTrackedRemoteOld->Buttons;
primaryButton1 = offButton1;
primaryButton2 = offButton2;
secondaryButton1 = domButton1;
secondaryButton2 = domButton2;
}
else
{
pPrimaryJoystick = &pDominantTrackedRemoteNew->Joystick;
pSecondaryJoystick = &pOffTrackedRemoteNew->Joystick;
primaryButtonsNew = pDominantTrackedRemoteNew->Buttons;
primaryButtonsOld = pDominantTrackedRemoteOld->Buttons;
secondaryButtonsNew = pOffTrackedRemoteNew->Buttons;
secondaryButtonsOld = pOffTrackedRemoteOld->Buttons;
primaryButton1 = domButton1;
primaryButton2 = domButton2;
secondaryButton1 = offButton1;
secondaryButton2 = offButton2;
}
{
//Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick
vec3_t rotation = {0};
rotation[PITCH] = 45;
QuatToYawPitchRoll(pWeapon->HeadPose.Pose.Orientation, rotation, vr.weaponangles_saber);
rotation[PITCH] = vr_weapon_pitchadjust->value;
QuatToYawPitchRoll(pWeapon->HeadPose.Pose.Orientation, rotation, vr.weaponangles);
VectorSubtract(vr.weaponangles_last, vr.weaponangles, vr.weaponangles_delta);
VectorCopy(vr.weaponangles, vr.weaponangles_last);
// ALOGV(" weaponangles_last: %f, %f, %f",
// vr.weaponangles_last[0], vr.weaponangles_last[1], vr.weaponangles_last[2]);
//GB Also set offhand angles just in case we want to use those.
vec3_t rotation_off = {0};
rotation_off[PITCH] = vr_weapon_pitchadjust->value;
QuatToYawPitchRoll(pOff->HeadPose.Pose.Orientation, rotation_off, vr.offhandangles);
VectorSubtract(vr.offhandangles_last, vr.offhandangles, vr.offhandangles_delta);
VectorCopy(vr.offhandangles, vr.offhandangles_last);
}
//Menu button
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, A_ESCAPE);
static bool resetCursor = qtrue;
if ( JKVR_useScreenLayer() )
{
interactWithTouchScreen(resetCursor, pDominantTrackedRemoteNew, pDominantTrackedRemoteOld);
resetCursor = qfalse;
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, A_MOUSE1);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, ovrButton_Trigger, A_MOUSE1);
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, A_ESCAPE);
//To skip flatscreen cinematic
if ((pDominantTrackedRemoteNew->Buttons & primaryThumb) !=
(pDominantTrackedRemoteOld->Buttons & primaryThumb)) {
sendButtonAction("+use", (pDominantTrackedRemoteNew->Buttons & primaryThumb));
}
}
else
{
resetCursor = qtrue;
float distance = sqrtf(powf(pOff->HeadPose.Pose.Position.x - pWeapon->HeadPose.Pose.Position.x, 2) +
powf(pOff->HeadPose.Pose.Position.y - pWeapon->HeadPose.Pose.Position.y, 2) +
powf(pOff->HeadPose.Pose.Position.z - pWeapon->HeadPose.Pose.Position.z, 2));
float distanceToHMD = sqrtf(powf(vr.hmdposition[0] - pWeapon->HeadPose.Pose.Position.x, 2) +
powf(vr.hmdposition[1] - pWeapon->HeadPose.Pose.Position.y, 2) +
powf(vr.hmdposition[2] - pWeapon->HeadPose.Pose.Position.z, 2));
float distanceToHMDOff = sqrtf(powf(vr.hmdposition[0] - pOff->HeadPose.Pose.Position.x, 2) +
powf(vr.hmdposition[1] - pOff->HeadPose.Pose.Position.y, 2) +
powf(vr.hmdposition[2] - pOff->HeadPose.Pose.Position.z, 2));
float controllerYawHeading = 0.0f;
//Turn on weapon stabilisation?
bool stabilised = qfalse;
bool offhandGripPushed = (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger);
if ( (offhandGripPushed != (pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) &&
offhandGripPushed && (distance < STABILISATION_DISTANCE))
#ifndef DEBUG
{
stabilised = qtrue;
}
#else
{
Cvar_Set("vr_control_scheme", "99");
}
#endif
dominantGripPushed = (pDominantTrackedRemoteNew->Buttons &
ovrButton_GripTrigger) != 0;
bool dominantButton1Pushed = (pDominantTrackedRemoteNew->Buttons &
domButton1) != 0;
bool dominantButton2Pushed = (pDominantTrackedRemoteNew->Buttons &
domButton2) != 0;
//Do this early so we can suppress other button actions when item selector is up
{
if (dominantGripPushed) {
if (dominantGripPushTime == 0) {
dominantGripPushTime = GetTimeInMilliSeconds();
}
vr.item_selector = true;
}
else
{
dominantGripPushTime = 0;
if (vr.item_selector)
{
sendButtonActionSimple("itemselectorselect");
vr.item_selector = false;
}
}
}
#define JOYX_SAMPLE_COUNT 4
static float joyx[JOYX_SAMPLE_COUNT] = {0};
for (int j = JOYX_SAMPLE_COUNT - 1; j > 0; --j)
joyx[j] = joyx[j - 1];
joyx[0] = pPrimaryJoystick->x;
float sum = 0.0f;
for (int j = 0; j < JOYX_SAMPLE_COUNT; ++j)
sum += joyx[j];
float primaryJoystickX = sum / 4.0f;
//Left/right to switch between which selector we are using
if (vr.item_selector) {
static bool itemSwitched = false;
if (between(-0.2f, pPrimaryJoystick->y, 0.2f) &&
(between(0.8f, primaryJoystickX, 1.0f) ||
between(-1.0f, primaryJoystickX, -0.8f))) {
if (!itemSwitched) {
if (between(0.8f, primaryJoystickX, 1.0f)) {
sendButtonActionSimple("itemselectornext");
} else {
sendButtonActionSimple("itemselectorprev");
}
itemSwitched = true;
}
} else {
itemSwitched = false;
}
}
if (vr.cgzoommode > 1)
{
if (between(-0.2f, primaryJoystickX, 0.2f)) {
sendButtonAction("+attack", between(0.8f, pPrimaryJoystick->y, 1.0f));
sendButtonAction("+altattack", between(-1.0f, pPrimaryJoystick->y, -0.8f));
}
} else if (vr.weaponid == WP_SABER)
{
static bool switched = false;
if (between(-0.2f, primaryJoystickX, 0.2f) &&
(between(0.8f, pPrimaryJoystick->y, 1.0f) ||
between(-1.0f, pPrimaryJoystick->y, -0.8f))) {
if (!switched) {
if (between(0.8f, pPrimaryJoystick->y, 1.0f)) {
sendButtonActionSimple("cg_thirdPerson 1");
} else {
sendButtonActionSimple("cg_thirdPerson 0");
}
switched = true;
}
} else {
switched = false;
}
}
vr.weapon_stabilised = stabilised;
//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
{
//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;
VectorSet(vr.weaponposition, pWeapon->HeadPose.Pose.Position.x,
pWeapon->HeadPose.Pose.Position.y, pWeapon->HeadPose.Pose.Position.z);
///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);
//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");
sendButtonAction("+altattack", vr.primaryVelocityTriggeredAttack);
}
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");
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");
sendButtonAction("+attack", 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");
}
}
}
//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 {
sendButtonAction("+altattack", (primaryButtonsNew & primaryButton2));
}
}
static bool firing = false;
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);
}
}
else if (vr.weaponid == WP_SABER)
{
if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
if (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) {
sendButtonActionSimple("togglesaber");
}
}
}
//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));
}
}
//Resync Yaw on mounted gun transition
static int usingMountedGun = false;
if (vr.mountedgun != usingMountedGun) {
usingMountedGun = vr.mountedgun;
}
//No snap turn when using mounted gun
static int syncCount = 0;
static int increaseSnap = true;
if (!vr.item_selector && !vr.mountedgun && !vr.scopeengaged) {
if (primaryJoystickX > 0.7f) {
if (increaseSnap) {
float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f)
: vr_turn_angle->value;
vr.snapTurn -= turnAngle;
if (vr_turn_mode->integer == 0) {
increaseSnap = false;
}
if (vr.snapTurn < -180.0f) {
vr.snapTurn += 360.f;
}
}
} else if (primaryJoystickX < 0.3f) {
increaseSnap = true;
}
static int decreaseSnap = true;
if (primaryJoystickX < -0.7f) {
if (decreaseSnap) {
float turnAngle = vr_turn_mode->integer ? (vr_turn_angle->value / 9.0f)
: vr_turn_angle->value;
vr.snapTurn += turnAngle;
//If snap turn configured for less than 10 degrees
if (vr_turn_mode->integer == 0) {
decreaseSnap = false;
}
if (vr.snapTurn > 180.0f) {
vr.snapTurn -= 360.f;
}
}
} else if (primaryJoystickX > -0.3f) {
decreaseSnap = true;
}
} else {
if (fabs(primaryJoystickX) > 0.5f) {
increaseSnap = false;
} else {
increaseSnap = true;
}
}
}
updateScopeAngles();
}
}
//Save state
rightTrackedRemoteState_old = rightTrackedRemoteState_new;
leftTrackedRemoteState_old = leftTrackedRemoteState_new;
}