From cf2ee1eb3f31178095e5483ce28a9364cb8c2312 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Jan 2016 11:58:44 +0100 Subject: [PATCH] - fixed: Interpolations were deleted too early. They were immediately deleted when the associated thinker was destroyed. But this was too early because it missed the final tic of movement, resulting in a visible jump when a moving platform with a player on it came to a halt. Changed it so that DelRef no longer destroys the interpolation itself. Instead the ::Interpolate method will check if the reference count is 0, and if so and there was no more movement, will then destroy the interpolation. This ensures that it keeps running until it has interpolated all remaining bits of movement induced by the thinker. Now moving up a lift is 100% smooth, even with movement interpolation on. --- src/r_data/r_interpolate.cpp | 65 ++++++++++++++++++++++++++---------- src/r_data/r_interpolate.h | 3 +- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/r_data/r_interpolate.cpp b/src/r_data/r_interpolate.cpp index 268dd4aa0d..c46e17f9c2 100644 --- a/src/r_data/r_interpolate.cpp +++ b/src/r_data/r_interpolate.cpp @@ -344,10 +344,6 @@ int DInterpolation::AddRef() int DInterpolation::DelRef() { if (refcount > 0) --refcount; - if (refcount <= 0 && !(ObjectFlags & OF_EuthanizeMe)) - { - Destroy(); - } return refcount; } @@ -496,9 +492,16 @@ void DSectorPlaneInterpolation::Interpolate(fixed_t smoothratio) bakheight = *pheight; baktexz = sector->GetPlaneTexZ(pos); - *pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio); - sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio)); - P_RecalculateAttached3DFloors(sector); + if (refcount == 0 && oldheight == bakheight) + { + Destroy(); + } + else + { + *pheight = oldheight + FixedMul(bakheight - oldheight, smoothratio); + sector->SetPlaneTexZ(pos, oldtexz + FixedMul(baktexz - oldtexz, smoothratio)); + P_RecalculateAttached3DFloors(sector); + } } //========================================================================== @@ -622,8 +625,15 @@ void DSectorScrollInterpolation::Interpolate(fixed_t smoothratio) bakx = sector->GetXOffset(ceiling); baky = sector->GetYOffset(ceiling, false); - sector->SetXOffset(ceiling, oldx + FixedMul(bakx - oldx, smoothratio)); - sector->SetYOffset(ceiling, oldy + FixedMul(baky - oldy, smoothratio)); + if (refcount == 0 && oldx == bakx && oldy == baky) + { + Destroy(); + } + else + { + sector->SetXOffset(ceiling, oldx + FixedMul(bakx - oldx, smoothratio)); + sector->SetYOffset(ceiling, oldy + FixedMul(baky - oldy, smoothratio)); + } } //========================================================================== @@ -706,8 +716,15 @@ void DWallScrollInterpolation::Interpolate(fixed_t smoothratio) bakx = side->GetTextureXOffset(part); baky = side->GetTextureYOffset(part); - side->SetTextureXOffset(part, oldx + FixedMul(bakx - oldx, smoothratio)); - side->SetTextureYOffset(part, oldy + FixedMul(baky - oldy, smoothratio)); + if (refcount == 0 && oldx == bakx && oldy == baky) + { + Destroy(); + } + else + { + side->SetTextureXOffset(part, oldx + FixedMul(bakx - oldx, smoothratio)); + side->SetTextureYOffset(part, oldy + FixedMul(baky - oldy, smoothratio)); + } } //========================================================================== @@ -798,6 +815,7 @@ void DPolyobjInterpolation::Restore() void DPolyobjInterpolation::Interpolate(fixed_t smoothratio) { + bool changed = false; for(unsigned int i = 0; i < poly->Vertices.Size(); i++) { fixed_t *px = &poly->Vertices[i]->x; @@ -806,15 +824,26 @@ void DPolyobjInterpolation::Interpolate(fixed_t smoothratio) bakverts[i*2 ] = *px; bakverts[i*2+1] = *py; - *px = oldverts[i*2 ] + FixedMul(bakverts[i*2 ] - oldverts[i*2 ], smoothratio); - *py = oldverts[i*2+1] + FixedMul(bakverts[i*2+1] - oldverts[i*2+1], smoothratio); + if (bakverts[i * 2] != oldverts[i * 2] || bakverts[i * 2 + i] != oldverts[i * 2 + 1]) + { + changed = true; + *px = oldverts[i * 2] + FixedMul(bakverts[i * 2] - oldverts[i * 2], smoothratio); + *py = oldverts[i * 2 + 1] + FixedMul(bakverts[i * 2 + 1] - oldverts[i * 2 + 1], smoothratio); + } } - bakcx = poly->CenterSpot.x; - bakcy = poly->CenterSpot.y; - poly->CenterSpot.x = bakcx + FixedMul(bakcx - oldcx, smoothratio); - poly->CenterSpot.y = bakcy + FixedMul(bakcy - oldcy, smoothratio); + if (refcount == 0 && !changed) + { + Destroy(); + } + else + { + bakcx = poly->CenterSpot.x; + bakcy = poly->CenterSpot.y; + poly->CenterSpot.x = bakcx + FixedMul(bakcx - oldcx, smoothratio); + poly->CenterSpot.y = bakcy + FixedMul(bakcy - oldcy, smoothratio); - poly->ClearSubsectorLinks(); + poly->ClearSubsectorLinks(); + } } //========================================================================== diff --git a/src/r_data/r_interpolate.h b/src/r_data/r_interpolate.h index 9f28b04d08..29e8a61712 100644 --- a/src/r_data/r_interpolate.h +++ b/src/r_data/r_interpolate.h @@ -17,9 +17,10 @@ class DInterpolation : public DObject TObjPtr Next; TObjPtr Prev; - int refcount; protected: + int refcount; + DInterpolation(); public: