Added FOV Interpolation

This commit is contained in:
Boondorl 2022-12-18 01:04:25 -05:00 committed by Christoph Oelckers
parent a0cd1ba04a
commit 0d4d5587b5
13 changed files with 54 additions and 5 deletions

View file

@ -899,11 +899,8 @@ void D_Display ()
DAngle fov = DAngle::fromDeg(90.);
AActor *cam = players[consoleplayer].camera;
if (cam)
{
if (cam->player)
fov = DAngle::fromDeg(cam->player->FOV);
else fov = DAngle::fromDeg(cam->CameraFOV);
}
fov = DAngle::fromDeg(cam->GetFOV(I_GetTimeFrac()));
R_SetFOV(vp, fov);
}

View file

@ -1702,6 +1702,7 @@ int FLevelLocals::FinishTravel ()
}
pawn->LinkToWorld (nullptr);
pawn->ClearInterpolation();
pawn->ClearFOVInterpolation();
const int tid = pawn->tid; // Save TID (actor isn't linked into the hash chain yet)
pawn->tid = 0; // Reset TID
pawn->SetTID(tid); // Set TID (and link actor into the hash chain)

View file

@ -158,6 +158,7 @@ void P_Ticker (void)
while ((ac = it.Next()))
{
ac->ClearInterpolation();
ac->ClearFOVInterpolation();
}
P_ThinkParticles(Level); // [RH] make the particles think

View file

@ -929,6 +929,8 @@ public:
void SetViewAngle(DAngle ang, int fflags);
void SetViewRoll(DAngle roll, int fflags);
double GetFOV(double ticFrac);
PClassActor *GetBloodType(int type = 0) const;
double Distance2DSquared(AActor *other, bool absolute = false)
@ -998,6 +1000,7 @@ public:
DVector3 Vec3Angle(double length, DAngle angle, double dz, bool absolute = false);
void ClearInterpolation();
void ClearFOVInterpolation();
void Move(const DVector3 &vel)
{
@ -1278,6 +1281,7 @@ public:
// [RH] Used to interpolate the view to get >35 FPS
DVector3 Prev;
DRotator PrevAngles;
DAngle PrevFOV;
int PrevPortalGroup;
TArray<FDynamicLight *> AttachedLights;
TDeletingArray<FLightDefaults *> UserLights;

View file

@ -34,6 +34,14 @@ inline void AActor::ClearInterpolation()
else PrevPortalGroup = 0;
}
inline void AActor::ClearFOVInterpolation()
{
if (player)
PrevFOV = DAngle::fromDeg(player->FOV);
else
PrevFOV = DAngle::fromDeg(CameraFOV);
}
inline double secplane_t::ZatPoint(const AActor *ac) const
{
return (D + normal.X*ac->X() + normal.Y*ac->Y()) * negiC;

View file

@ -124,6 +124,7 @@ typedef enum
CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame
CF_INTERPVIEWANGLES = 1 << 15, // [MR] flag for interpolating view angles without interpolating the entire frame
CF_SCALEDNOLERP = 1 << 15, // [MR] flag for applying angles changes in the ticrate without interpolating the frame
CF_NOFOVINTERP = 1 << 16, // [B] Disable FOV interpolation when instantly zooming
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.

View file

@ -407,6 +407,7 @@ void AActor::PostSerialize()
}
}
ClearInterpolation();
ClearFOVInterpolation();
UpdateWaterLevel(false);
}
@ -3552,6 +3553,28 @@ void AActor::SetViewAngle(DAngle ang, int fflags)
}
double AActor::GetFOV(double ticFrac)
{
// [B] Disable interpolation when playing online, otherwise it gets vomit inducing
if (netgame)
return player ? player->FOV : CameraFOV;
double fov;
if (player)
{
if (player->cheats & CF_NOFOVINTERP)
return player->FOV;
fov = player->FOV;
}
else
{
fov = CameraFOV;
}
return PrevFOV.Degrees() * (1 - ticFrac) + fov * ticFrac;
}
void AActor::SetViewRoll(DAngle r, int fflags)
{
if (r != ViewAngles.Roll)
@ -4566,6 +4589,7 @@ void ConstructActor(AActor *actor, const DVector3 &pos, bool SpawningMapThing)
// set subsector and/or block links
actor->LinkToWorld (nullptr, SpawningMapThing);
actor->ClearInterpolation();
actor->ClearFOVInterpolation();
actor->dropoffz = actor->floorz = actor->Sector->floorplane.ZatPoint(pos);
actor->ceilingz = actor->Sector->ceilingplane.ZatPoint(pos);

View file

@ -1266,6 +1266,7 @@ void P_PlayerThink (player_t *player)
player->cheats &= ~CF_INTERPVIEW;
player->cheats &= ~CF_INTERPVIEWANGLES;
player->cheats &= ~CF_SCALEDNOLERP;
player->cheats &= ~CF_NOFOVINTERP;
player->mo->FloatVar("prevBob") = player->bob;
IFVIRTUALPTRNAME(player->mo, NAME_PlayerPawn, PlayerThink)

View file

@ -716,6 +716,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, ClearInterpolation, ClearInterpolation)
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, ClearFOVInterpolation)
{
PARAM_SELF_PROLOGUE(AActor);
self->ClearFOVInterpolation();
return 0;
}
static int ApplyDamageFactors(PClassActor *itemcls, int damagetype, int damage, int defdamage)
{
DmgFactors &df = itemcls->ActorInfo()->DamageFactors;

View file

@ -669,6 +669,7 @@ class Actor : Thinker native
native bool UpdateWaterLevel (bool splash = true);
native bool IsZeroDamage();
native void ClearInterpolation();
native void ClearFOVInterpolation();
native clearscope Vector3 PosRelative(sector sec) const;
native void RailAttack(FRailParams p);

View file

@ -464,6 +464,7 @@ class Weapon : StateProvider
if (flags & 1)
{ // Make the zoom instant.
player.FOV = player.DesiredFOV * zoom;
player.cheats |= CF_NOFOVINTERP;
}
if (flags & 2)
{ // Disable pitch/yaw scaling.

View file

@ -220,6 +220,7 @@ extend class PlayerPawn
{
p.camera = morphed;
}
morphed.ClearFOVInterpolation();
morphed.ScoreIcon = ScoreIcon; // [GRB]
if (eflash)
eflash.target = morphed;
@ -336,6 +337,7 @@ extend class PlayerPawn
{
player.camera = altmo;
}
altmo.ClearFOVInterpolation();
// [MH]
// If the player that was morphed is the one

View file

@ -1140,6 +1140,7 @@ enum EPlayerCheats
CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame
CF_INTERPVIEWANGLES = 1 << 15, // [MR] flag for interpolating view angles without interpolating the entire frame
CF_SCALEDNOLERP = 1 << 15, // [MR] flag for applying angles changes in the ticrate without interpolating the frame
CF_NOFOVINTERP = 1 << 16, // [B] Disable FOV interpolation when instantly zooming
CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths.