From 5f7389142e4cd4005f0f1bbe0704a8969dc8f73f Mon Sep 17 00:00:00 2001
From: Lactozilla <jp6781615@gmail.com>
Date: Fri, 7 Jun 2024 19:08:22 -0300
Subject: [PATCH] Interpolate renderer-specific slope vectors

---
 src/m_vector.c | 26 ++++++++++++++++++++++++++
 src/m_vector.h |  4 ++++
 src/r_fps.c    | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/r_fps.h    |  3 +++
 4 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/src/m_vector.c b/src/m_vector.c
index 3132a869d..1b04f8ae1 100644
--- a/src/m_vector.c
+++ b/src/m_vector.c
@@ -21,6 +21,32 @@ void DVector3_Load(dvector3_t *vec, double x, double y, double z)
 	vec->z = z;
 }
 
+void DVector3_Copy(dvector3_t *a_o, const dvector3_t *a_i)
+{
+	memcpy(a_o, a_i, sizeof(dvector3_t));
+}
+
+void DVector3_Add(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o)
+{
+	a_o->x = a_i->x + a_c->x;
+	a_o->y = a_i->y + a_c->y;
+	a_o->z = a_i->z + a_c->z;
+}
+
+void DVector3_Subtract(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o)
+{
+	a_o->x = a_i->x - a_c->x;
+	a_o->y = a_i->y - a_c->y;
+	a_o->z = a_i->z - a_c->z;
+}
+
+void DVector3_Multiply(const dvector3_t *a_i, double a_c, dvector3_t *a_o)
+{
+	a_o->x = a_i->x * a_c;
+	a_o->y = a_i->y * a_c;
+	a_o->z = a_i->z * a_c;
+}
+
 double DVector3_Magnitude(const dvector3_t *a_normal)
 {
 	double xs = a_normal->x * a_normal->x;
diff --git a/src/m_vector.h b/src/m_vector.h
index 55669be03..1395744f2 100644
--- a/src/m_vector.h
+++ b/src/m_vector.h
@@ -19,6 +19,10 @@ typedef struct
 } dvector3_t;
 
 void DVector3_Load(dvector3_t *vec, double x, double y, double z);
+void DVector3_Copy(dvector3_t *a_o, const dvector3_t *a_i);
+void DVector3_Add(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o);
+void DVector3_Subtract(const dvector3_t *a_i, const dvector3_t *a_c, dvector3_t *a_o);
+void DVector3_Multiply(const dvector3_t *a_i, double a_c, dvector3_t *a_o);
 double DVector3_Magnitude(const dvector3_t *a_normal);
 double DVector3_Normalize(dvector3_t *a_normal);
 void DVector3_Negate(dvector3_t *a_o);
diff --git a/src/r_fps.c b/src/r_fps.c
index 0773f228d..7f1f2bb30 100644
--- a/src/r_fps.c
+++ b/src/r_fps.c
@@ -120,6 +120,19 @@ static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixe
 	return out;
 }
 
+static double R_LerpDouble(double from, double to, double frac)
+{
+	return from + (frac * (to - from));
+}
+
+static dvector3_t *R_LerpDVector3(const dvector3_t *from, const dvector3_t *to, double frac, dvector3_t *out)
+{
+	DVector3_Subtract(to, from, out);
+	DVector3_Multiply(out, frac, out);
+	DVector3_Add(from, out, out);
+	return out;
+}
+
 // recalc necessary stuff for mouseaiming
 // slopes are already calculated for the full possible view (which is 4*viewheight).
 // 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
@@ -497,6 +510,14 @@ void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope)
 	FV2_Copy(&interp->dynslope.bakd, &slope->d);
 
 	interp->dynslope.oldzdelta = interp->dynslope.bakzdelta = slope->zdelta;
+
+	DVector3_Copy(&interp->dynslope.oldorigin, &slope->dorigin);
+	DVector3_Copy(&interp->dynslope.bakorigin, &slope->dorigin);
+
+	DVector3_Copy(&interp->dynslope.oldnormdir, &slope->dnormdir);
+	DVector3_Copy(&interp->dynslope.baknormdir, &slope->dnormdir);
+
+	interp->dynslope.olddzdelta = interp->dynslope.bakdzdelta = slope->dzdelta;
 }
 
 void R_InitializeLevelInterpolators(void)
@@ -561,6 +582,21 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
 		FV3_Copy(&interp->dynslope.bako, &interp->dynslope.slope->o);
 		FV2_Copy(&interp->dynslope.bakd, &interp->dynslope.slope->d);
 		interp->dynslope.bakzdelta = interp->dynslope.slope->zdelta;
+
+		DVector3_Copy(&interp->dynslope.oldorigin, &interp->dynslope.bakorigin);
+		DVector3_Copy(&interp->dynslope.oldnormdir, &interp->dynslope.baknormdir);
+		interp->dynslope.olddzdelta = interp->dynslope.bakdzdelta;
+
+		if (interp->dynslope.slope->moved)
+		{
+			P_CalculateSlopeVectors(interp->dynslope.slope);
+
+			interp->dynslope.slope->moved = false;
+		}
+
+		DVector3_Copy(&interp->dynslope.bakorigin, &interp->dynslope.slope->dorigin);
+		DVector3_Copy(&interp->dynslope.baknormdir, &interp->dynslope.slope->dnormdir);
+		interp->dynslope.bakdzdelta = interp->dynslope.slope->dzdelta;
 		break;
 	}
 }
@@ -646,7 +682,13 @@ void R_ApplyLevelInterpolators(fixed_t frac)
 			R_LerpVector3(&interp->dynslope.oldo, &interp->dynslope.bako, frac, &interp->dynslope.slope->o);
 			R_LerpVector2(&interp->dynslope.oldd, &interp->dynslope.bakd, frac, &interp->dynslope.slope->d);
 			interp->dynslope.slope->zdelta = R_LerpFixed(interp->dynslope.oldzdelta, interp->dynslope.bakzdelta, frac);
-			interp->dynslope.slope->moved = true;
+			if (rendermode == render_soft)
+			{
+				double dfrac = FixedToDouble(frac);
+				R_LerpDVector3(&interp->dynslope.oldorigin, &interp->dynslope.bakorigin, dfrac, &interp->dynslope.slope->dorigin);
+				R_LerpDVector3(&interp->dynslope.oldnormdir, &interp->dynslope.baknormdir, dfrac, &interp->dynslope.slope->dnormdir);
+				interp->dynslope.slope->dzdelta = R_LerpDouble(interp->dynslope.olddzdelta, interp->dynslope.bakdzdelta, dfrac);
+			}
 			break;
 		}
 	}
@@ -704,6 +746,10 @@ void R_RestoreLevelInterpolators(void)
 			FV3_Copy(&interp->dynslope.slope->o, &interp->dynslope.bako);
 			FV2_Copy(&interp->dynslope.slope->d, &interp->dynslope.bakd);
 			interp->dynslope.slope->zdelta = interp->dynslope.bakzdelta;
+
+			DVector3_Copy(&interp->dynslope.slope->dorigin, &interp->dynslope.bakorigin);
+			DVector3_Copy(&interp->dynslope.slope->dnormdir, &interp->dynslope.baknormdir);
+			interp->dynslope.slope->dzdelta = interp->dynslope.bakdzdelta;
 			break;
 		}
 	}
diff --git a/src/r_fps.h b/src/r_fps.h
index cd40b0a9a..33224a83a 100644
--- a/src/r_fps.h
+++ b/src/r_fps.h
@@ -115,6 +115,9 @@ typedef struct levelinterpolator_s {
 			vector3_t oldo, bako;
 			vector2_t oldd, bakd;
 			fixed_t oldzdelta, bakzdelta;
+			dvector3_t oldorigin, bakorigin;
+			dvector3_t oldnormdir, baknormdir;
+			double olddzdelta, bakdzdelta;
 		} dynslope;
 	};
 } levelinterpolator_t;
-- 
GitLab