mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2025-02-17 01:21:47 +00:00
Lots of good stuff..
- Multiplayer 6DoF can be disabled setting vr_mp6DoF to 0 (will use a 3DoF scheme instead) - Cross hair now correctly aligned with weapon aiming when playing on a swerver - "Use Item" is not a right thumbstick click - B button will perform crouch in single player or skirmish - B button will realign the weapon with the controller when playing on a server
This commit is contained in:
parent
49b8ba1f43
commit
f5bced0623
10 changed files with 109 additions and 45 deletions
|
@ -3,7 +3,7 @@
|
|||
package="com.drbeef.ioq3quest"
|
||||
android:installLocation="preferExternal"
|
||||
android:versionCode="13"
|
||||
android:versionName="0.8.1">
|
||||
android:versionName="0.9.0">
|
||||
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
|
||||
<uses-feature android:glEsVersion="0x00030001" />
|
||||
|
||||
|
|
|
@ -1992,7 +1992,7 @@ static void CG_DrawCrosshair3D(void)
|
|||
vec3_t viewaxis[3];
|
||||
vec3_t weaponangles;
|
||||
vec3_t origin;
|
||||
CG_CalculateVRWeaponPosition(origin, weaponangles);
|
||||
CG_CalculateVRWeaponPosition(origin, weaponangles, qtrue);
|
||||
AnglesToAxis(weaponangles, viewaxis);
|
||||
maxdist = cgs.glconfig.vidWidth * stereoSep * zProj / (2 * xmax);
|
||||
VectorMA(origin, maxdist, viewaxis[0], endpos);
|
||||
|
@ -2679,21 +2679,26 @@ void CG_DrawActive( stereoFrame_t stereoView ) {
|
|||
|
||||
|
||||
float ipd = trap_Cvar_VariableValue("r_stereoSeparation") / 1000.0f;
|
||||
float separation = stereoView == STEREO_LEFT ?
|
||||
worldscale * (-ipd / 2) : //left
|
||||
worldscale * (ipd / 2); // right
|
||||
float separation = worldscale * (ipd / 2) * (stereoView == STEREO_LEFT ? -1.0f : 1.0f);
|
||||
|
||||
cg.refdef.vieworg[2] -= PLAYER_HEIGHT;
|
||||
cg.refdef.vieworg[2] += vr->hmdposition[1] * worldscale;
|
||||
|
||||
//If connected to external server, allow some amount of faked positional tracking
|
||||
float sv_running = trap_Cvar_VariableValue("sv_running");
|
||||
if ( sv_running == 0.0f && ( cg.snap->ps.stats[STAT_HEALTH] > 0 )) {
|
||||
vec3_t pos;
|
||||
VectorClear(pos);
|
||||
rotateAboutOrigin(vr->hmdposition[2], vr->hmdposition[0], cg.refdefViewAngles[YAW] - vr->weaponangles[YAW], pos);
|
||||
VectorScale(pos, worldscale, pos);
|
||||
VectorSubtract(cg.refdef.vieworg, pos, cg.refdef.vieworg);
|
||||
if (cgs.localServer) {
|
||||
cg.refdef.vieworg[2] -= PLAYER_HEIGHT;
|
||||
cg.refdef.vieworg[2] += vr->hmdposition[1] * worldscale;
|
||||
}
|
||||
else if (trap_Cvar_VariableValue("vr_mp6DoF") == 1.0f)
|
||||
{
|
||||
//If connected to external server, allow some amount of faked positional tracking
|
||||
cg.refdef.vieworg[2] -= PLAYER_HEIGHT;
|
||||
cg.refdef.vieworg[2] += vr->hmdposition[1] * worldscale;
|
||||
if (cg.snap->ps.stats[STAT_HEALTH] > 0)
|
||||
{
|
||||
vec3_t pos;
|
||||
VectorClear(pos);
|
||||
rotateAboutOrigin(vr->hmdposition[2], vr->hmdposition[0],
|
||||
cg.refdefViewAngles[YAW] - vr->weaponangles[YAW], pos);
|
||||
VectorScale(pos, worldscale, pos);
|
||||
VectorSubtract(cg.refdef.vieworg, pos, cg.refdef.vieworg);
|
||||
}
|
||||
}
|
||||
|
||||
VectorMA(cg.refdef.vieworg, -separation, cg.refdef.viewaxis[1], cg.refdef.vieworg);
|
||||
|
|
|
@ -988,7 +988,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
if(es->clientNum == cg.snap->ps.clientNum && !cg.renderingThirdPerson)
|
||||
{
|
||||
vec3_t angles;
|
||||
CG_CalculateVRWeaponPosition(es->origin2, angles);
|
||||
CG_CalculateVRWeaponPosition(es->origin2, angles, qfalse);
|
||||
/*
|
||||
if(cg_drawGun.integer == 2)
|
||||
VectorMA(es->origin2, 8, cg.refdef.viewaxis[1], es->origin2);
|
||||
|
|
|
@ -1369,7 +1369,7 @@ void CG_PrevWeapon_f( void );
|
|||
void CG_Weapon_f( void );
|
||||
|
||||
void rotateAboutOrigin(float x, float y, float rotation, vec2_t out);
|
||||
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles );
|
||||
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles, qboolean crosshair );
|
||||
void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out);
|
||||
|
||||
void CG_RegisterWeapon( int weaponNum );
|
||||
|
|
|
@ -704,8 +704,7 @@ static int CG_CalcViewValues( void ) {
|
|||
}
|
||||
|
||||
// position eye relative to origin
|
||||
float sv_running = trap_Cvar_VariableValue("sv_running");
|
||||
if (sv_running == 0.0f )
|
||||
if (!cgs.localServer)
|
||||
{
|
||||
//We are connected to a multiplayer server, so make the appropriate adjustment to the view
|
||||
//angles as we send orientation to the server that includes the weapon angles
|
||||
|
|
|
@ -230,8 +230,7 @@ void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
|
|||
VectorSet(vrSpace, in[2], in[0], in[1] );
|
||||
|
||||
vec2_t r;
|
||||
float sv_running = trap_Cvar_VariableValue("sv_running");
|
||||
if (sv_running == 0.0f )
|
||||
if (!cgs.localServer)
|
||||
{
|
||||
//We are connected to a multiplayer server, so make the appropriate adjustment to the view
|
||||
//angles as we send orientation to the server that includes the weapon angles
|
||||
|
@ -254,29 +253,50 @@ void CG_ConvertFromVR(vec3_t in, vec3_t offset, vec3_t out)
|
|||
}
|
||||
}
|
||||
|
||||
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles )
|
||||
void CG_CalculateVRWeaponPosition( vec3_t origin, vec3_t angles, qboolean crosshair )
|
||||
{
|
||||
qboolean localServer = trap_Cvar_VariableValue("sv_running") != 0;
|
||||
float worldscale = trap_Cvar_VariableValue("vr_worldscale");
|
||||
|
||||
if (!localServer)
|
||||
if (!cgs.localServer)
|
||||
{
|
||||
vec3_t offset;
|
||||
VectorCopy(vr->weaponposition, offset);
|
||||
offset[1] = vr->weaponoffset[1]; // up/down is index 1 in this case
|
||||
CG_ConvertFromVR(offset, cg.refdef.vieworg, origin);
|
||||
if (trap_Cvar_VariableValue("vr_mp6DoF") == 1.0f &&
|
||||
!crosshair)
|
||||
{
|
||||
//Use absolute position for the faked 6DoF for multiplayer
|
||||
vec3_t offset;
|
||||
VectorCopy(vr->weaponposition, offset);
|
||||
offset[1] = vr->weaponoffset[1]; // up/down is index 1 in this case
|
||||
CG_ConvertFromVR(offset, cg.refdef.vieworg, origin);
|
||||
origin[2] -= PLAYER_HEIGHT;
|
||||
origin[2] += vr->hmdposition[1] * worldscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3_t weaponoffset;
|
||||
VectorSet(weaponoffset, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
//Fixed point
|
||||
if (!crosshair) {
|
||||
vec2_t temp;
|
||||
rotateAboutOrigin(0.25f, -0.25f, -vr->hmdorientation[YAW], temp);
|
||||
VectorSet(weaponoffset, temp[0], -0.3f, temp[1]);
|
||||
}
|
||||
|
||||
CG_ConvertFromVR(weaponoffset, cg.refdef.vieworg, origin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Local server - true 6DoF offset from HMD
|
||||
CG_ConvertFromVR(vr->weaponoffset, cg.refdef.vieworg, origin);
|
||||
origin[2] -= PLAYER_HEIGHT;
|
||||
origin[2] += vr->hmdposition[1] * worldscale;
|
||||
}
|
||||
|
||||
float worldscale = trap_Cvar_VariableValue("vr_worldscale");
|
||||
origin[2] -= PLAYER_HEIGHT;
|
||||
origin[2] += vr->hmdposition[1] * worldscale;
|
||||
|
||||
VectorCopy(vr->weaponangles, angles);
|
||||
|
||||
if ( !localServer )
|
||||
if ( !cgs.localServer )
|
||||
{
|
||||
//take player state angles provided by server
|
||||
angles[YAW] = cg.predictedPlayerState.viewangles[YAW]; //cg.snap->ps.viewangles[YAW];
|
||||
|
@ -1290,7 +1310,7 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
|
|||
// CPMA "true" lightning
|
||||
if ((cent->currentState.number == cg.predictedPlayerState.clientNum) && (cg_trueLightning.value != 0)) {
|
||||
vec3_t angle;
|
||||
CG_CalculateVRWeaponPosition(muzzlePoint, angle);
|
||||
CG_CalculateVRWeaponPosition(muzzlePoint, angle, qfalse);
|
||||
AngleVectors(angle, forward, NULL, NULL );
|
||||
} else {
|
||||
// !CPMA
|
||||
|
@ -1648,7 +1668,7 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
refEntity_t hand;
|
||||
centity_t *cent;
|
||||
clientInfo_t *ci;
|
||||
float fovOffset;
|
||||
//float fovOffset;
|
||||
vec3_t angles;
|
||||
weaponInfo_t *weapon;
|
||||
|
||||
|
@ -1700,7 +1720,7 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
memset (&hand, 0, sizeof(hand));
|
||||
|
||||
// set up gun position
|
||||
CG_CalculateVRWeaponPosition( hand.origin, angles );
|
||||
CG_CalculateVRWeaponPosition( hand.origin, angles, qfalse );
|
||||
|
||||
//Scale / Move gun etc
|
||||
float scale = 1.0f;
|
||||
|
@ -1790,7 +1810,7 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
vec3_t endForward, endRight, endUp;
|
||||
vec3_t _angles;
|
||||
clientInfo_t ci;
|
||||
CG_CalculateVRWeaponPosition( _origin, _angles );
|
||||
CG_CalculateVRWeaponPosition( _origin, _angles, qfalse );
|
||||
|
||||
vec3_t forward, right, up;
|
||||
AngleVectors(_angles, forward, right, up);
|
||||
|
|
|
@ -596,13 +596,22 @@ void CL_FinishMove( usercmd_t *cmd ) {
|
|||
//and adjust the move values accordingly, to "fake" a 3DoF weapon but keeping the movement correct
|
||||
if ( !com_sv_running || !com_sv_running->integer )
|
||||
{
|
||||
vr.localServer = qfalse;
|
||||
vr.clientNum = -1;
|
||||
vr.local_server = qfalse;
|
||||
|
||||
vec3_t angles;
|
||||
VectorCopy(vr.weaponangles, angles);
|
||||
angles[ROLL] = 0; // suppress roll
|
||||
|
||||
if (vr.realign_weapon)
|
||||
{
|
||||
vr.realign_weapon_pitch -= (cl.snap.ps.viewangles[PITCH]-vr.weaponangles[PITCH]) ;
|
||||
vr.realign_weapon = qfalse;
|
||||
}
|
||||
|
||||
angles[PITCH] += vr.realign_weapon_pitch;
|
||||
angles[YAW] += (cl.viewangles[YAW] - vr.hmdorientation[YAW]);
|
||||
angles[ROLL] = 0; // suppress roll
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
cmd->angles[i] = ANGLE2SHORT(angles[i]);
|
||||
}
|
||||
|
@ -613,11 +622,10 @@ void CL_FinishMove( usercmd_t *cmd ) {
|
|||
cmd->forwardmove = out[1];
|
||||
}
|
||||
else {
|
||||
vr.localServer = qtrue;
|
||||
|
||||
//Record client number - local server uses this to know we can use absolute angles
|
||||
//rather than deltas
|
||||
vr.clientNum = cl.snap.ps.clientNum;
|
||||
vr.local_server = qtrue;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
|
||||
|
|
|
@ -1812,7 +1812,7 @@ void PM_UpdateViewAngles( playerState_t *ps, const usercmd_t *cmd ) {
|
|||
|
||||
// circularly clamp the angles with deltas
|
||||
for (i=0 ; i<3 ; i++) {
|
||||
if (vr != NULL && vr->clientNum == ps->clientNum && vr->localServer)
|
||||
if (vr != NULL && vr->clientNum == ps->clientNum && vr->local_server)
|
||||
{
|
||||
//Client is the VR player on the "local" server
|
||||
temp = cmd->angles[i] + (i == YAW ? ps->delta_angles[i] : 0);
|
||||
|
|
|
@ -9,8 +9,11 @@ typedef struct {
|
|||
qboolean weapon_stabilised;
|
||||
qboolean right_handed;
|
||||
qboolean virtual_screen;
|
||||
qboolean local_server; // used in bg_pmove.c
|
||||
|
||||
qboolean realign_weapon; // used to realign the weapon in a multiplayer game
|
||||
int realign_weapon_pitch; // used to realign the weapon pitch in a multiplayer game
|
||||
|
||||
qboolean localServer;
|
||||
int clientNum;
|
||||
|
||||
vec3_t hmdposition;
|
||||
|
|
|
@ -67,6 +67,7 @@ float degrees(float rad) {
|
|||
|
||||
cvar_t *vr_extralatencymode = NULL;
|
||||
cvar_t *vr_directionMode = NULL;
|
||||
cvar_t *vr_mp6DoF = NULL;
|
||||
|
||||
void rotateAboutOrigin(float x, float y, float rotation, vec2_t out)
|
||||
{
|
||||
|
@ -196,6 +197,9 @@ void IN_VRInit( void )
|
|||
vr_snapturn = Cvar_Get ("vr_snapturn", "45", CVAR_ARCHIVE);
|
||||
vr_extralatencymode = Cvar_Get ("vr_extralatencymode", "1", CVAR_ARCHIVE);
|
||||
vr_directionMode = Cvar_Get ("vr_directionMode", "0", CVAR_ARCHIVE); // 0 = HMD, 1 = Off-hand
|
||||
vr_mp6DoF = Cvar_Get ("vr_mp6DoF", "1", CVAR_ARCHIVE); // if 0 then multiplayer will use only 3DoF for headset
|
||||
|
||||
memset(&vr, 0, sizeof(vr));
|
||||
}
|
||||
|
||||
static void IN_VRController( qboolean isRightController, ovrTracking remoteTracking )
|
||||
|
@ -397,11 +401,36 @@ static void IN_VRButtonsChanged( qboolean isRightController, uint32_t buttons )
|
|||
}
|
||||
|
||||
if ((buttons & ovrButton_B) && !(controller->buttons & ovrButton_B)) {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ENTER, qtrue, 0, NULL);
|
||||
if ( !com_sv_running || !com_sv_running->integer )
|
||||
{
|
||||
vr.realign_weapon = qtrue;
|
||||
} else {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, 'c', qtrue, 0, NULL);
|
||||
}
|
||||
} else if (!(buttons & ovrButton_B) && (controller->buttons & ovrButton_B)) {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ENTER, qfalse, 0, NULL);
|
||||
if ( !com_sv_running || !com_sv_running->integer )
|
||||
{
|
||||
} else {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, 'c', qfalse, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (isRightController == (vr_righthanded->integer != 0)) {
|
||||
//thumbstick is "use item"
|
||||
if ((buttons & ovrButton_RThumb) && !(controller->buttons & ovrButton_RThumb)) {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ENTER, qtrue, 0, NULL);
|
||||
} else if (!(buttons & ovrButton_RThumb) && (controller->buttons & ovrButton_RThumb)) {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ENTER, qfalse, 0, NULL);
|
||||
}
|
||||
} else {
|
||||
//thumbstick is "use item"
|
||||
if ((buttons & ovrButton_LThumb) && !(controller->buttons & ovrButton_LThumb)) {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ENTER, qtrue, 0, NULL);
|
||||
} else if (!(buttons & ovrButton_LThumb) && (controller->buttons & ovrButton_LThumb)) {
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_ENTER, qfalse, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if ((buttons & ovrButton_X) && !(controller->buttons & ovrButton_X)) {
|
||||
//sendButtonActionSimple("fraglimit 1");
|
||||
Com_QueueEvent(in_vrEventTime, SE_KEY, K_PAD0_X, qtrue, 0, NULL);
|
||||
|
|
Loading…
Reference in a new issue