From 7d1f2df404711986a3cc742dad1f9e6e0ac69cde Mon Sep 17 00:00:00 2001 From: Boondorl <59555366+Boondorl@users.noreply.github.com> Date: Tue, 22 Jul 2025 10:35:20 -0400 Subject: [PATCH] Added scale and alpha interpolation Similar to angles, needs to be enabled via flags to prevent breaking existing sprites. --- src/playsim/actor.h | 14 +++++++++++++- src/playsim/actorinlines.h | 2 ++ src/rendering/hwrenderer/scene/hw_sprites.cpp | 7 ++++--- src/scripting/thingdef_data.cpp | 2 ++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 2a0db55b9..37c27a820 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -510,6 +510,8 @@ enum ActorRenderFlag2 RF2_STRETCHPIXELS = 0x0200, // don't apply SQUAREPIXELS for ROLLSPRITES RF2_LIGHTMULTALPHA = 0x0400, // attached lights use alpha as intensity multiplier RF2_ANGLEDROLL = 0x0800, // Sprite roll amount depends on (actor.Angle - actor.AngledRollOffset) + RF2_INTERPOLATESCALE = 0x1000, + RF2_INTERPOLATEALPHA = 0x2000, }; // This translucency value produces the closest match to Heretic's TINTTAB. @@ -1396,6 +1398,8 @@ public: // [RH] Used to interpolate the view to get >35 FPS DVector3 Prev; DRotator PrevAngles; + DVector2 PrevScale; + double PrevAlpha; DAngle PrevFOV; TArray AttachedLights; TDeletingArray UserLights; @@ -1544,7 +1548,7 @@ public: DVector3 InterpolatedPosition(double ticFrac) const { if (renderflags & RF_DONTINTERPOLATE) return Pos(); - else return Prev + (ticFrac * (Pos() - Prev)); + else return Prev * (1.0 - ticFrac) + Pos() * ticFrac; } DRotator InterpolatedAngles(double ticFrac) const { @@ -1554,6 +1558,14 @@ public: result.Roll = PrevAngles.Roll + deltaangle(PrevAngles.Roll, Angles.Roll) * ticFrac; return result; } + DVector2 InterpolatedScale(double ticFrac) const + { + return (renderflags2 & RF2_INTERPOLATESCALE) ? PrevScale * (1.0 - ticFrac) + Scale * ticFrac : Scale; + } + double InterpolatedAlpha(double ticFrac) const + { + return (renderflags2 & RF2_INTERPOLATEALPHA) ? PrevAlpha * (1.0 - ticFrac) + Alpha * ticFrac : Alpha; + } float GetSpriteOffset(bool y) const { if (y) return (float)(renderflags2 & RF2_FLIPSPRITEOFFSETY ? SpriteOffset.Y : -SpriteOffset.Y); diff --git a/src/playsim/actorinlines.h b/src/playsim/actorinlines.h index bbc173801..95e7d314f 100644 --- a/src/playsim/actorinlines.h +++ b/src/playsim/actorinlines.h @@ -30,6 +30,8 @@ inline void AActor::ClearInterpolation() { Prev = Pos(); PrevAngles = Angles; + PrevScale = Scale; + PrevAlpha = Alpha; if (Sector) PrevPortalGroup = Sector->PortalGroup; else PrevPortalGroup = 0; } diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 54253ee9e..d29766350 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -808,7 +808,8 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t const auto &vp = di->Viewpoint; AActor *camera = vp.camera; - if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha)) + const double alpha = thing->InterpolatedAlpha(vp.TicFrac); + if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(alpha)) { if (!(thing->flags & MF_STEALTH) || !di->isStealthVision() || thing == camera) return; @@ -821,7 +822,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t return; int spritenum = thing->sprite; - DVector2 sprscale(thing->Scale.X, thing->Scale.Y); + DVector2 sprscale = thing->InterpolatedScale(vp.TicFrac); if (thing->player != nullptr) { P_CheckPlayerSprite(thing, spritenum, sprscale); @@ -1281,7 +1282,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t translation = thing->Translation; OverrideShader = -1; - trans = thing->Alpha; + trans = alpha; hw_styleflags = STYLEHW_Normal; if (RenderStyle.BlendOp >= STYLEOP_Fuzz && RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 2c49d102a..db69e09b9 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -392,6 +392,8 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG(RF2, STRETCHPIXELS, AActor, renderflags2), DEFINE_FLAG(RF2, LIGHTMULTALPHA, AActor, renderflags2), DEFINE_FLAG(RF2, ANGLEDROLL, AActor, renderflags2), + DEFINE_FLAG(RF2, INTERPOLATESCALE, AActor, renderflags2), + DEFINE_FLAG(RF2, INTERPOLATEALPHA, AActor, renderflags2), // Bounce flags DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),