diff --git a/src/playsim/d_player.h b/src/playsim/d_player.h index 49d8d54a1f..34ac55da6f 100644 --- a/src/playsim/d_player.h +++ b/src/playsim/d_player.h @@ -125,6 +125,7 @@ typedef enum CF_INTERPVIEWANGLES = 1 << 15, // [MR] flag for interpolating view angles without interpolating the entire frame CF_NOFOVINTERP = 1 << 16, // [B] Disable FOV interpolation when instantly zooming CF_SCALEDNOLERP = 1 << 17, // [MR] flag for applying angles changes in the ticrate without interpolating the frame + CF_NOVIEWPOSINTERP = 1 << 18, // Disable view position interpolation. CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths. CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either. CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either. diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index a1888d5c15..6839b412ac 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -1278,6 +1278,7 @@ void P_PlayerThink (player_t *player) player->cheats &= ~CF_INTERPVIEWANGLES; player->cheats &= ~CF_SCALEDNOLERP; player->cheats &= ~CF_NOFOVINTERP; + player->cheats &= ~CF_NOVIEWPOSINTERP; player->mo->FloatVar("prevBob") = player->bob; IFVIRTUALPTRNAME(player->mo, NAME_PlayerPawn, PlayerThink) diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index fbb785d0b5..b78cf955d0 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -78,7 +78,7 @@ struct InterpolationViewer { struct instance { - DVector3 Pos; + DVector3 Pos, ViewPos; DRotator Angles; DRotator ViewAngles; }; @@ -605,6 +605,22 @@ void R_InterpolateView(FRenderViewpoint& viewPoint, const player_t* const player // Now that the base position and angles are set, add offsets. + const DViewPosition* const vPos = iView->ViewActor->ViewPos; + if (vPos != nullptr && !(vPos->Flags & VPSF_ABSOLUTEPOS) + && (player == nullptr || gamestate == GS_TITLELEVEL || (!(player->cheats & CF_CHASECAM) && (!r_deathcamera || !(iView->ViewActor->flags6 & MF6_KILLED))))) + { + DVector3 vOfs = {}; + if (player == nullptr || !(player->cheats & CF_NOVIEWPOSINTERP)) + vOfs = iView->Old.ViewPos * inverseTicFrac + iView->New.ViewPos * ticFrac; + else + vOfs = iView->New.ViewPos; + + if (vPos->Flags & VPSF_ABSOLUTEOFFSET) + iView->ViewOffset += vOfs; + else + iView->RelativeViewOffset += vOfs; + } + DVector3 posOfs = iView->ViewOffset; if (!iView->RelativeViewOffset.isZero()) posOfs += DQuaternion::FromAngles(viewPoint.Angles.Yaw, viewPoint.Angles.Pitch, viewPoint.Angles.Roll) * iView->RelativeViewOffset; @@ -916,8 +932,8 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA viewPoint.showviewer = false; viewPoint.bForceNoViewer = matchPlayer; - if (gamestate != GS_TITLELEVEL && - ((player != nullptr && (player->cheats & CF_CHASECAM)) || (r_deathcamera && (viewPoint.camera->flags6 & MF6_KILLED)))) + if (player != nullptr && gamestate != GS_TITLELEVEL + && ((player->cheats & CF_CHASECAM) || (r_deathcamera && (viewPoint.camera->flags6 & MF6_KILLED)))) { // The cam Actor should probably be visible in third person. viewPoint.showviewer = true; @@ -925,7 +941,8 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA iView->ViewOffset.Z = clamp(chase_height, -1000.0, 1000.0); iView->RelativeViewOffset.X = -clamp(chase_dist, 0.0, 30000.0); } - else if (viewOffset != nullptr) + + if (viewOffset != nullptr) { // No chase/death cam, so use the view offset. if (!viewPoint.bForceNoViewer) @@ -933,16 +950,13 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA if (viewOffset->Flags & VPSF_ABSOLUTEPOS) { + iView->New.ViewPos.Zero(); if (!matchPlayer) camPos = viewOffset->Offset; } - else if (viewOffset->Flags & VPSF_ABSOLUTEOFFSET) - { - iView->ViewOffset += viewOffset->Offset; - } else { - iView->RelativeViewOffset = viewOffset->Offset; + iView->New.ViewPos = viewOffset->Offset; } } diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 7afacf2086..92120c36df 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -1161,6 +1161,7 @@ enum EPlayerCheats CF_INTERPVIEWANGLES = 1 << 15, // [MR] flag for interpolating view angles without interpolating the entire frame CF_NOFOVINTERP = 1 << 16, // [B] Disable FOV interpolation when instantly zooming CF_SCALEDNOLERP = 1 << 17, // [MR] flag for applying angles changes in the ticrate without interpolating the frame + CF_NOVIEWPOSINTERP = 1 << 18, // Disable view position interpolation. CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.