diff --git a/src/p_slopes.c b/src/p_slopes.c index ffbfef2d300f5c2645b54c7dc62fa8c9dc8668b5..7c700d73681f15e4e4ca26c76376acb6494b83bc 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -22,6 +22,7 @@ #include "r_main.h" #include "p_maputl.h" #include "w_wad.h" +#include "r_fps.h" pslope_t *slopelist = NULL; UINT16 slopecount = 0; @@ -200,6 +201,9 @@ static inline void P_AddDynSlopeThinker (pslope_t* slope, dynplanetype_t type, l th->type = type; P_AddThinker(THINK_DYNSLOPE, &th->thinker); + + // interpolation + R_CreateInterpolator_DynSlope(&th->thinker, slope); } diff --git a/src/r_fps.c b/src/r_fps.c index 5c0c8f6df853bfe3f3ad749b17edf09fdacfe293..732052eacbbe8836ce4140324ed091357d6ac32a 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -93,6 +93,22 @@ static angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac) return from + FixedMul(frac, to - from); } +static vector2_t *R_LerpVector2(const vector2_t *from, const vector2_t *to, fixed_t frac, vector2_t *out) +{ + FV2_SubEx(to, from, out); + FV2_MulEx(out, frac, out); + FV2_AddEx(from, out, out); + return out; +} + +static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixed_t frac, vector3_t *out) +{ + FV3_SubEx(to, from, out); + FV3_MulEx(out, frac, out); + FV3_AddEx(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) @@ -364,6 +380,20 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj) interp->polyobj.oldcy = interp->polyobj.bakcy = polyobj->centerPt.y; } +void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope) +{ + levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_DynSlope, thinker); + interp->dynslope.slope = slope; + + FV3_Copy(&interp->dynslope.oldo, &slope->o); + FV3_Copy(&interp->dynslope.bako, &slope->o); + + FV2_Copy(&interp->dynslope.oldd, &slope->d); + FV2_Copy(&interp->dynslope.bakd, &slope->d); + + interp->dynslope.oldzdelta = interp->dynslope.bakzdelta = slope->zdelta; +} + void R_InitializeLevelInterpolators(void) { levelinterpolators_len = 0; @@ -406,6 +436,15 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp) interp->polyobj.bakcx = interp->polyobj.polyobj->centerPt.x; interp->polyobj.bakcy = interp->polyobj.polyobj->centerPt.y; break; + case LVLINTERP_DynSlope: + FV3_Copy(&interp->dynslope.oldo, &interp->dynslope.bako); + FV2_Copy(&interp->dynslope.oldd, &interp->dynslope.bakd); + interp->dynslope.oldzdelta = interp->dynslope.bakzdelta; + + 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; + break; } } @@ -484,6 +523,11 @@ void R_ApplyLevelInterpolators(fixed_t frac) interp->polyobj.polyobj->centerPt.x = R_LerpFixed(interp->polyobj.oldcx, interp->polyobj.bakcx, frac); interp->polyobj.polyobj->centerPt.y = R_LerpFixed(interp->polyobj.oldcy, interp->polyobj.bakcy, frac); break; + case LVLINTERP_DynSlope: + 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); + break; } } } @@ -533,6 +577,11 @@ void R_RestoreLevelInterpolators(void) interp->polyobj.polyobj->centerPt.x = interp->polyobj.bakcx; interp->polyobj.polyobj->centerPt.y = interp->polyobj.bakcy; break; + case LVLINTERP_DynSlope: + 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; + break; } } } diff --git a/src/r_fps.h b/src/r_fps.h index ec85a1f35fafa5c7ee96eeb24f28279bd0d1c00b..8ce2f3c26d5fdac64190f5bea9e1130ca03c0814 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -66,6 +66,7 @@ typedef enum { LVLINTERP_SectorScroll, LVLINTERP_SideScroll, LVLINTERP_Polyobj, + LVLINTERP_DynSlope, } levelinterpolator_type_e; // Tagged union of a level interpolator @@ -95,6 +96,12 @@ typedef struct levelinterpolator_s { size_t vertices_size; fixed_t oldcx, oldcy, bakcx, bakcy; } polyobj; + struct { + pslope_t *slope; + vector3_t oldo, bako; + vector2_t oldd, bakd; + fixed_t oldzdelta, bakzdelta; + } dynslope; }; } levelinterpolator_t; @@ -119,6 +126,7 @@ void R_CreateInterpolator_SectorPlane(thinker_t *thinker, sector_t *sector, bool void R_CreateInterpolator_SectorScroll(thinker_t *thinker, sector_t *sector, boolean ceiling); void R_CreateInterpolator_SideScroll(thinker_t *thinker, side_t *side); void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj); +void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope); // Initialize level interpolators after a level change void R_InitializeLevelInterpolators(void);