diff --git a/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c b/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c index 7807a65..6a05624 100644 --- a/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c +++ b/Projects/Android/jni/src/Lambda1VR/L1VR_SurfaceView.c @@ -648,16 +648,24 @@ void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer ) //Glide comfort mask in and out static float currentVLevel = 0.0f; - if (player_moving) + + //Hack to surround scope sight with blackness + const float scopeSize = 0.75; + if (isScopeEngaged()) + { + if (currentVLevel < scopeSize) + currentVLevel += scopeSize * 0.05; + } + else if (player_moving && vr_comfort_mask->value > 0.0f) { if (currentVLevel < vr_comfort_mask->value) currentVLevel += vr_comfort_mask->value * 0.05; } else{ + float v = (vr_comfort_mask->value == 0) ? scopeSize : vr_comfort_mask->value; if (currentVLevel > 0.0f) - currentVLevel -= vr_comfort_mask->value * 0.05; + currentVLevel -= v * 0.05; } - bool useMask = (currentVLevel > 0.0f && currentVLevel <= 1.0f); float width = useMask ? (frameBuffer->Width / 2.0f) * currentVLevel : 1; @@ -893,15 +901,32 @@ bool isMultiplayer() return (CL_GetMaxClients() > 1); } +bool isScopeEngaged() +{ + return (cl.scr_fov != 0 && cl.scr_fov < VR_FOV); +} + void Host_BeginFrame(); void Host_Frame(); void Host_EndFrame(); void VR_GetMove( float *forward, float *side, float *yaw, float *pitch, float *roll ) { - *forward = remote_movementForward + positional_movementForward; + //This is pretty crazy, but due to the way the angles are sent between the client and server + //they are truncated, which results in a small rounding down, over time this leads to a yaw drift + //which doesn't take long to start affecting the accuracy of the sniper rifle, or simply leave you + // not facing the direction you started in! + static float driftCorrection = 0; + //Update our drift correction + driftCorrection += YAWDRIFTPERFRAME; + if (driftCorrection > 360.0F) + { + driftCorrection = 0; + } + + *forward = remote_movementForward + positional_movementForward; *side = remote_movementSideways + positional_movementSideways; - *yaw = hmdorientation[YAW] + snapTurn; + *yaw = hmdorientation[YAW] + snapTurn + driftCorrection; *pitch = hmdorientation[PITCH]; *roll = hmdorientation[ROLL]; } @@ -945,8 +970,20 @@ void RenderFrame( ovrRenderer * renderer, const ovrJava * java, GL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); GL(glDisable(GL_SCISSOR_TEST)); - //Now do the drawing for this eye - Force the set as it is a "read only" cvar - Cvar_Set2("vr_stereo_side", eye == 0 ? "0" : "1", true); + if (isScopeEngaged()) { + //Now do the drawing for this eye - Force the set as it is a "read only" cvar + char buffer[5]; + Q_snprintf(buffer, 5, "%i", eye+2); + Cvar_Set2("vr_stereo_side", buffer, true); + } + else + { + //Now do the drawing for this eye - Force the set as it is a "read only" cvar + char buffer[5]; + Q_snprintf(buffer, 5, "%i", eye); + Cvar_Set2("vr_stereo_side", buffer, true); + } + //Sow the seed COM_SetRandomSeed(lSeed); diff --git a/Projects/Android/jni/src/Lambda1VR/VrCommon.h b/Projects/Android/jni/src/Lambda1VR/VrCommon.h index 13eef26..a24bea4 100644 --- a/Projects/Android/jni/src/Lambda1VR/VrCommon.h +++ b/Projects/Android/jni/src/Lambda1VR/VrCommon.h @@ -1,4 +1,6 @@ +#ifndef VRCOMMON_H +#define VRCOMMON_H #include #include @@ -57,9 +59,11 @@ int ducked; bool player_moving; +bool isMultiplayer(); +bool isScopeEngaged(); + float radians(float deg); float degrees(float rad); -bool isMultiplayer(); double GetTimeInMilliSeconds(); float length(float x, float y); float nonLinearFilter(float in); @@ -69,3 +73,5 @@ void QuatToYawPitchRoll(ovrQuatf q, float pitchAdjust, vec3_t out); bool useScreenLayer(); void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key); void Android_Vibrate( float duration, int channel, float intensity ); + +#endif //VRCOMMON_H diff --git a/Projects/Android/jni/src/Lambda1VR/VrInput.h b/Projects/Android/jni/src/Lambda1VR/VrInput.h index e7f1829..2bbe5f2 100644 --- a/Projects/Android/jni/src/Lambda1VR/VrInput.h +++ b/Projects/Android/jni/src/Lambda1VR/VrInput.h @@ -1,9 +1,13 @@ +#ifndef VRINPUT_H +#define VRINPUT_H #include "VrCommon.h" //New control scheme definitions to be defined L1VR_SurfaceView.c enumeration enum control_scheme; +#define YAWDRIFTPERFRAME 0.0026F; + ovrInputStateTrackedRemote leftTrackedRemoteState_old; ovrInputStateTrackedRemote leftTrackedRemoteState_new; ovrTracking leftRemoteTracking_new; @@ -38,5 +42,5 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr //A specific custom for left alt 2 void HandleInput_LeftAlt2( ); - +#endif //VRINPUT_H diff --git a/Projects/Android/jni/src/Lambda1VR/VrInputAlt.c b/Projects/Android/jni/src/Lambda1VR/VrInputAlt.c index 923fc64..c55c08b 100644 --- a/Projects/Android/jni/src/Lambda1VR/VrInputAlt.c +++ b/Projects/Android/jni/src/Lambda1VR/VrInputAlt.c @@ -90,6 +90,16 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr powf(pOffTracking->HeadPose.Pose.Position.y - pDominantTracking->HeadPose.Pose.Position.y, 2) + powf(pOffTracking->HeadPose.Pose.Position.z - pDominantTracking->HeadPose.Pose.Position.z, 2)); + float distanceToHMD = sqrtf(powf(hmdPosition[0] - pDominantTracking->HeadPose.Pose.Position.x, 2) + + powf(hmdPosition[1] - pDominantTracking->HeadPose.Pose.Position.y, 2) + + powf(hmdPosition[2] - pDominantTracking->HeadPose.Pose.Position.z, 2)); + + static float forwardYaw = 0; + if (!isScopeEngaged()) + { + forwardYaw = (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - snapTurn; + } + //Turn on weapon stabilisation? if ((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) != (pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) { @@ -107,6 +117,16 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr } } + //Engage scope if conditions are right + if (vr_weapon_stabilised->value == 1 && !isScopeEngaged() && distanceToHMD < 0.25) + { + sendButtonActionSimple("+alt1"); + } + else if (isScopeEngaged() && (distanceToHMD > 0.25 || vr_weapon_stabilised->value != 1)) + { + sendButtonActionSimple("-alt1"); + } + //dominant hand stuff first { ///Weapon location relative to view @@ -163,7 +183,6 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr if (zxDist != 0.0f && z != 0.0f) { VectorSet(weaponangles[ADJUSTED], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[ADJUSTED][ROLL]); VectorSet(weaponangles[UNADJUSTED], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[UNADJUSTED][ROLL]); - VectorSet(weaponangles[MELEE], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[MELEE][ROLL]); } } else @@ -173,11 +192,11 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr weaponangles[UNADJUSTED][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); weaponangles[UNADJUSTED][PITCH] *= -1.0f; - - weaponangles[MELEE][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); - weaponangles[MELEE][PITCH] *= -1.0f; } + weaponangles[MELEE][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); + weaponangles[MELEE][PITCH] *= -1.0f; + //Use (Action) if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick) != (pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick)) { @@ -397,25 +416,49 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr } - //Apply a filter and quadratic scaler so small movements are easier to make - float dist = length(pOffTrackedRemoteNew->Joystick.x, pOffTrackedRemoteNew->Joystick.y); - float nlf = nonLinearFilter(dist); - float x = nlf * pOffTrackedRemoteNew->Joystick.x; - float y = nlf * pOffTrackedRemoteNew->Joystick.y; + if (!isScopeEngaged()) { + //Apply a filter and quadratic scaler so small movements are easier to make + float dist = length(pOffTrackedRemoteNew->Joystick.x, pOffTrackedRemoteNew->Joystick.y); + float nlf = nonLinearFilter(dist); + float x = nlf * pOffTrackedRemoteNew->Joystick.x; + float y = nlf * pOffTrackedRemoteNew->Joystick.y; - player_moving = (fabs(x) + fabs(y)) > 0.01f; + player_moving = (fabs(x) + fabs(y)) > 0.01f; - //Adjust to be off-hand controller oriented - vec2_t v; - rotateAboutOrigin(x, y, controllerYawHeading,v); + //Adjust to be off-hand controller oriented + vec2_t v; + rotateAboutOrigin(x, y, controllerYawHeading,v); - remote_movementSideways = v[0]; - remote_movementForward = v[1]; + remote_movementSideways = v[0]; + remote_movementForward = v[1]; - ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", - remote_movementSideways, - remote_movementForward); + ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", + remote_movementSideways, + remote_movementForward); + } else { + static bool scopeZoomed = false; + if (between(0.75f, pOffTrackedRemoteNew->Joystick.y, 1.0f) || + between(-1.0f, pOffTrackedRemoteNew->Joystick.y, -0.75f)) + { + if (!scopeZoomed) + { + if (between(0.75f, pOffTrackedRemoteNew->Joystick.y, 1.0f)) + { + sendButtonActionSimple("impulse 104"); //zoom in + } + else if (between(-1.0f, pOffTrackedRemoteNew->Joystick.y, -0.75f)) + { + sendButtonActionSimple("impulse 105"); //zoom out + } + scopeZoomed = true; + } + } + else + { + scopeZoomed = false; + } + } //flashlight on/off @@ -487,6 +530,25 @@ void HandleInput_Alt( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovr } } } + + //YAW: Left increase, Right decrease + + //Bit of a hack, but use weapon orientation / position for view when scope is engaged + if (isScopeEngaged()) + { + //Set Position + VectorSet(hmdPosition, hmdPosition[0] + weaponoffset[0], hmdPosition[1] + weaponoffset[1], hmdPosition[2] + weaponoffset[2]); + VectorSet(weaponoffset, 0, 0, 0); + + //Set "view" Angles + VectorSet(hmdorientation, -weaponangles[ADJUSTED][PITCH], weaponangles[ADJUSTED][YAW] - (forwardYaw+snapTurn), hmdorientation[ROLL]); + } + + //Debugging +/* char buffer[1024]; + Q_snprintf(buffer, 1024, "Snap Turn:\t\t%.2f\nForward:\t\t%.2f\nDrift:\t\t%.2f\nWeapon:\t\t%.2f\nOriginal HMD:\t\t%.2f\nHMD:\t\t%.2f\ncl.refdef.viewangles Yaw:\t\t%.2f", + snapTurn, forwardYaw, driftCorrection, weaponangles[ADJUSTED][YAW], orighmdorientationyaw, hmdorientation[YAW], cl.refdef.viewangles[YAW]); + CL_CenterPrint(buffer, -1);*/ } //Save state diff --git a/Projects/Android/jni/src/Lambda1VR/VrInputDefault.c b/Projects/Android/jni/src/Lambda1VR/VrInputDefault.c index 80a91d8..504ad64 100644 --- a/Projects/Android/jni/src/Lambda1VR/VrInputDefault.c +++ b/Projects/Android/jni/src/Lambda1VR/VrInputDefault.c @@ -101,6 +101,16 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, powf(pOffTracking->HeadPose.Pose.Position.y - pDominantTracking->HeadPose.Pose.Position.y, 2) + powf(pOffTracking->HeadPose.Pose.Position.z - pDominantTracking->HeadPose.Pose.Position.z, 2)); + float distanceToHMD = sqrtf(powf(hmdPosition[0] - pDominantTracking->HeadPose.Pose.Position.x, 2) + + powf(hmdPosition[1] - pDominantTracking->HeadPose.Pose.Position.y, 2) + + powf(hmdPosition[2] - pDominantTracking->HeadPose.Pose.Position.z, 2)); + + static float forwardYaw = 0; + if (!isScopeEngaged()) + { + forwardYaw = (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - snapTurn; + } + //Turn on weapon stabilisation? if ((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) != (pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) { @@ -115,9 +125,20 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, else { Cvar_Set2("vr_weapon_stabilised", "0", true); + } } + //Engage scope if conditions are right + if (vr_weapon_stabilised->value == 1 && !isScopeEngaged() && distanceToHMD < 0.25) + { + sendButtonActionSimple("+alt1"); + } + else if (isScopeEngaged() && (distanceToHMD > 0.25 || vr_weapon_stabilised->value != 1)) + { + sendButtonActionSimple("-alt1"); + } + //dominant hand stuff first { ///Weapon location relative to view @@ -172,9 +193,8 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, float zxDist = length(x, z); if (zxDist != 0.0f && z != 0.0f) { - VectorSet(weaponangles[ADJUSTED], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[ADJUSTED][ROLL]); - VectorSet(weaponangles[UNADJUSTED], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[UNADJUSTED][ROLL]); - VectorSet(weaponangles[MELEE], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[MELEE][ROLL]); + VectorSet(weaponangles[ADJUSTED], degrees(atanf(y / zxDist)), (forwardYaw+snapTurn) - degrees(atan2f(x, -z)), weaponangles[ADJUSTED][ROLL]); + VectorSet(weaponangles[UNADJUSTED], degrees(atanf(y / zxDist)), (forwardYaw+snapTurn) - degrees(atan2f(x, -z)), weaponangles[UNADJUSTED][ROLL]); } } else @@ -184,11 +204,11 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, weaponangles[UNADJUSTED][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); weaponangles[UNADJUSTED][PITCH] *= -1.0f; - - weaponangles[MELEE][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); - weaponangles[MELEE][PITCH] *= -1.0f; } + weaponangles[MELEE][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); + weaponangles[MELEE][PITCH] *= -1.0f; + //Use (Action) if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick) != (pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick)) { @@ -414,25 +434,50 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, } - //Apply a filter and quadratic scaler so small movements are easier to make - float dist = length(pOffTrackedRemoteNew->Joystick.x, pOffTrackedRemoteNew->Joystick.y); - float nlf = nonLinearFilter(dist); - float x = nlf * pOffTrackedRemoteNew->Joystick.x; - float y = nlf * pOffTrackedRemoteNew->Joystick.y; + if (!isScopeEngaged()) { + //Apply a filter and quadratic scaler so small movements are easier to make + float dist = length(pOffTrackedRemoteNew->Joystick.x, + pOffTrackedRemoteNew->Joystick.y); + float nlf = nonLinearFilter(dist); + float x = nlf * pOffTrackedRemoteNew->Joystick.x; + float y = nlf * pOffTrackedRemoteNew->Joystick.y; - player_moving = (fabs(x) + fabs(y)) > 0.01f; + player_moving = (fabs(x) + fabs(y)) > 0.01f; - //Adjust to be off-hand controller oriented - vec2_t v; - rotateAboutOrigin(x, y, controllerYawHeading,v); + //Adjust to be off-hand controller oriented + vec2_t v; + rotateAboutOrigin(x, y, controllerYawHeading, v); - remote_movementSideways = v[0]; - remote_movementForward = v[1]; + remote_movementSideways = v[0]; + remote_movementForward = v[1]; - ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", - remote_movementSideways, - remote_movementForward); + ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", + remote_movementSideways, + remote_movementForward); + } else { + static bool scopeZoomed = false; + if (between(0.75f, pOffTrackedRemoteNew->Joystick.y, 1.0f) || + between(-1.0f, pOffTrackedRemoteNew->Joystick.y, -0.75f)) + { + if (!scopeZoomed) + { + if (between(0.75f, pOffTrackedRemoteNew->Joystick.y, 1.0f)) + { + sendButtonActionSimple("impulse 104"); //zoom in + } + else if (between(-1.0f, pOffTrackedRemoteNew->Joystick.y, -0.75f)) + { + sendButtonActionSimple("impulse 105"); //zoom out + } + scopeZoomed = true; + } + } + else + { + scopeZoomed = false; + } + } //flashlight on/off @@ -499,7 +544,26 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, decreaseSnap = true; } } - } + + //YAW: Left increase, Right decrease + + //Bit of a hack, but use weapon orientation / position for view when scope is engaged + if (isScopeEngaged()) + { + //Set Position + VectorSet(hmdPosition, hmdPosition[0] + weaponoffset[0], hmdPosition[1] + weaponoffset[1], hmdPosition[2] + weaponoffset[2]); + VectorSet(weaponoffset, 0, 0, 0); + + //Set "view" Angles + VectorSet(hmdorientation, -weaponangles[ADJUSTED][PITCH], weaponangles[ADJUSTED][YAW] - (forwardYaw+snapTurn), hmdorientation[ROLL]); + } + + //Debugging +/* char buffer[1024]; + Q_snprintf(buffer, 1024, "Snap Turn:\t\t%.2f\nForward:\t\t%.2f\nDrift:\t\t%.2f\nWeapon:\t\t%.2f\nOriginal HMD:\t\t%.2f\nHMD:\t\t%.2f\ncl.refdef.viewangles Yaw:\t\t%.2f", + snapTurn, forwardYaw, driftCorrection, weaponangles[ADJUSTED][YAW], orighmdorientationyaw, hmdorientation[YAW], cl.refdef.viewangles[YAW]); + CL_CenterPrint(buffer, -1);*/ + } //Save state leftTrackedRemoteState_old = leftTrackedRemoteState_new; diff --git a/Projects/Android/jni/src/Lambda1VR/VrInputLeftAlt2.c b/Projects/Android/jni/src/Lambda1VR/VrInputLeftAlt2.c index ef99fa1..5e9a01e 100644 --- a/Projects/Android/jni/src/Lambda1VR/VrInputLeftAlt2.c +++ b/Projects/Android/jni/src/Lambda1VR/VrInputLeftAlt2.c @@ -95,6 +95,16 @@ void HandleInput_LeftAlt2() powf(rightRemoteTracking_new.HeadPose.Pose.Position.y - leftRemoteTracking_new.HeadPose.Pose.Position.y, 2) + powf(rightRemoteTracking_new.HeadPose.Pose.Position.z - leftRemoteTracking_new.HeadPose.Pose.Position.z, 2)); + float distanceToHMD = sqrtf(powf(hmdPosition[0] - leftRemoteTracking_new.HeadPose.Pose.Position.x, 2) + + powf(hmdPosition[1] - leftRemoteTracking_new.HeadPose.Pose.Position.y, 2) + + powf(hmdPosition[2] - leftRemoteTracking_new.HeadPose.Pose.Position.z, 2)); + + static float forwardYaw = 0; + if (!isScopeEngaged()) + { + forwardYaw = (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - snapTurn; + } + //Turn on weapon stabilisation? if ((rightTrackedRemoteState_new.Buttons & ovrButton_GripTrigger) != (rightTrackedRemoteState_old.Buttons & ovrButton_GripTrigger)) { @@ -112,6 +122,16 @@ void HandleInput_LeftAlt2() } } + //Engage scope if conditions are right + if (vr_weapon_stabilised->value == 1 && !isScopeEngaged() && distanceToHMD < 0.25) + { + sendButtonActionSimple("+alt1"); + } + else if (isScopeEngaged() && (distanceToHMD > 0.25 || vr_weapon_stabilised->value != 1)) + { + sendButtonActionSimple("-alt1"); + } + //dominant hand stuff first { ///Weapon location relative to view @@ -168,7 +188,6 @@ void HandleInput_LeftAlt2() if (zxDist != 0.0f && z != 0.0f) { VectorSet(weaponangles[ADJUSTED], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[ADJUSTED][ROLL]); VectorSet(weaponangles[UNADJUSTED], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[UNADJUSTED][ROLL]); - VectorSet(weaponangles[MELEE], degrees(atanf(y / zxDist)), (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[MELEE][ROLL]); } } else @@ -178,11 +197,11 @@ void HandleInput_LeftAlt2() weaponangles[UNADJUSTED][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); weaponangles[UNADJUSTED][PITCH] *= -1.0f; - - weaponangles[MELEE][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); - weaponangles[MELEE][PITCH] *= -1.0f; } + weaponangles[MELEE][YAW] += (cl.refdef.cl_viewangles[YAW] - hmdorientation[YAW]); + weaponangles[MELEE][PITCH] *= -1.0f; + //Use (Action) if ((leftTrackedRemoteState_new.Buttons & ovrButton_Joystick) != (leftTrackedRemoteState_old.Buttons & ovrButton_Joystick)) { @@ -366,25 +385,49 @@ void HandleInput_LeftAlt2() Cvar_SetFloat("vr_lasersight", 1.0f - vr_lasersight->value); } - //Apply a filter and quadratic scaler so small movements are easier to make - float dist = length(leftTrackedRemoteState_new.Joystick.x, leftTrackedRemoteState_new.Joystick.y); - float nlf = nonLinearFilter(dist); - float x = nlf * leftTrackedRemoteState_new.Joystick.x; - float y = nlf * leftTrackedRemoteState_new.Joystick.y; + if (!isScopeEngaged()) { + //Apply a filter and quadratic scaler so small movements are easier to make + float dist = length(leftTrackedRemoteState_new.Joystick.x, leftTrackedRemoteState_new.Joystick.y); + float nlf = nonLinearFilter(dist); + float x = nlf * leftTrackedRemoteState_new.Joystick.x; + float y = nlf * leftTrackedRemoteState_new.Joystick.y; - player_moving = (fabs(x) + fabs(y)) > 0.01f; + player_moving = (fabs(x) + fabs(y)) > 0.01f; - //Adjust to be off-hand controller oriented - vec2_t v; - rotateAboutOrigin(x, y, controllerYawHeading, v); + //Adjust to be off-hand controller oriented + vec2_t v; + rotateAboutOrigin(x, y, controllerYawHeading, v); - remote_movementSideways = v[0]; - remote_movementForward = v[1]; + remote_movementSideways = v[0]; + remote_movementForward = v[1]; - ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", - remote_movementSideways, - remote_movementForward); + ALOGV(" remote_movementSideways: %f, remote_movementForward: %f", + remote_movementSideways, + remote_movementForward); + } else { + static bool scopeZoomed = false; + if (between(0.75f, rightTrackedRemoteState_new.Joystick.y, 1.0f) || + between(-1.0f, rightTrackedRemoteState_new.Joystick.y, -0.75f)) + { + if (!scopeZoomed) + { + if (between(0.75f, rightTrackedRemoteState_new.Joystick.y, 1.0f)) + { + sendButtonActionSimple("impulse 104"); //zoom in + } + else if (between(-1.0f, rightTrackedRemoteState_new.Joystick.y, -0.75f)) + { + sendButtonActionSimple("impulse 105"); //zoom out + } + scopeZoomed = true; + } + } + else + { + scopeZoomed = false; + } + } //flashlight on/off @@ -451,6 +494,25 @@ void HandleInput_LeftAlt2() decreaseSnap = true; } } + + //YAW: Left increase, Right decrease + + //Bit of a hack, but use weapon orientation / position for view when scope is engaged + if (isScopeEngaged()) + { + //Set Position + VectorSet(hmdPosition, hmdPosition[0] + weaponoffset[0], hmdPosition[1] + weaponoffset[1], hmdPosition[2] + weaponoffset[2]); + VectorSet(weaponoffset, 0, 0, 0); + + //Set "view" Angles + VectorSet(hmdorientation, -weaponangles[ADJUSTED][PITCH], weaponangles[ADJUSTED][YAW] - (forwardYaw+snapTurn), hmdorientation[ROLL]); + } + + //Debugging +/* char buffer[1024]; + Q_snprintf(buffer, 1024, "Snap Turn:\t\t%.2f\nForward:\t\t%.2f\nDrift:\t\t%.2f\nWeapon:\t\t%.2f\nOriginal HMD:\t\t%.2f\nHMD:\t\t%.2f\ncl.refdef.viewangles Yaw:\t\t%.2f", + snapTurn, forwardYaw, driftCorrection, weaponangles[ADJUSTED][YAW], orighmdorientationyaw, hmdorientation[YAW], cl.refdef.viewangles[YAW]); + CL_CenterPrint(buffer, -1);*/ } //Save state diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_game.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_game.c index 4470f5b..0e31a76 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_game.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_game.c @@ -693,6 +693,41 @@ void CL_DrawVignette( void ) } + +/* +============= +CL_DrawScope + + +============= +*/ +bool isScopeEngaged(); + +void CL_DrawScope( void ) +{ + const float scopeSize = 0.75; + static float currentVLevel = 0.0; + if (isScopeEngaged()) + { + if (currentVLevel < scopeSize) + currentVLevel += scopeSize * 0.05; + } else{ + if (currentVLevel > 0.0) + currentVLevel -= scopeSize * 0.05; + } + + if (currentVLevel > 0.0 && + currentVLevel < 1.0) { + int x = (int) ((scr_width->integer / 2) * currentVLevel); + int y = (int) ((scr_height->integer / 2) * currentVLevel); + + GL_SetRenderMode(kRenderTransTexture); + R_DrawStretchPic(x, y, scr_width->integer - (2 * x), scr_height->integer - (2 * y), 0, 0, 1, + 1, + cls.scopeImage); + pglColor4ub(255, 255, 255, 255); + } +} /* ============= CL_DrawScreenFade @@ -940,7 +975,7 @@ void CL_DrawCrosshair( void ) int x, y, width, height; cl_entity_t *pPlayer; - if( !crosshair_state.pCrosshair || cl.refdef.crosshairangle[2] || !cl_crosshair->integer ) + if( !crosshair_state.pCrosshair || !isScopeEngaged() ) return; pPlayer = CL_GetLocalPlayer(); @@ -961,7 +996,7 @@ void CL_DrawCrosshair( void ) // g-cont - cl.refdef.crosshairangle is the autoaim angle. // if we're not using autoaim, just draw in the middle of the screen - if( !VectorIsNull( cl.refdef.crosshairangle )) +/* if( !VectorIsNull( cl.refdef.crosshairangle )) { vec3_t angles; vec3_t forward; @@ -974,7 +1009,7 @@ void CL_DrawCrosshair( void ) x += 0.5f * screen[0] * scr_width->value + 0.5f; y += 0.5f * screen[1] * scr_height->value + 0.5f; - } + }*/ clgame.ds.pSprite = crosshair_state.pCrosshair; @@ -1851,7 +1886,7 @@ like trigger_multiple message in q1 static void GAME_EXPORT pfnCenterPrint( const char *string ) { if( !string || !*string ) return; // someone stupid joke - CL_CenterPrint( string, 0.25f ); + CL_CenterPrint( string, -1.0f ); } /* diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_main.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_main.c index d207d12..a37cb54 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_main.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_main.c @@ -2281,7 +2281,7 @@ void Host_ClientFrame( ) int eye = Cvar_VariableInteger("vr_stereo_side"); - if (eye == VR_EYE_MONO || eye == VR_EYE_LEFT ) { + if (eye == VR_EYE_LEFT || eye == VR_EYE_LEFT_MONO) { #endif cl.oldtime = cl.time; cl.time += host.frametime; @@ -2327,7 +2327,7 @@ void Host_ClientFrame( ) SCR_UpdateScreen (); #ifdef VR - if (eye == VR_EYE_MONO || eye == VR_EYE_RIGHT) + if (eye == VR_EYE_RIGHT || eye == VR_EYE_RIGHT_MONO) #endif { if( cls.initialized ) diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_scrn.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_scrn.c index 0d6da26..d014fa2 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_scrn.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_scrn.c @@ -45,6 +45,9 @@ static qboolean scr_init = false; int GetStereoDepthOffset() { + if (vr_stereo_side->value >= VR_EYE_LEFT_MONO) + return 0; + return (int)( ( vr_stereo_side->value * -2.0f ) + 1.0f) * (scr_width->integer / 36.0f); } @@ -607,6 +610,7 @@ void SCR_RegisterTextures( void ) { cls.fillImage = GL_LoadTexture( "*white", NULL, 0, TF_IMAGE, NULL ); // used for FillRGBA cls.vignetteImage = GL_LoadTexture( "sprites/vignette.tga", NULL, 0, TF_IMAGE, NULL ); // used for puke reducing vignette + cls.scopeImage = GL_LoadTexture( "sprites/scope.tga", NULL, 0, TF_IMAGE, NULL ); // used for weapons with scopes cls.particleImage = GL_LoadTexture( "*particle", NULL, 0, TF_IMAGE, NULL ); // register gfx.wad images diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_view.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_view.c index 00c61d0..ee36b0e 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_view.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/cl_view.c @@ -154,6 +154,12 @@ void V_SetupRefDef( void ) VectorCopy(weaponangles[1], cl.refdef.weapon.angles.unadjusted); VectorCopy(weaponangles[2], cl.refdef.weapon.angles.melee); + //Scope + if (cl.scr_fov < 90) { + VectorAdd(cl.refdef.simorg, cl.refdef.weapon.org, cl.refdef.simorg); + VectorSet(cl.refdef.weapon.org, 0, 0, 0); + } + //Flashlight convertFromVRtoHL(flashlightoffset, cl.refdef.flashlight.org); cl.refdef.flashlight.org[2] += cl.refdef.viewheight[2]; // Have to do this for some reason.. @@ -359,7 +365,8 @@ void V_CalcRefDef( void ) do { //Only recalc refdef once - if (vr_stereo_side->integer == VR_EYE_LEFT || vr_stereo_side->integer == VR_EYE_MONO) { + int eye = vr_stereo_side->integer; + if (eye == VR_EYE_LEFT || eye == VR_EYE_LEFT_MONO) { clgame.dllFuncs.pfnCalcRefdef(&cl.refdef); V_MergeOverviewRefdef(&cl.refdef); } @@ -389,7 +396,7 @@ void V_RenderView( void ) int eye = Cvar_VariableInteger("vr_stereo_side"); - if( eye == VR_EYE_LEFT && cl.frame.valid && ( cl.force_refdef || !cl.refdef.paused )) + if( (eye == VR_EYE_LEFT || eye == VR_EYE_LEFT_MONO) && cl.frame.valid && ( cl.force_refdef || !cl.refdef.paused )) { cl.force_refdef = false; @@ -451,6 +458,7 @@ void V_PostRender( void ) { SCR_TileClear(); CL_DrawVignette(); + CL_DrawScope(); CL_DrawHUD( CL_ACTIVE ); VGui_Paint(); } diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h index b2d184d..b18bede 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/client.h @@ -490,6 +490,7 @@ typedef struct int glowShell; // for renderFxGlowShell int tileImage; // for draw any areas not covered by the refresh int vignetteImage; + int scopeImage; HSPRITE hChromeSprite; // this is a really HudSprite handle, not texnum! cl_font_t creditsFont; // shared creditsfont @@ -690,6 +691,7 @@ void CL_FreeEdicts( void ); void CL_ClearWorld( void ); void CL_DrawCenterPrint( void ); void CL_DrawVignette( void ); +void CL_DrawScope( void ); void CL_FreeEntity( cl_entity_t *pEdict ); void CL_CenterPrint( const char *text, float y ); void CL_TextMessageParse( byte *pMemFile, int fileSize ); diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c index 6ad4aaf..2906854 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_rmain.c @@ -662,10 +662,11 @@ extern convar_t *vr_stereo_side; static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m ) { Matrix4x4_CreateModelview( m ); - Matrix4x4_ConcatTranslate( m, 0, vr_worldscale->value * (0.065f / 2.0f) * ((vr_stereo_side->integer - 0.5f) * 2.0f), 0 ); - //Move eyes forward 3cm - super rudimentary neck model lol - Matrix4x4_ConcatTranslate( m, vr_worldscale->value * -0.025f, 0, 0 ); + if (vr_stereo_side->value == VR_EYE_LEFT || vr_stereo_side->value == VR_EYE_RIGHT) { + Matrix4x4_ConcatTranslate(m, 0, vr_worldscale->value * (VR_IPD / 2.0f) * + ((vr_stereo_side->integer - 0.5f) * 2.0f), 0); + } Matrix4x4_ConcatRotate( m, -fd->viewangles[ROLL], 1, 0, 0 ); Matrix4x4_ConcatRotate( m, -fd->viewangles[PITCH], 0, 1, 0 ); diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c index 016d0e1..2a7be42 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/client/gl_studio.c @@ -3724,10 +3724,14 @@ R_DrawViewModel extern convar_t *vr_mirror_weapons; extern convar_t *vr_weapon_backface_culling; +int bScopeEngaged() +{ + return (cl.scr_fov != 0 && cl.scr_fov < 90.0f); +} void R_DrawViewModel( void ) { - if( RI.refdef.onlyClientDraw || r_drawviewmodel->integer == 0 ) + if( RI.refdef.onlyClientDraw || r_drawviewmodel->integer == 0 || bScopeEngaged()) return; // ignore in thirdperson, camera view or client is died diff --git a/Projects/Android/jni/src/Xash3D/xash3d/engine/common/common.h b/Projects/Android/jni/src/Xash3D/xash3d/engine/common/common.h index 8ece398..bf7a148 100644 --- a/Projects/Android/jni/src/Xash3D/xash3d/engine/common/common.h +++ b/Projects/Android/jni/src/Xash3D/xash3d/engine/common/common.h @@ -180,9 +180,12 @@ typedef enum #define MAX_FPS 500.0 // upper limit for maxfps. #ifdef VR -#define VR_EYE_MONO -1 +#define VR_IPD 0.065f #define VR_EYE_LEFT 0 #define VR_EYE_RIGHT 1 +#define VR_EYE_LEFT_MONO 2 +#define VR_EYE_RIGHT_MONO 3 +#define VR_FOV 104.0f #endif #define MAX_FRAMETIME 0.1 diff --git a/java/com/drbeef/lambda1vr/GLES3JNIActivity.java b/java/com/drbeef/lambda1vr/GLES3JNIActivity.java index 2ced974..1d86ec8 100644 --- a/java/com/drbeef/lambda1vr/GLES3JNIActivity.java +++ b/java/com/drbeef/lambda1vr/GLES3JNIActivity.java @@ -313,7 +313,10 @@ import static android.system.Os.setenv; if (game.equalsIgnoreCase("gearbox") && !(new File("/sdcard/xash/" + game + "/models/no_copy").exists())) { - + //Scope vignette texture + copy_asset("/sdcard/xash/" + game + "/", "sprites/scope.tga", true); + copy_asset("/sdcard/xash/valve/", "sprites/scope.tga", true); + } //Set default environment