two handed pistol stabilisation

Draw iron sight lock mode as mono
This commit is contained in:
Simon 2020-08-26 10:01:48 +01:00
parent e60b606b57
commit f0d839b38f
9 changed files with 79 additions and 47 deletions

View file

@ -29,11 +29,14 @@ typedef struct {
vec3_t weaponangles_last; // Don't use this, it is just for calculating delta!
vec3_t weaponangles_delta;
vec3_t weaponoffset;
float weaponoffset_timestamp;
vec3_t current_weaponoffset;
vec3_t calculated_weaponoffset;
float current_weaponoffset_timestamp;
vec3_t weaponoffset_history[NUM_WEAPON_SAMPLES];
float weaponoffset_history_timestamp[NUM_WEAPON_SAMPLES];
qboolean pistol; // True if the weapon is a pistol
//Lots of scope weapon stuff
qboolean scopeengaged; // Scope has been engaged on a scoped weapon
qboolean scopedweapon; // Weapon scope is available

View file

@ -7,6 +7,7 @@
//New control scheme definitions to be defined L1VR_SurfaceView.c enumeration
enum control_scheme;
#define STABILISATION_DISTANCE 0.5
#define SCOPE_ENGAGE_DISTANCE 0.25
#define VSTOCK_ENGAGE_DISTANCE 0.25
#define BINOCULAR_ENGAGE_DISTANCE 0.25

View file

@ -134,14 +134,14 @@ void updateScopeAngles()
if (vr.vstock_engaged)
{
//Copy weapon offset X
vr.weaponoffset[0] = vr.vstock_weapon_offset[1];
vr.weaponoffset[1] = vr.vstock_weapon_offset[2];
vr.weaponoffset[2] = vr.vstock_weapon_offset[0];
vr.calculated_weaponoffset[0] = vr.vstock_weapon_offset[1];
vr.calculated_weaponoffset[1] = vr.vstock_weapon_offset[2];
vr.calculated_weaponoffset[2] = vr.vstock_weapon_offset[0];
}
else
{
//Clear weapon offset
VectorSet(vr.weaponoffset, 0, 0, 0);
VectorSet(vr.calculated_weaponoffset, 0, 0, 0);
}
VectorSet(currentScopeAngles, vr.weaponangles[PITCH], vr.weaponangles[YAW], vr.hmdorientation[ROLL]);

View file

@ -166,21 +166,20 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
powf(vr.hmdposition[2] - pWeapon->HeadPose.Pose.Position.z, 2));
//Turn on weapon stabilisation?
if ((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) !=
(pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) {
if (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger)
qboolean stabilised = qfalse;
if (vr.pistol)
{
//For pistols, it is simply a case of holding the two controllers close together
if (distance < (STABILISATION_DISTANCE / 2.0f))
{
if (distance < 0.50f)
{
vr.weapon_stabilised = qtrue;
}
}
else
{
vr.weapon_stabilised = qfalse;
stabilised = qtrue;
}
}
else if ((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) && (distance < STABILISATION_DISTANCE))
{
stabilised = qtrue;
}
vr.weapon_stabilised = stabilised;
//Engage scope / virtual stock if conditions are right
qboolean scopeready = vr.weapon_stabilised && (distanceToHMD < SCOPE_ENGAGE_DISTANCE);
@ -239,14 +238,17 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
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;
VectorCopy(vr.current_weaponoffset, vr.weaponoffset_history[0]);
vr.weaponoffset_history_timestamp[0] = vr.current_weaponoffset_timestamp;
///Weapon location relative to view
vr.weaponoffset[0] = pWeapon->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.weaponoffset[1] = pWeapon->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.weaponoffset[2] = pWeapon->HeadPose.Pose.Position.z - vr.hmdposition[2];
vr.weaponoffset_timestamp = Sys_Milliseconds( );
vr.current_weaponoffset[0] = pWeapon->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.current_weaponoffset[1] = pWeapon->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.current_weaponoffset[2] = pWeapon->HeadPose.Pose.Position.z - vr.hmdposition[2];
vr.current_weaponoffset_timestamp = Sys_Milliseconds( );
//Lerp (stabilises pistol) - Won't have any effect on any other weapons
VectorLerp(vr.weaponoffset_history[1], (vr.pistol && vr.weapon_stabilised) ? 0.25f : 1.0f, vr.current_weaponoffset, vr.calculated_weaponoffset);
//Does weapon velocity trigger attack (knife) and is it fast enough
static qboolean velocityTriggeredAttack = false;
@ -273,12 +275,13 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
sendButtonAction("+attack", velocityTriggeredAttack);
}
if (vr.weapon_stabilised || vr.dualwield)
//Don't do this for pistols
if (!vr.pistol && (vr.weapon_stabilised || vr.dualwield))
{
if (vr.scopeengaged || vr.vstock_engaged)
{
float x = pOff->HeadPose.Pose.Position.x - vr.hmdposition[0];
float y = pOff->HeadPose.Pose.Position.y - vr.hmdposition[1];
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];
float zxDist = length(x, z);
@ -301,11 +304,16 @@ void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
else
{
VectorSet(vr.weaponangles, -degrees(atanf(y / zxDist)),
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL]);
-degrees(atan2f(x, -z)), vr.weaponangles[ROLL] / 2.0f); //Dampen roll on stabilised weapon
}
}
}
}
else if (vr.pistol && vr.weapon_stabilised)
{
//No roll if pistol is being stabilised with off-hand
vr.weaponangles[ROLL] = 0;
}
static bool finishReloadNextFrame = false;
if (finishReloadNextFrame)

View file

@ -81,10 +81,10 @@ void HandleInput_WeaponAlign( ovrInputStateTrackedRemote *pDominantTrackedRemote
//dominant hand stuff first
{
///Weapon location relative to view
vr.weaponoffset[0] = pDominantTracking->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.weaponoffset[1] = pDominantTracking->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.weaponoffset[2] = pDominantTracking->HeadPose.Pose.Position.z - vr.hmdposition[2];
vr.weaponoffset_timestamp = Sys_Milliseconds( );
vr.current_weaponoffset[0] = pDominantTracking->HeadPose.Pose.Position.x - vr.hmdposition[0];
vr.current_weaponoffset[1] = pDominantTracking->HeadPose.Pose.Position.y - vr.hmdposition[1];
vr.current_weaponoffset[2] = pDominantTracking->HeadPose.Pose.Position.z - vr.hmdposition[2];
vr.current_weaponoffset_timestamp = Sys_Milliseconds( );
}
float controllerYawHeading = 0.0f;

View file

@ -3681,9 +3681,11 @@ void CG_DrawActive( int stereoView ) {
// offset vieworg appropriately if we're doing stereo separation
VectorCopy( cg.refdef.vieworg, baseOrg );
int vStock = trap_Cvar_VariableIntegerValue("vr_virtual_stock");
int vr_cinematic_stereo = trap_Cvar_VariableIntegerValue( "vr_cinematic_stereo");
if ( !cgVR->scopeengaged &&
(!cg.cameraMode || (cg.cameraMode && vr_cinematic_stereo))) {
(!cg.cameraMode || (cg.cameraMode && vr_cinematic_stereo)) &&
!cgVR->vstock_engaged) {
VectorMA( cg.refdef.vieworg, -separation, cg.refdef.viewaxis[1], cg.refdef.vieworg );
}

View file

@ -276,26 +276,26 @@ int weapBanksMultiPlayer[MAX_WEAP_BANKS_MP][MAX_WEAPS_IN_BANK_MP] = {
//These are in real world units (metres)
float virtualStockOffsets[WP_SILENCER][3] = {
//Right Up Forward
//Yaw Adjust Up Forward
{0, 0, 0} ,//WP_NONE,
{0, 0, 0} ,//WP_KNIFE,
{0, 0, 0} ,//WP_LUGER,
{0, 0, 0} ,//WP_MP40,
{0.03f, -0.08f, -0.35f} ,//WP_MAUSER,
{0.03f, -0.12f, -0.25f} ,//WP_FG42,
{0, -0.08f, -0.35f} ,//WP_MAUSER,
{0.4f, -0.12f, -0.25f} ,//WP_FG42, - needs a slight yaw tweak
{0, 0, 0} ,//WP_GRENADE_LAUNCHER,
{0, 0, 0} ,//WP_PANZERFAUST,
{0, 0, 0} ,//WP_VENOM,
{0, 0, 0} ,//WP_FLAMETHROWER,
{0, 0, 0} ,//WP_TESLA,
{0, 0, 0} ,//WP_COLT,
{0.03f, -0.108f, -0.3f} ,//WP_THOMPSON,
{0, -0.108f, -0.3f} ,//WP_THOMPSON,
{0, 0, 0} ,//WP_GARAND,
{0, 0, 0} ,//WP_GRENADE_PINEAPPLE,
{0, 0, 0} ,//WP_SNIPERRIFLE,
{0, 0, 0} ,//WP_SNOOPERSCOPE,
{0, 0, 0} ,//WP_FG42SCOPE,
{0.0325f, -0.06f, -0.24f}//WP_STEN,
{0, -0.06f, -0.24f}//WP_STEN,
};
/*
@ -2003,7 +2003,7 @@ void CG_CalculateVRWeaponPosition( int weaponNum, vec3_t origin, vec3_t angles )
if (weaponNum != WP_AKIMBO || BG_AkimboFireSequence(weaponNum, cg.predictedPlayerState.ammoclip[WP_AKIMBO], cg.predictedPlayerState.ammoclip[WP_COLT] ))
{
convertFromVR(cgVR->weaponoffset, cg.refdef.vieworg, origin);
convertFromVR(cgVR->calculated_weaponoffset, cg.refdef.vieworg, origin);
} else{
convertFromVR(cgVR->offhandoffset, cg.refdef.vieworg, origin);
}
@ -2091,6 +2091,10 @@ static float CG_CalculateWeaponPositionAndScale( playerState_t *ps, vec3_t origi
&(adjust[PITCH]), &(adjust[YAW]), &(adjust[ROLL]));
VectorScale(temp_offset, scale, offset);
if (cgVR->vstock_engaged) {
adjust[YAW] += virtualStockOffsets[ps->weapon][0];
}
if (!cgVR->right_handed)
{
//yaw needs to go in the other direction as left handed model is reversed
@ -3657,12 +3661,21 @@ void CG_AddViewWeapon( playerState_t *ps ) {
//Set some important flags based on the current weapon
cgVR->mountedgun = qfalse;
cgVR->pistol = qfalse;
switch ( ps->weapon ) {
case WP_KNIFE:
cgVR->velocitytriggered = qtrue;
cgVR->scopedweapon = qfalse;
cgVR->vstock_weapon = qfalse;
break;
case WP_LUGER:
case WP_SILENCER:
case WP_COLT:
cgVR->velocitytriggered = qfalse;
cgVR->scopedweapon = qfalse;
cgVR->vstock_weapon = qfalse;
cgVR->pistol = qtrue;
break;
case WP_FG42:
case WP_MAUSER:
cgVR->velocitytriggered = qfalse;
@ -3707,7 +3720,7 @@ void CG_AddViewWeapon( playerState_t *ps ) {
vec3_t forward, right, up;
AngleVectors(orientation, forward, right, up);
VectorMA(offset, virtualStockOffsets[ps->weapon][0] * multiplier, right, offset);
//VectorMA(offset, (cg_stereoSeparation.value / 2.0f) * multiplier, right, offset);
VectorMA(offset, virtualStockOffsets[ps->weapon][1], up, offset);
VectorMA(offset, virtualStockOffsets[ps->weapon][2], forward, offset);

View file

@ -59,7 +59,7 @@ extern vmCvar_t g_gametype;
// these defines are matched with the character torso animations
#define DELAY_LOW 100 // machineguns, tesla, spear, flame
#define DELAY_HIGH 100 // mauser, garand
#define DELAY_PISTOL 100 // colt, luger, sp5, cross
#define DELAY_PISTOL 75 // colt, luger, sp5, cross
#define DELAY_SHOULDER 50 // rl
#define DELAY_THROW 250 // grenades, dynamite
#define DELAY_THROW_VR 15 // grenades, dynamite
@ -92,7 +92,7 @@ ammotable_t ammoTable[] = {
{ 999, 0, 999, 0, 50, 200, 0, 0, MOD_KNIFE }, // WP_KNIFE // 1
{ MAX_AMMO_9MM, 1, 8, 1500, DELAY_PISTOL, 400, 0, 0, MOD_LUGER }, // WP_LUGER // 2 // NOTE: also 32 round 'snail' magazine
{ MAX_AMMO_9MM, 1, 8, 1500, DELAY_PISTOL, 250, 0, 0, MOD_LUGER }, // WP_LUGER // 2 // NOTE: also 32 round 'snail' magazine
{ MAX_AMMO_9MM, 1, 32, 2600, DELAY_LOW, 100, 0, 0, MOD_MP40 }, // WP_MP40 // 3
{ MAX_AMMO_MAUSER,1, 10, 2500, DELAY_HIGH, 1200, 0, 0, MOD_MAUSER }, // WP_MAUSER // 4 // NOTE: authentic clips are 5/10/25 rounds
{ MAX_AMMO_FG42, 1, 20, 2000, DELAY_LOW, 200, 0, 0, MOD_FG42 }, // WP_FG42 // 5
@ -105,7 +105,7 @@ ammotable_t ammoTable[] = {
// { 50, 1, 50, 1000, DELAY_LOW, 1200, 0, 0, MOD_SPEARGUN }, // WP_SPEARGUN // 11
// { 999, 0, 999, 0, 50, 200, 0, 0, MOD_KNIFE2 }, // WP_KNIFE2 // 12
{ MAX_AMMO_45, 1, 8, 1500, DELAY_PISTOL, 400, 0, 0, MOD_COLT }, // WP_COLT // 13
{ MAX_AMMO_45, 1, 8, 1500, DELAY_PISTOL, 250, 0, 0, MOD_COLT }, // WP_COLT // 13
{ MAX_AMMO_45, 1, 30, 2400, DELAY_LOW, 120, 0, 0, MOD_THOMPSON }, // WP_THOMPSON // 14 // NOTE: also 50 round drum magazine
{ MAX_AMMO_GARAND,1, 5, 2500, DELAY_HIGH, 1200, 0, 0, MOD_GARAND }, // WP_GARAND // 15 // NOTE: always 5 round clips
// { MAX_AMMO_BAR, 1, 20, 2000, DELAY_LOW, 200, 0, 0, MOD_BAR }, // WP_BAR // 16
@ -121,8 +121,8 @@ ammotable_t ammoTable[] = {
{ MAX_AMMO_FG42, 1, 20, 2000, DELAY_LOW, 200, 0, 0, MOD_FG42SCOPE }, // WP_FG42SCOPE // 23
// { MAX_AMMO_BAR, 1, 20, 2000, DELAY_LOW, 90, 0, 0, MOD_BAR }, // WP_BAR2 // 24
{ MAX_AMMO_9MM, 1, 32, 3100, DELAY_LOW, 110, 700, 300, MOD_STEN }, // WP_STEN // 25
{ MAX_AMMO_9MM, 1, 8, 1500, DELAY_PISTOL, 400, 0, 0, MOD_SILENCER }, // WP_SILENCER // 26
{ MAX_AMMO_45, 1, 8, 2700, DELAY_PISTOL, 200, 0, 0, MOD_AKIMBO }, // WP_AKIMBO // 27
{ MAX_AMMO_9MM, 1, 8, 1500, DELAY_PISTOL, 250, 0, 0, MOD_SILENCER }, // WP_SILENCER // 26
{ MAX_AMMO_45, 1, 8, 2700, DELAY_PISTOL, 125, 0, 0, MOD_AKIMBO }, // WP_AKIMBO // 27
{ 999, 0, 999, 0, 50, 0, 0, 0, 0 }, // WP_CLASS_SPECIAL // 28 // class_special
// { 100, 1, 100, 1000, DELAY_PISTOL, 900, 0, 0, MOD_CROSS }, // WP_CROSS // 29

View file

@ -1744,7 +1744,7 @@ void CalcMuzzlePoint( gentity_t *ent, int weapon, vec3_t forward, vec3_t right,
float worldscale = trap_Cvar_VariableIntegerValue("cg_worldScale");
float heightAdjust = 0;
trap_Cvar_VariableValue("cg_heightAdjust", &heightAdjust);
convertFromVR(worldscale, ent, gVR->weaponoffset, ent->r.currentOrigin, muzzlePoint);
convertFromVR(worldscale, ent, gVR->calculated_weaponoffset, ent->r.currentOrigin, muzzlePoint);
muzzlePoint[2] += (ent->client->ps.viewheight - 64);
muzzlePoint[2] += (gVR->hmdposition[1] + heightAdjust) * worldscale;
return;
@ -1805,7 +1805,7 @@ void CalcMuzzlePointForActivate( gentity_t *ent, vec3_t forward, vec3_t right, v
float worldscale = trap_Cvar_VariableIntegerValue("cg_worldScale");
float heightAdjust = 0;
trap_Cvar_VariableValue("cg_heightAdjust", &heightAdjust);
convertFromVR(worldscale, ent, gVR->weaponoffset, ent->r.currentOrigin, muzzlePoint);
convertFromVR(worldscale, ent, gVR->calculated_weaponoffset, ent->r.currentOrigin, muzzlePoint);
muzzlePoint[2] += (ent->client->ps.viewheight - 64);
muzzlePoint[2] += (gVR->hmdposition[1] + heightAdjust) * worldscale;
return;
@ -1934,8 +1934,13 @@ void FireWeapon( gentity_t *ent ) {
{
//Stabilised weapon is even more accurate
aimSpreadScale /= 3.0f;
}
if (gVR->pistol)
{
//Stabilised pistol is even more accurate
aimSpreadScale /= 2.0f;
}
}
// fire the specific weapon
switch ( ent->s.weapon ) {