From 7fce284d93f8eadf91000d91a364219828c49abd Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 18 Mar 2022 22:21:22 +0000 Subject: [PATCH] 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 --- android/app/src/main/cpp/code/cgame/cg_draw.c | 14 +-- .../app/src/main/cpp/code/cgame/cg_local.h | 4 +- .../app/src/main/cpp/code/cgame/cg_players.c | 2 +- android/app/src/main/cpp/code/cgame/cg_view.c | 64 +++++----- .../app/src/main/cpp/code/cgame/cg_weapons.c | 117 ++++++++---------- .../src/main/cpp/code/renderergl2/tr_init.c | 2 +- .../src/main/cpp/code/renderergl2/tr_main.c | 89 ++++--------- .../src/main/cpp/code/renderergl2/tr_world.c | 6 +- .../app/src/main/cpp/code/vr/vr_clientinfo.h | 3 + .../app/src/main/cpp/code/vr/vr_renderer.c | 3 + android/app/src/main/cpp/code/vr/vr_types.h | 6 +- 11 files changed, 137 insertions(+), 173 deletions(-) diff --git a/android/app/src/main/cpp/code/cgame/cg_draw.c b/android/app/src/main/cpp/code/cgame/cg_draw.c index 1f2689d9..972e244e 100644 --- a/android/app/src/main/cpp/code/cgame/cg_draw.c +++ b/android/app/src/main/cpp/code/cgame/cg_draw.c @@ -1875,6 +1875,7 @@ CROSSHAIR CG_DrawCrosshair ================= */ +/* static void CG_DrawCrosshair(void) { float w, h; @@ -1930,7 +1931,7 @@ static void CG_DrawCrosshair(void) w, h, 0, 0, 1, 1, hShader ); trap_R_SetColor( NULL ); -} +}*/ /* ================= @@ -2550,7 +2551,6 @@ CG_DrawWeapReticle */ static void CG_DrawWeapReticle( void ) { - int weap; vec4_t light_color = {0.7, 0.7, 0.7, 1}; vec4_t black = {0.0, 0.0, 0.0, 1}; @@ -2602,7 +2602,7 @@ static void CG_DrawVignette( void ) 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 (currentComfortVignetteValue < comfortVignetteValue) @@ -2783,15 +2783,13 @@ void CG_DrawActive( void ) { float heightOffset = 0.0f; 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; //Just move camera down about 20cm heightOffset = -0.2f; } - else if ((( cg.snap->ps.stats[STAT_HEALTH] <= 0 ) && - ( cg.snap->ps.pm_type != PM_INTERMISSION )) || - (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON_2)) + else if (CG_IsDeathCam() || CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_2)) { worldscale *= SPECTATOR2_WORLDSCALE_MULTIPLIER; //Just move camera down about 50cm @@ -2818,7 +2816,7 @@ void CG_DrawActive( void ) { if (cg.snap->ps.stats[STAT_HEALTH] > 0 && //Don't use fake positional if following another player - this is handled in the //VR third person code - !( cg.demoPlayback || CG_IsThirdPersonFollowMode())) + !( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY))) { vec3_t pos, hmdposition, vieworg; VectorClear(pos); diff --git a/android/app/src/main/cpp/code/cgame/cg_local.h b/android/app/src/main/cpp/code/cgame/cg_local.h index 34fbb81d..e7e8b735 100644 --- a/android/app/src/main/cpp/code/cgame/cg_local.h +++ b/android/app/src/main/cpp/code/cgame/cg_local.h @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../game/bg_public.h" #include "cg_public.h" +#include "../vr/vr_types.h" // The entire cgame module is unloaded and reloaded on each level change, // 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_ZoomUp_f( void ); 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 ); diff --git a/android/app/src/main/cpp/code/cgame/cg_players.c b/android/app/src/main/cpp/code/cgame/cg_players.c index dbcf3eed..1afd526f 100644 --- a/android/app/src/main/cpp/code/cgame/cg_players.c +++ b/android/app/src/main/cpp/code/cgame/cg_players.c @@ -1998,7 +1998,7 @@ static void CG_PlayerSprites( centity_t *cent ) { //Put a sprite over the followed player's head if ( cent->currentState.number == cg.snap->ps.clientNum && cg.renderingThirdPerson && - CG_IsThirdPersonFollowMode()) { + CG_IsThirdPersonFollowMode(VRFM_QUERY)) { CG_PlayerFloatSprite( cent, cgs.media.friendShader ); return; } diff --git a/android/app/src/main/cpp/code/cgame/cg_view.c b/android/app/src/main/cpp/code/cgame/cg_view.c index f3267cd8..24937581 100644 --- a/android/app/src/main/cpp/code/cgame/cg_view.c +++ b/android/app/src/main/cpp/code/cgame/cg_view.c @@ -228,8 +228,7 @@ static void CG_OffsetVRThirdPersonView( void ) { float scale = 1.0f; //Follow mode 1 - if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW && - vr->follow_mode == VRFM_THIRDPERSON)) + if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_1)) { scale *= SPECTATOR_WORLDSCALE_MULTIPLIER; @@ -251,17 +250,15 @@ static void CG_OffsetVRThirdPersonView( void ) { } } //Death or follow mode 2 - else if ((( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) && - ( cg.predictedPlayerState.pm_type != PM_INTERMISSION )) || - (cg.snap->ps.pm_flags & PMF_FOLLOW && vr->follow_mode == VRFM_THIRDPERSON_2)) + else if (CG_IsDeathCam() ||CG_IsThirdPersonFollowMode(VRFM_THIRDPERSON_2)) { scale *= SPECTATOR2_WORLDSCALE_MULTIPLIER; //Move camera if the user is pushing thumbstick vec3_t angles, forward, right, up; VectorCopy(vr->offhandangles, angles); - float deltaYaw = SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]); - angles[YAW] += (vr->clientviewangles[YAW] - vr->hmdorientation[YAW]); + float deltaYaw = CG_IsDeathCam() ? SHORT2ANGLE(cg.predictedPlayerState.delta_angles[YAW]) : 0.0f; + angles[YAW] += deltaYaw + (vr->clientviewangles[YAW] - vr->hmdorientation[YAW]); 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][0] * 5.0f, right, cg.vr_vieworigin); @@ -525,6 +522,8 @@ static int CG_CalcFov( void ) { float f; int inwater; + +/* if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { // if in intermission, use a fixed value fov_x = 90; @@ -534,7 +533,7 @@ static int CG_CalcFov( void ) { // dmflag to prevent wide fov for all clients fov_x = 90; } else { - fov_x = cg_fov.value; + fov_x = vr->fov_x; if ( fov_x < 1 ) { fov_x = 1; } else if ( fov_x > 160 ) { @@ -568,6 +567,7 @@ static int CG_CalcFov( void ) { x = cg.refdef.width / tan( fov_x / 360 * M_PI ); fov_y = atan2( cg.refdef.height, x ); fov_y = fov_y * 360 / M_PI; +*/ // warp if underwater contents = CG_PointContents( cg.refdef.vieworg, -1 ); @@ -583,9 +583,9 @@ static int CG_CalcFov( void ) { } - // set it - cg.refdef.fov_x = fov_x; - cg.refdef.fov_y = fov_y; + // Seems we can get away with actually using 10 degrees less on the FOV + cg.refdef.fov_x = vr->fov_x - 10; + cg.refdef.fov_y = vr->fov_y - 10; if ( !cg.zoomed ) { cg.zoomSensitivity = 1; @@ -671,13 +671,6 @@ static int CG_CalcViewValues( ) { 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 static float hmdYaw = 0; if ( ps->pm_type == PM_INTERMISSION ) { @@ -731,9 +724,7 @@ static int CG_CalcViewValues( ) { } } - if (( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) && - ( cg.predictedPlayerState.pm_type != PM_INTERMISSION ) || - ( cg.demoPlayback || CG_IsThirdPersonFollowMode())) + if (CG_IsDeathCam() || cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY)) { //If dead, or spectating, view the map from above CG_OffsetVRThirdPersonView(); @@ -790,7 +781,7 @@ static int CG_CalcViewValues( ) { 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); VectorMA(origin, 4096, forward2, end2); @@ -826,7 +817,7 @@ static int CG_CalcViewValues( ) { angles[ROLL] = vr->hmdorientation[ROLL]; AnglesToAxis( angles, cg.refdef.viewaxis ); } - else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode()) + else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY)) { //If we're following someone, vec3_t angles; @@ -856,7 +847,7 @@ static int CG_CalcViewValues( ) { angles[YAW] = (cg.refdefViewAngles[YAW] - vr->hmdorientation[YAW]) + vr->weaponangles[YAW]; AnglesToAxis(angles, cg.refdef.viewaxis); } - else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode()) + else if ( cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY)) { //If we're following someone, 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 && - (vr->follow_mode == VRFM_THIRDPERSON || vr->follow_mode == VRFM_THIRDPERSON_2); + if (followMode == VRFM_QUERY) + { + 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 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 // pacifier, don't even try to read snapshots if ( cg.infoScreenText[0] != 0 ) { @@ -999,7 +1007,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo // decide on third person view cg.renderingThirdPerson = cg.predictedPlayerState.pm_type == PM_SPECTATOR || - cg.demoPlayback || CG_IsThirdPersonFollowMode() || + cg.demoPlayback || CG_IsThirdPersonFollowMode(VRFM_QUERY) || cg_thirdPerson.integer; // build cg.refdef diff --git a/android/app/src/main/cpp/code/cgame/cg_weapons.c b/android/app/src/main/cpp/code/cgame/cg_weapons.c index a4bbef9e..c74ffadb 100644 --- a/android/app/src/main/cpp/code/cgame/cg_weapons.c +++ b/android/app/src/main/cpp/code/cgame/cg_weapons.c @@ -2076,24 +2076,24 @@ void CG_DrawWeaponSelector( void ) CG_CalculateVRWeaponPosition(controllerOrigin, controllerAngles); VectorSubtract(vr->weaponposition, cg.weaponSelectorOrigin, controllerOffset); - vec3_t holsterAngles, holsterOrigin, beamOrigin, holsterForward, holsterRight, holsterUp; - CG_CalculateVRPositionInWorld(cg.weaponSelectorOrigin, cg.weaponSelectorOffset, cg.weaponSelectorAngles, holsterOrigin, holsterAngles); + vec3_t wheelAngles, wheelOrigin, beamOrigin, wheelForward, wheelRight, wheelUp; + CG_CalculateVRPositionInWorld(cg.weaponSelectorOrigin, cg.weaponSelectorOffset, cg.weaponSelectorAngles, wheelOrigin, wheelAngles); - AngleVectors(holsterAngles, holsterForward, holsterRight, holsterUp); + AngleVectors(wheelAngles, wheelForward, wheelRight, wheelUp); if (selectorMode == WS_CONTROLLER) { - VectorCopy(controllerOrigin, holsterOrigin); + VectorCopy(controllerOrigin, wheelOrigin); } else { // 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); - VectorMA(holsterOrigin, ((DEPTH*2.0f)*((selectorMode == WS_CONTROLLER) ? frac : 1.0f)), holsterForward, holsterOrigin); - VectorCopy(holsterOrigin, selectorOrigin); + VectorCopy(wheelOrigin, beamOrigin); + VectorMA(wheelOrigin, ((DEPTH*2.0f)*((selectorMode == WS_CONTROLLER) ? frac : 1.0f)), wheelForward, wheelOrigin); + VectorCopy(wheelOrigin, selectorOrigin); const int switchThumbsticks = (int)trap_Cvar_VariableValue("vr_switchThumbsticks"); const int thumb = switchThumbsticks !=0 ? THUMB_LEFT : THUMB_RIGHT; @@ -2111,8 +2111,8 @@ void CG_DrawWeaponSelector( void ) float y = 0.0f; if (selectorMode == WS_CONTROLLER) { - x = (sinf(DEG2RAD(holsterAngles[YAW] - controllerAngles[YAW])) / sinf(DEG2RAD(22.5f))); - y = ((holsterAngles[PITCH] - controllerAngles[PITCH]) / 22.5f); + x = (sinf(DEG2RAD(wheelAngles[YAW] - controllerAngles[YAW])) / sinf(DEG2RAD(22.5f))); + y = ((wheelAngles[PITCH] - controllerAngles[PITCH]) / 22.5f); float len = length(x, y); if (len > 1.0f) @@ -2127,8 +2127,8 @@ void CG_DrawWeaponSelector( void ) y = thumbstickAxisY; } - VectorMA(selectorOrigin, RAD * x, holsterRight, selectorOrigin); - VectorMA(selectorOrigin, RAD * y, holsterUp, selectorOrigin); + VectorMA(selectorOrigin, RAD * x, wheelRight, selectorOrigin); + VectorMA(selectorOrigin, RAD * y, wheelUp, selectorOrigin); { refEntity_t blob; @@ -2154,38 +2154,39 @@ void CG_DrawWeaponSelector( void ) } #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 - 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 qboolean selected = qfalse; - int w = 0; - for (int index = 0; index < WP_NUM_WEAPONS-1; ++index) + int angleIndex = 0; + for (int weaponId = 1; weaponId < WP_NUM_WEAPONS; ++weaponId) { - if ((index+1) == WP_GRAPPLING_HOOK) + if (weaponId == WP_GRAPPLING_HOOK || + weaponId == WP_GAUNTLET) { continue; } //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; VectorClear(angles); - angles[YAW] = holsterAngles[YAW]; - angles[PITCH] = holsterAngles[PITCH]; - angles[ROLL] = iconAngles[w]; + angles[YAW] = wheelAngles[YAW]; + angles[PITCH] = wheelAngles[PITCH]; + angles[ROLL] = wheelIconAngles[angleIndex]; vec3_t forward, 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, iconForeground); @@ -2198,9 +2199,9 @@ void CG_DrawWeaponSelector( void ) frac == 1.0f && selectable) { - if (cg.weaponSelectorSelection != w) + if (cg.weaponSelectorSelection != weaponId) { - cg.weaponSelectorSelection = w; + cg.weaponSelectorSelection = weaponId; trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0); } @@ -2215,16 +2216,16 @@ void CG_DrawWeaponSelector( void ) float angle = AngleNormalize360(RAD2DEG(a)); float angle360 = angle + 360; // HACK - Account for the icon at the top - float low = ((iconAngles[w-1]+iconAngles[w])/2.0f); - float high = ((iconAngles[w]+iconAngles[w+1])/2.0f); + float low = ((wheelIconAngles[angleIndex-1]+wheelIconAngles[angleIndex])/2.0f); + float high = ((wheelIconAngles[angleIndex]+wheelIconAngles[angleIndex+1])/2.0f); if (((angle > low && angle <= high) || (angle360 > low && angle360 <= high)) && (length(vr->thumbstick_location[thumb][0], vr->thumbstick_location[thumb][1]) > 0.5f) && selectable) { - if (cg.weaponSelectorSelection != w) + if (cg.weaponSelectorSelection != weaponId) { - cg.weaponSelectorSelection = w; + cg.weaponSelectorSelection = weaponId; 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; memset( &sprite, 0, sizeof( sprite ) ); @@ -2250,52 +2251,36 @@ void CG_DrawWeaponSelector( void ) 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; memset(&ent, 0, sizeof(ent)); VectorCopy(iconOrigin, ent.origin); //Shift the weapon model a bit to be in the sphere - if (w == WP_GAUNTLET) + if (weaponId == WP_GAUNTLET) { SCALE = 0.065f; - VectorMA(ent.origin, 0.3f, holsterUp, ent.origin); - VectorMA(ent.origin, 0.15f, holsterRight, ent.origin); - VectorMA(ent.origin, -0.15f, holsterForward, ent.origin); + VectorMA(ent.origin, 0.3f, wheelUp, ent.origin); + VectorMA(ent.origin, 0.15f, wheelRight, ent.origin); + VectorMA(ent.origin, -0.15f, wheelForward, ent.origin); } else { - VectorMA(ent.origin, 0.3f, holsterForward, ent.origin); - VectorMA(ent.origin, -0.2f, holsterRight, ent.origin); - VectorMA(ent.origin, 0.5f, holsterUp, ent.origin); + VectorMA(ent.origin, 0.3f, wheelForward, ent.origin); + VectorMA(ent.origin, -0.2f, wheelRight, ent.origin); + VectorMA(ent.origin, 0.5f, wheelUp, ent.origin); } vec3_t iconAngles; - VectorCopy(holsterAngles, iconAngles); + VectorCopy(wheelAngles, iconAngles); iconAngles[PITCH] = 10; iconAngles[YAW] -= 145.0f; - if (w == WP_GAUNTLET) + if (weaponId == WP_GAUNTLET) { iconAngles[ROLL] -= 90.0f; } float weaponScale = ((SCALE+0.02f)*frac) + - (cg.weaponSelectorSelection == w ? 0.04f : 0); + (cg.weaponSelectorSelection == weaponId ? 0.04f : 0); AnglesToAxis(iconAngles, ent.axis); VectorScale(ent.axis[0], weaponScale, ent.axis[0]); @@ -2303,7 +2288,7 @@ void CG_DrawWeaponSelector( void ) VectorScale(ent.axis[2], weaponScale, ent.axis[2]); ent.nonNormalizedAxes = qtrue; - if( w == WP_RAILGUN ) { + if( weaponId == WP_RAILGUN ) { clientInfo_t *ci = &cgs.clientinfo[cg.predictedPlayerState.clientNum]; if( cg_entities[cg.predictedPlayerState.clientNum].pe.railFireTime + 1500 > cg.time ) { 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) { ent.customShader = cgs.media.invisShader; } trap_R_AddRefEntityToScene(&ent); - if ( cg_weapons[w].barrelModel ) + if ( cg_weapons[weaponId].barrelModel ) { refEntity_t barrel; memset(&barrel, 0, sizeof(barrel)); - barrel.hModel = cg_weapons[w].barrelModel; + barrel.hModel = cg_weapons[weaponId].barrelModel; vec3_t barrelAngles; VectorClear(barrelAngles); barrelAngles[ROLL] = AngleNormalize360((cg.time - cg.weaponSelectorTime) * 0.9f); AnglesToAxis(barrelAngles, barrel.axis); - CG_PositionRotatedEntityOnTag(&barrel, &ent, cg_weapons[w].weaponModel, + CG_PositionRotatedEntityOnTag(&barrel, &ent, cg_weapons[weaponId].weaponModel, "tag_barrel"); if (!selectable) { @@ -2350,8 +2335,8 @@ void CG_DrawWeaponSelector( void ) VectorCopy(iconOrigin, sprite.origin); sprite.reType = RT_SPRITE; - sprite.customShader = cg_weapons[w].weaponIcon; - sprite.radius = 0.6f + (cg.weaponSelectorSelection == w ? 0.1f : 0); + sprite.customShader = cg_weapons[weaponId].weaponIcon; + sprite.radius = 0.6f + (cg.weaponSelectorSelection == weaponId ? 0.1f : 0); sprite.shaderRGBA[0] = 255; sprite.shaderRGBA[1] = 255; sprite.shaderRGBA[2] = 255; @@ -2363,7 +2348,7 @@ void CG_DrawWeaponSelector( void ) VectorCopy( iconBackground, sprite.origin ); sprite.reType = RT_SPRITE; 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[1] = 255; sprite.shaderRGBA[2] = 255; diff --git a/android/app/src/main/cpp/code/renderergl2/tr_init.c b/android/app/src/main/cpp/code/renderergl2/tr_init.c index f87a8516..0642ceff 100644 --- a/android/app/src/main/cpp/code/renderergl2/tr_init.c +++ b/android/app/src/main/cpp/code/renderergl2/tr_init.c @@ -1359,7 +1359,7 @@ void R_Register( void ) r_norefresh = ri.Cvar_Get ("r_norefresh", "0", CVAR_CHEAT); r_drawentities = ri.Cvar_Get ("r_drawentities", "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_showcluster = ri.Cvar_Get ("r_showcluster", "0", CVAR_CHEAT); r_speeds = ri.Cvar_Get ("r_speeds", "0", CVAR_CHEAT); diff --git a/android/app/src/main/cpp/code/renderergl2/tr_main.c b/android/app/src/main/cpp/code/renderergl2/tr_main.c index ecf4cec0..880e13b8 100644 --- a/android/app/src/main/cpp/code/renderergl2/tr_main.c +++ b/android/app/src/main/cpp/code/renderergl2/tr_main.c @@ -207,7 +207,7 @@ int R_CullLocalBox(vec3_t localBounds[2]) { int anyBack; int front, back; - if ( r_nocull->integer ) { + if ( r_nocull->integer || vr_thirdPersonSpectator->integer ) { return CULL_CLIP; } @@ -258,7 +258,7 @@ int R_CullLocalBox(vec3_t localBounds[2]) { vec3_t v; vec3_t worldBounds[2]; - if(r_nocull->integer) + if(r_nocull->integer || vr_thirdPersonSpectator->integer) { return CULL_CLIP; } @@ -352,7 +352,7 @@ int R_CullPointAndRadiusEx( const vec3_t pt, float radius, const cplane_t* frust const cplane_t *frust; qboolean mightBeClipped = qfalse; - if ( r_nocull->integer ) { + if ( r_nocull->integer || vr_thirdPersonSpectator->integer) { return CULL_CLIP; } @@ -678,75 +678,38 @@ static void R_SetFarClip( void ) ================= R_SetupFrustum -Set up the culling frustum planes for the current view using the results we got from computing the first two rows of -the projection matrix. +Setup that culling frustum planes for the current view ================= */ -void R_SetupFrustum (viewParms_t *dest, float xmin, float xmax, float ymax, float zProj, float zFar, float stereoSep) -{ - vec3_t ofsorigin; - float oppleg, adjleg, length; +void R_SetupFrustum( void ) { int i; - - if(stereoSep == 0 && xmin == -xmax) - { - // symmetric case can be simplified - VectorCopy(dest->or.origin, ofsorigin); + float xs, xc; + float ang; - length = sqrt(xmax * xmax + zProj * zProj); - oppleg = xmax / length; - adjleg = zProj / length; + ang = tr.viewParms.fovX / 180 * M_PI * 0.5f; + xs = sinf( ang ); + xc = cosf( ang ); - VectorScale(dest->or.axis[0], oppleg, dest->frustum[0].normal); - VectorMA(dest->frustum[0].normal, adjleg, dest->or.axis[1], dest->frustum[0].normal); + VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.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); - VectorMA(dest->frustum[1].normal, -adjleg, dest->or.axis[1], dest->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); + VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[1].normal ); + VectorMA( tr.viewParms.frustum[1].normal, -xc, tr.viewParms.or.axis[1], tr.viewParms.frustum[1].normal ); - oppleg = xmin + stereoSep; - length = sqrt(oppleg * oppleg + zProj * zProj); - VectorScale(dest->or.axis[0], -oppleg / length, dest->frustum[1].normal); - VectorMA(dest->frustum[1].normal, -zProj / length, dest->or.axis[1], dest->frustum[1].normal); - } + ang = tr.viewParms.fovY / 180 * M_PI * 0.5f; + xs = sin( ang ); + xc = cos( ang ); - length = sqrt(ymax * ymax + zProj * zProj); - oppleg = ymax / length; - adjleg = zProj / length; + VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[2].normal ); + VectorMA( tr.viewParms.frustum[2].normal, xc, tr.viewParms.or.axis[2], tr.viewParms.frustum[2].normal ); - VectorScale(dest->or.axis[0], oppleg, dest->frustum[2].normal); - VectorMA(dest->frustum[2].normal, adjleg, dest->or.axis[2], dest->frustum[2].normal); + VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[3].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); - VectorMA(dest->frustum[3].normal, -adjleg, dest->or.axis[2], dest->frustum[3].normal); - - for (i=0 ; i<4 ; 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; + for ( i = 0 ; i < 4 ; i++ ) { + tr.viewParms.frustum[i].type = PLANE_NON_AXIAL; + tr.viewParms.frustum[i].dist = DotProduct( tr.viewParms.or.origin, tr.viewParms.frustum[i].normal ); + SetPlaneSignbits( &tr.viewParms.frustum[i] ); } } @@ -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. if(computeFrustum) - R_SetupFrustum(dest, xmin, xmax, ymax, zProj, zFar, stereoSep); + R_SetupFrustum( );//dest, xmin, xmax, ymax, zProj, zFar, stereoSep); } /* diff --git a/android/app/src/main/cpp/code/renderergl2/tr_world.c b/android/app/src/main/cpp/code/renderergl2/tr_world.c index f037d114..2de5583e 100644 --- a/android/app/src/main/cpp/code/renderergl2/tr_world.c +++ b/android/app/src/main/cpp/code/renderergl2/tr_world.c @@ -32,7 +32,7 @@ added to the sorting list. ================ */ 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; } @@ -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 // 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; } // if the bounding volume is outside the frustum, nothing // 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; if ( planeBits & 1 ) { diff --git a/android/app/src/main/cpp/code/vr/vr_clientinfo.h b/android/app/src/main/cpp/code/vr/vr_clientinfo.h index 4a2af780..ebb29b03 100644 --- a/android/app/src/main/cpp/code/vr/vr_clientinfo.h +++ b/android/app/src/main/cpp/code/vr/vr_clientinfo.h @@ -9,6 +9,9 @@ #define THUMB_RIGHT 1 typedef struct { + float fov_x; + float fov_y; + qboolean weapon_stabilised; qboolean weapon_zoomed; qboolean show_console; diff --git a/android/app/src/main/cpp/code/vr/vr_renderer.c b/android/app/src/main/cpp/code/vr/vr_renderer.c index d89e38ae..bcf7724c 100644 --- a/android/app/src/main/cpp/code/vr/vr_renderer.c +++ b/android/app/src/main/cpp/code/vr/vr_renderer.c @@ -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; *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 { diff --git a/android/app/src/main/cpp/code/vr/vr_types.h b/android/app/src/main/cpp/code/vr/vr_types.h index 14789c9c..8d5cdcce 100644 --- a/android/app/src/main/cpp/code/vr/vr_types.h +++ b/android/app/src/main/cpp/code/vr/vr_types.h @@ -39,10 +39,12 @@ typedef enum { } weaponSelectorType_t; 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_FIRSTPERSON, //Obvious isn't it?.. - VRFM_NUM_FOLLOWMODES + VRFM_NUM_FOLLOWMODES, + + VRFM_QUERY = 99 //Used to query which mode is active } vrFollowMode_t; #endif