Some small fixes

- Use FOV from the SDK to calculate the culling frustrum (so r_nocull can be turned off now, hopefully increasing framerate)
- I think I fixed thumbstick movement in second spectator follow mode
- Remove Gauntlet from weapon wheel because it is shit
- Some code refactoring
- Hopefully made the Chaingun accessible on the weapon wheel now
This commit is contained in:
Simon 2022-03-18 22:21:22 +00:00
parent 9aef5b5d68
commit 7fce284d93
11 changed files with 137 additions and 173 deletions

View file

@ -1875,6 +1875,7 @@ CROSSHAIR
CG_DrawCrosshair CG_DrawCrosshair
================= =================
*/ */
/*
static void CG_DrawCrosshair(void) static void CG_DrawCrosshair(void)
{ {
float w, h; float w, h;
@ -1930,7 +1931,7 @@ static void CG_DrawCrosshair(void)
w, h, 0, 0, 1, 1, hShader ); w, h, 0, 0, 1, 1, hShader );
trap_R_SetColor( NULL ); trap_R_SetColor( NULL );
} }*/
/* /*
================= =================
@ -2550,7 +2551,6 @@ CG_DrawWeapReticle
*/ */
static void CG_DrawWeapReticle( void ) static void CG_DrawWeapReticle( void )
{ {
int weap;
vec4_t light_color = {0.7, 0.7, 0.7, 1}; vec4_t light_color = {0.7, 0.7, 0.7, 1};
vec4_t black = {0.0, 0.0, 0.0, 1}; vec4_t black = {0.0, 0.0, 0.0, 1};
@ -2602,7 +2602,7 @@ static void CG_DrawVignette( void )
return; return;
} }
const float yawDelta = abs(vr->clientview_yaw_delta); const float yawDelta = fabsf(vr->clientview_yaw_delta);
if (VectorLength(cg.predictedPlayerState.velocity) > 30.0 || (yawDelta > 0 && yawDelta < 20) || (yawDelta > 340)) if (VectorLength(cg.predictedPlayerState.velocity) > 30.0 || (yawDelta > 0 && yawDelta < 20) || (yawDelta > 340))
{ {
if (currentComfortVignetteValue < comfortVignetteValue) if (currentComfortVignetteValue < comfortVignetteValue)
@ -2783,15 +2783,13 @@ void CG_DrawActive( void ) {
float heightOffset = 0.0f; float heightOffset = 0.0f;
float worldscale = cg.worldscale; float worldscale = cg.worldscale;
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON)) if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_1))
{ {
worldscale *= SPECTATOR_WORLDSCALE_MULTIPLIER; worldscale *= SPECTATOR_WORLDSCALE_MULTIPLIER;
//Just move camera down about 20cm //Just move camera down about 20cm
heightOffset = -0.2f; heightOffset = -0.2f;
} }
else if ((( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) && else if (CG_IsDeathCam() || CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_2))
( cg.snap->ps.pm_type != PM_INTERMISSION )) ||
(cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON_2))
{ {
worldscale *= SPECTATOR2_WORLDSCALE_MULTIPLIER; worldscale *= SPECTATOR2_WORLDSCALE_MULTIPLIER;
//Just move camera down about 50cm //Just move camera down about 50cm
@ -2818,7 +2816,7 @@ void CG_DrawActive( void ) {
if (cg.snap->ps.stats[STAT_HEALTH] > 0 && if (cg.snap->ps.stats[STAT_HEALTH] > 0 &&
//Don't use fake positional if following another player - this is handled in the //Don't use fake positional if following another player - this is handled in the
//VR third person code //VR third person code
!( cg.demoPlayback || CG_IsThirdPersonFollowMode())) !( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY)))
{ {
vec3_t pos, hmdposition, vieworg; vec3_t pos, hmdposition, vieworg;
VectorClear(pos); VectorClear(pos);

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../game/bg_public.h" #include "../game/bg_public.h"
#include "cg_public.h" #include "cg_public.h"
#include "../vr/vr_types.h"
// The entire cgame module is unloaded and reloaded on each level change, // The entire cgame module is unloaded and reloaded on each level change,
// so there is NO persistant data between levels on the client side. // so there is NO persistant data between levels on the client side.
@ -1267,7 +1268,8 @@ void CG_TestModelPrevSkin_f (void);
void CG_ZoomDown_f( void ); void CG_ZoomDown_f( void );
void CG_ZoomUp_f( void ); void CG_ZoomUp_f( void );
void CG_AddBufferedSound( sfxHandle_t sfx); void CG_AddBufferedSound( sfxHandle_t sfx);
qboolean CG_IsThirdPersonFollowMode( void ); qboolean CG_IsThirdPersonFollowMode( vrFollowMode_t followMode );
qboolean CG_IsDeathCam( void );
void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ); void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback );

View file

@ -1998,7 +1998,7 @@ static void CG_PlayerSprites( centity_t *cent ) {
//Put a sprite over the followed player's head //Put a sprite over the followed player's head
if ( cent->currentState.number == cg.snap->ps.clientNum && if ( cent->currentState.number == cg.snap->ps.clientNum &&
cg.renderingThirdPerson && cg.renderingThirdPerson &&
CG_IsThirdPersonFollowMode()) { CG_IsThirdPersonFollowMode(VRFM_QUERY)) {
CG_PlayerFloatSprite( cent, cgs.media.friendShader ); CG_PlayerFloatSprite( cent, cgs.media.friendShader );
return; return;
} }

View file

@ -228,8 +228,7 @@ static void CG_OffsetVRThirdPersonView( void ) {
float scale = 1.0f; float scale = 1.0f;
//Follow mode 1 //Follow mode 1
if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_1))
vr->follow_mode == VRFM_THIRDPERSON))
{ {
scale *= SPECTATOR_WORLDSCALE_MULTIPLIER; scale *= SPECTATOR_WORLDSCALE_MULTIPLIER;
@ -251,17 +250,15 @@ static void CG_OffsetVRThirdPersonView( void ) {
} }
} }
//Death or follow mode 2 //Death or follow mode 2
else if ((( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) && else if (CG_IsDeathCam() ||CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_2))
( cg.predictedPlayerState.pm_type != PM_INTERMISSION )) ||
(cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON_2))
{ {
scale *= SPECTATOR2_WORLDSCALE_MULTIPLIER; scale *= SPECTATOR2_WORLDSCALE_MULTIPLIER;
//Move camera if the user is pushing thumbstick //Move camera if the user is pushing thumbstick
vec3_t angles, forward, right, up; vec3_t angles, forward, right, up;
VectorCopy(vr->offhandangles, angles); VectorCopy(vr->offhandangles, angles);
float deltaYaw = SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]); float deltaYaw = CG_IsDeathCam() ? SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]) : 0.0f;
angles[YAW] += (vr->clientviewangles[YAW] - vr->hmdorientation[YAW]); angles[YAW] += deltaYaw + (vr->clientviewangles[YAW] - vr->hmdorientation[YAW]);
AngleVectors(angles, forward, right, up); AngleVectors(angles, forward, right, up);
VectorMA(cg.vr_vieworigin, vr->thumbstick_location[THUMB_LEFT][1] * 5.0f, forward, cg.vr_vieworigin); VectorMA(cg.vr_vieworigin, vr->thumbstick_location[THUMB_LEFT][1] * 5.0f, forward, cg.vr_vieworigin);
VectorMA(cg.vr_vieworigin, vr->thumbstick_location[THUMB_LEFT][0] * 5.0f, right, cg.vr_vieworigin); VectorMA(cg.vr_vieworigin, vr->thumbstick_location[THUMB_LEFT][0] * 5.0f, right, cg.vr_vieworigin);
@ -525,6 +522,8 @@ static int CG_CalcFov( void ) {
float f; float f;
int inwater; int inwater;
/*
if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
// if in intermission, use a fixed value // if in intermission, use a fixed value
fov_x = 90; fov_x = 90;
@ -534,7 +533,7 @@ static int CG_CalcFov( void ) {
// dmflag to prevent wide fov for all clients // dmflag to prevent wide fov for all clients
fov_x = 90; fov_x = 90;
} else { } else {
fov_x = cg_fov.value; fov_x = vr->fov_x;
if ( fov_x < 1 ) { if ( fov_x < 1 ) {
fov_x = 1; fov_x = 1;
} else if ( fov_x > 160 ) { } else if ( fov_x > 160 ) {
@ -568,6 +567,7 @@ static int CG_CalcFov( void ) {
x = cg.refdef.width / tan( fov_x / 360 * M_PI ); x = cg.refdef.width / tan( fov_x / 360 * M_PI );
fov_y = atan2( cg.refdef.height, x ); fov_y = atan2( cg.refdef.height, x );
fov_y = fov_y * 360 / M_PI; fov_y = fov_y * 360 / M_PI;
*/
// warp if underwater // warp if underwater
contents = CG_PointContents( cg.refdef.vieworg, -1 ); contents = CG_PointContents( cg.refdef.vieworg, -1 );
@ -583,9 +583,9 @@ static int CG_CalcFov( void ) {
} }
// set it // Seems we can get away with actually using 10 degrees less on the FOV
cg.refdef.fov_x = fov_x; cg.refdef.fov_x = vr->fov_x - 10;
cg.refdef.fov_y = fov_y; cg.refdef.fov_y = vr->fov_y - 10;
if ( !cg.zoomed ) { if ( !cg.zoomed ) {
cg.zoomSensitivity = 1; cg.zoomSensitivity = 1;
@ -671,13 +671,6 @@ static int CG_CalcViewValues( ) {
ps = &cg.predictedPlayerState; ps = &cg.predictedPlayerState;
//HACK!! - should change this to a renderer function call
//Indicate to renderer whether we are in deathcam mode, We don't want sky in death cam mode
trap_Cvar_Set( "vr_thirdPersonSpectator", (((ps->stats[STAT_HEALTH] <= 0) &&
( ps->pm_type != PM_INTERMISSION )) ||
cg.demoPlayback ||
CG_IsThirdPersonFollowMode() ? "1" : "0" ));
// intermission view // intermission view
static float hmdYaw = 0; static float hmdYaw = 0;
if ( ps->pm_type == PM_INTERMISSION ) { if ( ps->pm_type == PM_INTERMISSION ) {
@ -731,9 +724,7 @@ static int CG_CalcViewValues( ) {
} }
} }
if (( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) && if (CG_IsDeathCam() || cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY))
( cg.predictedPlayerState.pm_type != PM_INTERMISSION ) ||
( cg.demoPlayback || CG_IsThirdPersonFollowMode()))
{ {
//If dead, or spectating, view the map from above //If dead, or spectating, view the map from above
CG_OffsetVRThirdPersonView(); CG_OffsetVRThirdPersonView();
@ -790,7 +781,7 @@ static int CG_CalcViewValues( ) {
origin[2] -= cg.duckChange * (DUCK_TIME - timeDelta) / DUCK_TIME; origin[2] -= cg.duckChange * (DUCK_TIME - timeDelta) / DUCK_TIME;
} }
vec3_t forward2, end2, dir2; vec3_t forward2, end2;
AngleVectors(vr->calculated_weaponangles, forward2, NULL, NULL); AngleVectors(vr->calculated_weaponangles, forward2, NULL, NULL);
VectorMA(origin, 4096, forward2, end2); VectorMA(origin, 4096, forward2, end2);
@ -826,7 +817,7 @@ static int CG_CalcViewValues( ) {
angles[ROLL] = vr->hmdorientation[ROLL]; angles[ROLL] = vr->hmdorientation[ROLL];
AnglesToAxis( angles, cg.refdef.viewaxis ); AnglesToAxis( angles, cg.refdef.viewaxis );
} }
else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode()) else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY))
{ {
//If we're following someone, //If we're following someone,
vec3_t angles; vec3_t angles;
@ -856,7 +847,7 @@ static int CG_CalcViewValues( ) {
angles[YAW] = (cg.refdefViewAngles[YAW] - vr->hmdorientation[YAW]) + vr->weaponangles[YAW]; angles[YAW] = (cg.refdefViewAngles[YAW] - vr->hmdorientation[YAW]) + vr->weaponangles[YAW];
AnglesToAxis(angles, cg.refdef.viewaxis); AnglesToAxis(angles, cg.refdef.viewaxis);
} }
else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode()) else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY))
{ {
//If we're following someone, //If we're following someone,
vec3_t angles; vec3_t angles;
@ -936,10 +927,21 @@ static void CG_PlayBufferedSounds( void ) {
//========================================================================= //=========================================================================
qboolean CG_IsThirdPersonFollowMode( void ) qboolean CG_IsThirdPersonFollowMode( vrFollowMode_t followMode )
{ {
return cg.snap->ps.pm_flags & PMF_FOLLOW && if (followMode == VRFM_QUERY)
(vr->follow_mode == VRFM_THIRDPERSON || vr->follow_mode == VRFM_THIRDPERSON_2); {
return cg.snap->ps.pm_flags & PMF_FOLLOW &&
(vr->follow_mode == VRFM_THIRDPERSON_1 || vr->follow_mode == VRFM_THIRDPERSON_2);
}
return cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == followMode;
}
qboolean CG_IsDeathCam( void )
{
return (( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) &&
( cg.predictedPlayerState.pm_type != PM_INTERMISSION ));
} }
/* /*
@ -961,6 +963,12 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// update cvars // update cvars
CG_UpdateCvars(); CG_UpdateCvars();
//HACK!! - should change this to a renderer function call
//Indicate to renderer whether we are in deathcam mode, We don't want sky in death cam mode
trap_Cvar_Set( "vr_thirdPersonSpectator", (CG_IsDeathCam() ||
cg.demoPlayback ||
CG_IsThirdPersonFollowMode(VRFM_QUERY) ? "1" : "0" ));
// if we are only updating the screen as a loading // if we are only updating the screen as a loading
// pacifier, don't even try to read snapshots // pacifier, don't even try to read snapshots
if ( cg.infoScreenText[0] != 0 ) { if ( cg.infoScreenText[0] != 0 ) {
@ -999,7 +1007,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// decide on third person view // decide on third person view
cg.renderingThirdPerson = cg.predictedPlayerState.pm_type == PM_SPECTATOR || cg.renderingThirdPerson = cg.predictedPlayerState.pm_type == PM_SPECTATOR ||
cg.demoPlayback || CG_IsThirdPersonFollowMode() || cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY) ||
cg_thirdPerson.integer; cg_thirdPerson.integer;
// build cg.refdef // build cg.refdef

View file

@ -2076,24 +2076,24 @@ void CG_DrawWeaponSelector( void )
CG_CalculateVRWeaponPosition(controllerOrigin, controllerAngles); CG_CalculateVRWeaponPosition(controllerOrigin, controllerAngles);
VectorSubtract(vr->weaponposition, cg.weaponSelectorOrigin, controllerOffset); VectorSubtract(vr->weaponposition, cg.weaponSelectorOrigin, controllerOffset);
vec3_t holsterAngles, holsterOrigin, beamOrigin, holsterForward, holsterRight, holsterUp; vec3_t wheelAngles, wheelOrigin, beamOrigin, wheelForward, wheelRight, wheelUp;
CG_CalculateVRPositionInWorld(cg.weaponSelectorOrigin, cg.weaponSelectorOffset, cg.weaponSelectorAngles, holsterOrigin, holsterAngles); CG_CalculateVRPositionInWorld(cg.weaponSelectorOrigin, cg.weaponSelectorOffset, cg.weaponSelectorAngles, wheelOrigin, wheelAngles);
AngleVectors(holsterAngles, holsterForward, holsterRight, holsterUp); AngleVectors(wheelAngles, wheelForward, wheelRight, wheelUp);
if (selectorMode == WS_CONTROLLER) if (selectorMode == WS_CONTROLLER)
{ {
VectorCopy(controllerOrigin, holsterOrigin); VectorCopy(controllerOrigin, wheelOrigin);
} }
else else
{ {
// Do not shift weapon wheel down in order to fit inside comfort vignette // Do not shift weapon wheel down in order to fit inside comfort vignette
//VectorMA(holsterOrigin, -3.0f, holsterUp, holsterOrigin); //VectorMA(wheelOrigin, -3.0f, wheelUp, wheelOrigin);
} }
VectorCopy(holsterOrigin, beamOrigin); VectorCopy(wheelOrigin, beamOrigin);
VectorMA(holsterOrigin, ((DEPTH*2.0f)*((selectorMode == WS_CONTROLLER) ? frac : 1.0f)), holsterForward, holsterOrigin); VectorMA(wheelOrigin, ((DEPTH*2.0f)*((selectorMode == WS_CONTROLLER) ? frac : 1.0f)), wheelForward, wheelOrigin);
VectorCopy(holsterOrigin, selectorOrigin); VectorCopy(wheelOrigin, selectorOrigin);
const int switchThumbsticks = (int)trap_Cvar_VariableValue("vr_switchThumbsticks"); const int switchThumbsticks = (int)trap_Cvar_VariableValue("vr_switchThumbsticks");
const int thumb = switchThumbsticks !=0 ? THUMB_LEFT : THUMB_RIGHT; const int thumb = switchThumbsticks !=0 ? THUMB_LEFT : THUMB_RIGHT;
@ -2111,8 +2111,8 @@ void CG_DrawWeaponSelector( void )
float y = 0.0f; float y = 0.0f;
if (selectorMode == WS_CONTROLLER) if (selectorMode == WS_CONTROLLER)
{ {
x = (sinf(DEG2RAD(holsterAngles[YAW] - controllerAngles[YAW])) / sinf(DEG2RAD(22.5f))); x = (sinf(DEG2RAD(wheelAngles[YAW] - controllerAngles[YAW])) / sinf(DEG2RAD(22.5f)));
y = ((holsterAngles[PITCH] - controllerAngles[PITCH]) / 22.5f); y = ((wheelAngles[PITCH] - controllerAngles[PITCH]) / 22.5f);
float len = length(x, y); float len = length(x, y);
if (len > 1.0f) if (len > 1.0f)
@ -2127,8 +2127,8 @@ void CG_DrawWeaponSelector( void )
y = thumbstickAxisY; y = thumbstickAxisY;
} }
VectorMA(selectorOrigin, RAD * x, holsterRight, selectorOrigin); VectorMA(selectorOrigin, RAD * x, wheelRight, selectorOrigin);
VectorMA(selectorOrigin, RAD * y, holsterUp, selectorOrigin); VectorMA(selectorOrigin, RAD * y, wheelUp, selectorOrigin);
{ {
refEntity_t blob; refEntity_t blob;
@ -2154,38 +2154,39 @@ void CG_DrawWeaponSelector( void )
} }
#ifdef MISSIONPACK #ifdef MISSIONPACK
float iconAngles[WP_NUM_WEAPONS] = {0.0f, 30.0f, 60.0f, 90.0f, 120.0f, 150.0f, 180.0f, 210.0f, 240.0f, 270.0f, 300.0f, 330.0f, 360.0f, 390.0f}; float wheelIconAngles[WP_NUM_WEAPONS] = {0.0f, 45.0f, 90.0f, 120.0f, 150.0f, 180.0f, 210.0f, 240.0f, 270.0f, 300.0f, 330.0f, 360.0f, 390.0f};
#else #else
float iconAngles[WP_NUM_WEAPONS] = {0.0f, 30.0f, 60.0f, 90.0f, 135.0f, 180.0f, 225.0f, 270.0f, 315.0f, 360.0f, 390.0f}; float wheelIconAngles[WP_NUM_WEAPONS] = {0.0f, 45.0f, 90.0f, 135.0f, 180.0f, 225.0f, 270.0f, 315.0f, 360.0f, 390.0f};
#endif #endif
qboolean selected = qfalse; qboolean selected = qfalse;
int w = 0; int angleIndex = 0;
for (int index = 0; index < WP_NUM_WEAPONS-1; ++index) for (int weaponId = 1; weaponId < WP_NUM_WEAPONS; ++weaponId)
{ {
if ((index+1) == WP_GRAPPLING_HOOK) if (weaponId == WP_GRAPPLING_HOOK ||
weaponId == WP_GAUNTLET)
{ {
continue; continue;
} }
//increment now we know we aren't looking at an invalid weapon id //increment now we know we aren't looking at an invalid weapon id
++w; ++angleIndex;
CG_RegisterWeapon(w); CG_RegisterWeapon(weaponId);
{ {
qboolean selectable = CG_WeaponSelectable(w) && cg.snap->ps.ammo[ w ]; qboolean selectable = CG_WeaponSelectable(weaponId) && cg.snap->ps.ammo[weaponId];
//first calculate holster slot position //first calculate wheel slot position
vec3_t angles, iconOrigin,iconBackground,iconForeground; vec3_t angles, iconOrigin,iconBackground,iconForeground;
VectorClear(angles); VectorClear(angles);
angles[YAW] = holsterAngles[YAW]; angles[YAW] = wheelAngles[YAW];
angles[PITCH] = holsterAngles[PITCH]; angles[PITCH] = wheelAngles[PITCH];
angles[ROLL] = iconAngles[w]; angles[ROLL] = wheelIconAngles[angleIndex];
vec3_t forward, up; vec3_t forward, up;
AngleVectors(angles, forward, NULL, up); AngleVectors(angles, forward, NULL, up);
VectorMA(holsterOrigin, (RAD*frac), up, iconOrigin); VectorMA(wheelOrigin, (RAD*frac), up, iconOrigin);
VectorMA(iconOrigin, 0.2f, forward, iconBackground); VectorMA(iconOrigin, 0.2f, forward, iconBackground);
VectorMA(iconOrigin, -0.2f, forward, iconForeground); VectorMA(iconOrigin, -0.2f, forward, iconForeground);
@ -2198,9 +2199,9 @@ void CG_DrawWeaponSelector( void )
frac == 1.0f && frac == 1.0f &&
selectable) selectable)
{ {
if (cg.weaponSelectorSelection != w) if (cg.weaponSelectorSelection != weaponId)
{ {
cg.weaponSelectorSelection = w; cg.weaponSelectorSelection = weaponId;
trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0); trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0);
} }
@ -2215,16 +2216,16 @@ void CG_DrawWeaponSelector( void )
float angle = AngleNormalize360(RAD2DEG(a)); float angle = AngleNormalize360(RAD2DEG(a));
float angle360 = angle + 360; // HACK - Account for the icon at the top float angle360 = angle + 360; // HACK - Account for the icon at the top
float low = ((iconAngles[w-1]+iconAngles[w])/2.0f); float low = ((wheelIconAngles[angleIndex-1]+wheelIconAngles[angleIndex])/2.0f);
float high = ((iconAngles[w]+iconAngles[w+1])/2.0f); float high = ((wheelIconAngles[angleIndex]+wheelIconAngles[angleIndex+1])/2.0f);
if (((angle > low && angle <= high) || (angle360 > low && angle360 <= high)) && if (((angle > low && angle <= high) || (angle360 > low && angle360 <= high)) &&
(length(vr->thumbstick_location[thumb][0], vr->thumbstick_location[thumb][1]) > 0.5f) && (length(vr->thumbstick_location[thumb][0], vr->thumbstick_location[thumb][1]) > 0.5f) &&
selectable) selectable)
{ {
if (cg.weaponSelectorSelection != w) if (cg.weaponSelectorSelection != weaponId)
{ {
cg.weaponSelectorSelection = w; cg.weaponSelectorSelection = weaponId;
trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0); trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0);
} }
@ -2232,7 +2233,7 @@ void CG_DrawWeaponSelector( void )
} }
} }
if (cg.weaponSelectorSelection == w) if (cg.weaponSelectorSelection == weaponId)
{ {
refEntity_t sprite; refEntity_t sprite;
memset( &sprite, 0, sizeof( sprite ) ); memset( &sprite, 0, sizeof( sprite ) );
@ -2250,52 +2251,36 @@ void CG_DrawWeaponSelector( void )
if (!cg_weaponSelectorSimple2DIcons.integer) if (!cg_weaponSelectorSimple2DIcons.integer)
{ {
/* if (selectable)
{
refEntity_t blob;
memset( &blob, 0, sizeof( blob ) );
VectorCopy( iconOrigin, blob.origin );
AnglesToAxis(vec3_origin, blob.axis);
float sphereScale = (SCALE*frac) + 0.05f + (cg.weaponSelectorSelection == w ? 0.035f : 0);
VectorScale( blob.axis[0], sphereScale, blob.axis[0] );
VectorScale( blob.axis[1], sphereScale, blob.axis[1] );
VectorScale( blob.axis[2], sphereScale, blob.axis[2] );
blob.nonNormalizedAxes = qtrue;
blob.hModel = cgs.media.smallSphereModel;
blob.customShader = cgs.media.invisShader;
trap_R_AddRefEntityToScene( &blob );
}*/
refEntity_t ent; refEntity_t ent;
memset(&ent, 0, sizeof(ent)); memset(&ent, 0, sizeof(ent));
VectorCopy(iconOrigin, ent.origin); VectorCopy(iconOrigin, ent.origin);
//Shift the weapon model a bit to be in the sphere //Shift the weapon model a bit to be in the sphere
if (w == WP_GAUNTLET) if (weaponId == WP_GAUNTLET)
{ {
SCALE = 0.065f; SCALE = 0.065f;
VectorMA(ent.origin, 0.3f, holsterUp, ent.origin); VectorMA(ent.origin, 0.3f, wheelUp, ent.origin);
VectorMA(ent.origin, 0.15f, holsterRight, ent.origin); VectorMA(ent.origin, 0.15f, wheelRight, ent.origin);
VectorMA(ent.origin, -0.15f, holsterForward, ent.origin); VectorMA(ent.origin, -0.15f, wheelForward, ent.origin);
} }
else else
{ {
VectorMA(ent.origin, 0.3f, holsterForward, ent.origin); VectorMA(ent.origin, 0.3f, wheelForward, ent.origin);
VectorMA(ent.origin, -0.2f, holsterRight, ent.origin); VectorMA(ent.origin, -0.2f, wheelRight, ent.origin);
VectorMA(ent.origin, 0.5f, holsterUp, ent.origin); VectorMA(ent.origin, 0.5f, wheelUp, ent.origin);
} }
vec3_t iconAngles; vec3_t iconAngles;
VectorCopy(holsterAngles, iconAngles); VectorCopy(wheelAngles, iconAngles);
iconAngles[PITCH] = 10; iconAngles[PITCH] = 10;
iconAngles[YAW] -= 145.0f; iconAngles[YAW] -= 145.0f;
if (w == WP_GAUNTLET) if (weaponId == WP_GAUNTLET)
{ {
iconAngles[ROLL] -= 90.0f; iconAngles[ROLL] -= 90.0f;
} }
float weaponScale = ((SCALE+0.02f)*frac) + float weaponScale = ((SCALE+0.02f)*frac) +
(cg.weaponSelectorSelection == w ? 0.04f : 0); (cg.weaponSelectorSelection == weaponId ? 0.04f : 0);
AnglesToAxis(iconAngles, ent.axis); AnglesToAxis(iconAngles, ent.axis);
VectorScale(ent.axis[0], weaponScale, ent.axis[0]); VectorScale(ent.axis[0], weaponScale, ent.axis[0]);
@ -2303,7 +2288,7 @@ void CG_DrawWeaponSelector( void )
VectorScale(ent.axis[2], weaponScale, ent.axis[2]); VectorScale(ent.axis[2], weaponScale, ent.axis[2]);
ent.nonNormalizedAxes = qtrue; ent.nonNormalizedAxes = qtrue;
if( w == WP_RAILGUN ) { if( weaponId == WP_RAILGUN ) {
clientInfo_t *ci = &cgs.clientinfo[cg.predictedPlayerState.clientNum]; clientInfo_t *ci = &cgs.clientinfo[cg.predictedPlayerState.clientNum];
if( cg_entities[cg.predictedPlayerState.clientNum].pe.railFireTime + 1500 > cg.time ) { if( cg_entities[cg.predictedPlayerState.clientNum].pe.railFireTime + 1500 > cg.time ) {
int scale = 255 * ( cg.time - cg_entities[cg.predictedPlayerState.clientNum].pe.railFireTime ) / 1500; int scale = 255 * ( cg.time - cg_entities[cg.predictedPlayerState.clientNum].pe.railFireTime ) / 1500;
@ -2317,23 +2302,23 @@ void CG_DrawWeaponSelector( void )
} }
} }
ent.hModel = cg_weapons[w].weaponModel; ent.hModel = cg_weapons[weaponId].weaponModel;
if (!selectable) if (!selectable)
{ {
ent.customShader = cgs.media.invisShader; ent.customShader = cgs.media.invisShader;
} }
trap_R_AddRefEntityToScene(&ent); trap_R_AddRefEntityToScene(&ent);
if ( cg_weapons[w].barrelModel ) if ( cg_weapons[weaponId].barrelModel )
{ {
refEntity_t barrel; refEntity_t barrel;
memset(&barrel, 0, sizeof(barrel)); memset(&barrel, 0, sizeof(barrel));
barrel.hModel = cg_weapons[w].barrelModel; barrel.hModel = cg_weapons[weaponId].barrelModel;
vec3_t barrelAngles; vec3_t barrelAngles;
VectorClear(barrelAngles); VectorClear(barrelAngles);
barrelAngles[ROLL] = AngleNormalize360((cg.time - cg.weaponSelectorTime) * 0.9f); barrelAngles[ROLL] = AngleNormalize360((cg.time - cg.weaponSelectorTime) * 0.9f);
AnglesToAxis(barrelAngles, barrel.axis); AnglesToAxis(barrelAngles, barrel.axis);
CG_PositionRotatedEntityOnTag(&barrel, &ent, cg_weapons[w].weaponModel, CG_PositionRotatedEntityOnTag(&barrel, &ent, cg_weapons[weaponId].weaponModel,
"tag_barrel"); "tag_barrel");
if (!selectable) if (!selectable)
{ {
@ -2350,8 +2335,8 @@ void CG_DrawWeaponSelector( void )
VectorCopy(iconOrigin, sprite.origin); VectorCopy(iconOrigin, sprite.origin);
sprite.reType = RT_SPRITE; sprite.reType = RT_SPRITE;
sprite.customShader = cg_weapons[w].weaponIcon; sprite.customShader = cg_weapons[weaponId].weaponIcon;
sprite.radius = 0.6f + (cg.weaponSelectorSelection == w ? 0.1f : 0); sprite.radius = 0.6f + (cg.weaponSelectorSelection == weaponId ? 0.1f : 0);
sprite.shaderRGBA[0] = 255; sprite.shaderRGBA[0] = 255;
sprite.shaderRGBA[1] = 255; sprite.shaderRGBA[1] = 255;
sprite.shaderRGBA[2] = 255; sprite.shaderRGBA[2] = 255;
@ -2363,7 +2348,7 @@ void CG_DrawWeaponSelector( void )
VectorCopy( iconBackground, sprite.origin ); VectorCopy( iconBackground, sprite.origin );
sprite.reType = RT_SPRITE; sprite.reType = RT_SPRITE;
sprite.customShader = cgs.media.selectShader; sprite.customShader = cgs.media.selectShader;
sprite.radius = 0.7f + (cg.weaponSelectorSelection == w ? 0.1f : 0); sprite.radius = 0.7f + (cg.weaponSelectorSelection == weaponId ? 0.1f : 0);
sprite.shaderRGBA[0] = 255; sprite.shaderRGBA[0] = 255;
sprite.shaderRGBA[1] = 255; sprite.shaderRGBA[1] = 255;
sprite.shaderRGBA[2] = 255; sprite.shaderRGBA[2] = 255;

View file

@ -1359,7 +1359,7 @@ void R_Register( void )
r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT); r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT);
r_drawentities = ri.Cvar_Get ("r_drawentities", "1", CVAR_CHEAT ); r_drawentities = ri.Cvar_Get ("r_drawentities", "1", CVAR_CHEAT );
r_ignore = ri.Cvar_Get( "r_ignore", "1", CVAR_CHEAT ); r_ignore = ri.Cvar_Get( "r_ignore", "1", CVAR_CHEAT );
r_nocull = ri.Cvar_Get ("r_nocull", "1", CVAR_CHEAT); r_nocull = ri.Cvar_Get ("r_nocull", "0", CVAR_CHEAT);
r_novis = ri.Cvar_Get ("r_novis", "0", CVAR_CHEAT); r_novis = ri.Cvar_Get ("r_novis", "0", CVAR_CHEAT);
r_showcluster = ri.Cvar_Get ("r_showcluster", "0", CVAR_CHEAT); r_showcluster = ri.Cvar_Get ("r_showcluster", "0", CVAR_CHEAT);
r_speeds = ri.Cvar_Get ("r_speeds", "0", CVAR_CHEAT); r_speeds = ri.Cvar_Get ("r_speeds", "0", CVAR_CHEAT);

View file

@ -207,7 +207,7 @@ int R_CullLocalBox(vec3_t localBounds[2]) {
int anyBack; int anyBack;
int front, back; int front, back;
if ( r_nocull->integer ) { if ( r_nocull->integer || vr_thirdPersonSpectator->integer ) {
return CULL_CLIP; return CULL_CLIP;
} }
@ -258,7 +258,7 @@ int R_CullLocalBox(vec3_t localBounds[2]) {
vec3_t v; vec3_t v;
vec3_t worldBounds[2]; vec3_t worldBounds[2];
if(r_nocull->integer) if(r_nocull->integer || vr_thirdPersonSpectator->integer)
{ {
return CULL_CLIP; return CULL_CLIP;
} }
@ -352,7 +352,7 @@ int R_CullPointAndRadiusEx( const vec3_t pt, float radius, const cplane_t* frust
const cplane_t *frust; const cplane_t *frust;
qboolean mightBeClipped = qfalse; qboolean mightBeClipped = qfalse;
if ( r_nocull->integer ) { if ( r_nocull->integer || vr_thirdPersonSpectator->integer) {
return CULL_CLIP; return CULL_CLIP;
} }
@ -678,75 +678,38 @@ static void R_SetFarClip( void )
================= =================
R_SetupFrustum R_SetupFrustum
Set up the culling frustum planes for the current view using the results we got from computing the first two rows of Setup that culling frustum planes for the current view
the projection matrix.
================= =================
*/ */
void R_SetupFrustum (viewParms_t *dest, float xmin, float xmax, float ymax, float zProj, float zFar, float stereoSep) void R_SetupFrustum( void ) {
{
vec3_t ofsorigin;
float oppleg, adjleg, length;
int i; int i;
float xs, xc;
if(stereoSep == 0 && xmin == -xmax) float ang;
{
// symmetric case can be simplified
VectorCopy(dest->or.origin, ofsorigin);
length = sqrt(xmax * xmax + zProj * zProj); ang = tr.viewParms.fovX / 180 * M_PI * 0.5f;
oppleg = xmax / length; xs = sinf( ang );
adjleg = zProj / length; xc = cosf( ang );
VectorScale(dest->or.axis[0], oppleg, dest->frustum[0].normal); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[0].normal );
VectorMA(dest->frustum[0].normal, adjleg, dest->or.axis[1], dest->frustum[0].normal); VectorMA( tr.viewParms.frustum[0].normal, xc, tr.viewParms.or.axis[1], tr.viewParms.frustum[0].normal );
VectorScale(dest->or.axis[0], oppleg, dest->frustum[1].normal); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[1].normal );
VectorMA(dest->frustum[1].normal, -adjleg, dest->or.axis[1], dest->frustum[1].normal); VectorMA( tr.viewParms.frustum[1].normal, -xc, tr.viewParms.or.axis[1], tr.viewParms.frustum[1].normal );
}
else
{
// In stereo rendering, due to the modification of the projection matrix, dest->or.origin is not the
// actual origin that we're rendering so offset the tip of the view pyramid.
VectorMA(dest->or.origin, stereoSep, dest->or.axis[1], ofsorigin);
oppleg = xmax + stereoSep;
length = sqrt(oppleg * oppleg + zProj * zProj);
VectorScale(dest->or.axis[0], oppleg / length, dest->frustum[0].normal);
VectorMA(dest->frustum[0].normal, zProj / length, dest->or.axis[1], dest->frustum[0].normal);
oppleg = xmin + stereoSep; ang = tr.viewParms.fovY / 180 * M_PI * 0.5f;
length = sqrt(oppleg * oppleg + zProj * zProj); xs = sin( ang );
VectorScale(dest->or.axis[0], -oppleg / length, dest->frustum[1].normal); xc = cos( ang );
VectorMA(dest->frustum[1].normal, -zProj / length, dest->or.axis[1], dest->frustum[1].normal);
}
length = sqrt(ymax * ymax + zProj * zProj); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[2].normal );
oppleg = ymax / length; VectorMA( tr.viewParms.frustum[2].normal, xc, tr.viewParms.or.axis[2], tr.viewParms.frustum[2].normal );
adjleg = zProj / length;
VectorScale(dest->or.axis[0], oppleg, dest->frustum[2].normal); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[3].normal );
VectorMA(dest->frustum[2].normal, adjleg, dest->or.axis[2], dest->frustum[2].normal); VectorMA( tr.viewParms.frustum[3].normal, -xc, tr.viewParms.or.axis[2], tr.viewParms.frustum[3].normal );
VectorScale(dest->or.axis[0], oppleg, dest->frustum[3].normal); for ( i = 0 ; i < 4 ; i++ ) {
VectorMA(dest->frustum[3].normal, -adjleg, dest->or.axis[2], dest->frustum[3].normal); tr.viewParms.frustum[i].type = PLANE_NON_AXIAL;
tr.viewParms.frustum[i].dist = DotProduct( tr.viewParms.or.origin, tr.viewParms.frustum[i].normal );
for (i=0 ; i<4 ; i++) { SetPlaneSignbits( &tr.viewParms.frustum[i] );
dest->frustum[i].type = PLANE_NON_AXIAL;
dest->frustum[i].dist = DotProduct (ofsorigin, dest->frustum[i].normal);
SetPlaneSignbits( &dest->frustum[i] );
}
if (zFar != 0.0f)
{
vec3_t farpoint;
VectorMA(ofsorigin, zFar, dest->or.axis[0], farpoint);
VectorScale(dest->or.axis[0], -1.0f, dest->frustum[4].normal);
dest->frustum[4].type = PLANE_NON_AXIAL;
dest->frustum[4].dist = DotProduct (farpoint, dest->frustum[4].normal);
SetPlaneSignbits( &dest->frustum[4] );
dest->flags |= VPF_FARPLANEFRUSTUM;
} }
} }
@ -810,7 +773,7 @@ void R_SetupProjection(viewParms_t *dest, float zProj, float zFar, qboolean comp
// Now that we have all the data for the projection matrix we can also setup the view frustum. // Now that we have all the data for the projection matrix we can also setup the view frustum.
if(computeFrustum) if(computeFrustum)
R_SetupFrustum(dest, xmin, xmax, ymax, zProj, zFar, stereoSep); R_SetupFrustum( );//dest, xmin, xmax, ymax, zProj, zFar, stereoSep);
} }
/* /*

View file

@ -32,7 +32,7 @@ added to the sorting list.
================ ================
*/ */
static qboolean R_CullSurface( msurface_t *surf ) { static qboolean R_CullSurface( msurface_t *surf ) {
if ( r_nocull->integer || surf->cullinfo.type == CULLINFO_NONE) { if ( (r_nocull->integer || vr_thirdPersonSpectator->integer) || surf->cullinfo.type == CULLINFO_NONE) {
return qfalse; return qfalse;
} }
@ -407,14 +407,14 @@ static void R_RecursiveWorldNode( mnode_t *node, uint32_t planeBits, uint32_t dl
// if the node wasn't marked as potentially visible, exit // if the node wasn't marked as potentially visible, exit
// pvs is skipped for depth shadows // pvs is skipped for depth shadows
if (!r_nocull->integer && !(tr.viewParms.flags & VPF_DEPTHSHADOW) && node->visCounts[tr.visIndex] != tr.visCounts[tr.visIndex]) { if (!vr_thirdPersonSpectator->integer && !(tr.viewParms.flags & VPF_DEPTHSHADOW) && node->visCounts[tr.visIndex] != tr.visCounts[tr.visIndex]) {
return; return;
} }
// if the bounding volume is outside the frustum, nothing // if the bounding volume is outside the frustum, nothing
// inside can be visible OPTIMIZE: don't do this all the way to leafs? // inside can be visible OPTIMIZE: don't do this all the way to leafs?
if ( !r_nocull->integer ) { if ( !r_nocull->integer && !vr_thirdPersonSpectator->integer ) {
int r; int r;
if ( planeBits & 1 ) { if ( planeBits & 1 ) {

View file

@ -9,6 +9,9 @@
#define THUMB_RIGHT 1 #define THUMB_RIGHT 1
typedef struct { typedef struct {
float fov_x;
float fov_y;
qboolean weapon_stabilised; qboolean weapon_stabilised;
qboolean weapon_zoomed; qboolean weapon_zoomed;
qboolean show_console; qboolean show_console;

View file

@ -49,6 +49,9 @@ void VR_GetResolution(engine_t* engine, int *pWidth, int *pHeight)
{ {
*pWidth = width = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH) * SUPER_SAMPLE; *pWidth = width = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH) * SUPER_SAMPLE;
*pHeight = height = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT) * SUPER_SAMPLE; *pHeight = height = vrapi_GetSystemPropertyInt(&engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT) * SUPER_SAMPLE;
vr.fov_x = vrapi_GetSystemPropertyInt( &engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_X);
vr.fov_y = vrapi_GetSystemPropertyInt( &engine->java, VRAPI_SYS_PROP_SUGGESTED_EYE_FOV_DEGREES_Y);
} }
else else
{ {

View file

@ -39,10 +39,12 @@ typedef enum {
} weaponSelectorType_t; } weaponSelectorType_t;
typedef enum { typedef enum {
VRFM_THIRDPERSON, //Camera will auto move to keep up with player VRFM_THIRDPERSON_1, //Camera will auto move to keep up with player
VRFM_THIRDPERSON_2, //Camera is completely free movement with the thumbstick VRFM_THIRDPERSON_2, //Camera is completely free movement with the thumbstick
VRFM_FIRSTPERSON, //Obvious isn't it?.. VRFM_FIRSTPERSON, //Obvious isn't it?..
VRFM_NUM_FOLLOWMODES VRFM_NUM_FOLLOWMODES,
VRFM_QUERY = 99 //Used to query which mode is active
} vrFollowMode_t; } vrFollowMode_t;
#endif #endif