Add Polyobj interpolator

This commit is contained in:
Eidolon 2022-04-12 22:22:16 -05:00
parent 330b34ee6b
commit 2aa34f0273
3 changed files with 87 additions and 2 deletions

View file

@ -24,6 +24,7 @@
#include "p_tick.h"
#include "p_local.h"
#include "p_polyobj.h"
#include "r_fps.h"
#include "r_main.h"
#include "r_state.h"
#include "r_defs.h"
@ -2049,6 +2050,9 @@ boolean EV_DoPolyObjRotate(polyrotdata_t *prdata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
th->turnobjs = prdata->turnobjs;
// apply action to mirroring polyobjects as well
@ -2110,6 +2114,9 @@ boolean EV_DoPolyObjMove(polymovedata_t *pmdata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
// apply action to mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))
@ -2177,6 +2184,9 @@ boolean EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata)
th->continuous = false;
}
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
th->pointnum = first->health;
return true;
@ -2225,6 +2235,9 @@ static void Polyobj_doSlideDoor(polyobj_t *po, polydoordata_t *doordata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
// start action on mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))
@ -2265,6 +2278,9 @@ static void Polyobj_doSwingDoor(polyobj_t *po, polydoordata_t *doordata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
// start action on mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))
@ -2336,6 +2352,9 @@ boolean EV_DoPolyObjDisplace(polydisplacedata_t *prdata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
// apply action to mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))
@ -2382,6 +2401,9 @@ boolean EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
// apply action to mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))
@ -2486,6 +2508,9 @@ boolean EV_DoPolyObjFlag(polyflagdata_t *pfdata)
oldpo = po;
// interpolation
R_CreateInterpolator_Polyobj(&th->thinker, po);
// apply action to mirroring polyobjects as well
start = 0;
while ((po = Polyobj_GetChild(oldpo, &start)))

View file

@ -284,6 +284,24 @@ void R_CreateInterpolator_SideScroll(thinker_t *thinker, side_t *side)
interp->sidescroll.oldrowoffset = interp->sidescroll.bakrowoffset = side->rowoffset;
}
void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj)
{
levelinterpolator_t *interp = CreateInterpolator(LVLINTERP_Polyobj, thinker);
interp->polyobj.polyobj = polyobj;
interp->polyobj.vertices_size = polyobj->numVertices;
interp->polyobj.oldvertices = Z_CallocAlign(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL, 32);
interp->polyobj.bakvertices = Z_CallocAlign(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL, 32);
for (size_t i = 0; i < polyobj->numVertices; i++)
{
interp->polyobj.oldvertices[i * 2 ] = interp->polyobj.bakvertices[i * 2 ] = polyobj->vertices[i]->x;
interp->polyobj.oldvertices[i * 2 + 1] = interp->polyobj.bakvertices[i * 2 + 1] = polyobj->vertices[i]->y;
}
interp->polyobj.oldcx = interp->polyobj.bakcx = polyobj->centerPt.x;
interp->polyobj.oldcy = interp->polyobj.bakcy = polyobj->centerPt.y;
}
void R_InitializeLevelInterpolators(void)
{
levelinterpolators_len = 0;
@ -293,6 +311,8 @@ void R_InitializeLevelInterpolators(void)
static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
{
size_t i;
switch (interp->type)
{
case LVLINTERP_SectorPlane:
@ -311,6 +331,19 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp)
interp->sidescroll.oldrowoffset = interp->sidescroll.bakrowoffset;
interp->sidescroll.bakrowoffset = interp->sidescroll.side->rowoffset;
break;
case LVLINTERP_Polyobj:
for (i = 0; i < interp->polyobj.vertices_size; i++)
{
interp->polyobj.oldvertices[i * 2 ] = interp->polyobj.bakvertices[i * 2 ];
interp->polyobj.oldvertices[i * 2 + 1] = interp->polyobj.bakvertices[i * 2 + 1];
interp->polyobj.bakvertices[i * 2 ] = interp->polyobj.polyobj->vertices[i]->x;
interp->polyobj.bakvertices[i * 2 + 1] = interp->polyobj.polyobj->vertices[i]->y;
}
interp->polyobj.oldcx = interp->polyobj.bakcx;
interp->polyobj.oldcy = interp->polyobj.bakcy;
interp->polyobj.bakcx = interp->polyobj.polyobj->centerPt.x;
interp->polyobj.bakcy = interp->polyobj.polyobj->centerPt.y;
break;
}
}
@ -346,7 +379,7 @@ void R_ClearLevelInterpolatorState(thinker_t *thinker)
void R_ApplyLevelInterpolators(fixed_t frac)
{
size_t i;
size_t i, ii;
for (i = 0; i < levelinterpolators_len; i++)
{
@ -380,13 +413,22 @@ void R_ApplyLevelInterpolators(fixed_t frac)
interp->sidescroll.side->textureoffset = R_LerpFixed(interp->sidescroll.oldtextureoffset, interp->sidescroll.baktextureoffset, frac);
interp->sidescroll.side->rowoffset = R_LerpFixed(interp->sidescroll.oldrowoffset, interp->sidescroll.bakrowoffset, frac);
break;
case LVLINTERP_Polyobj:
for (ii = 0; ii < interp->polyobj.vertices_size; ii++)
{
interp->polyobj.polyobj->vertices[ii]->x = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 ], interp->polyobj.bakvertices[ii * 2 ], frac);
interp->polyobj.polyobj->vertices[ii]->y = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 + 1], interp->polyobj.bakvertices[ii * 2 + 1], 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;
}
}
}
void R_RestoreLevelInterpolators(void)
{
size_t i;
size_t i, ii;
for (i = 0; i < levelinterpolators_len; i++)
{
@ -420,6 +462,15 @@ void R_RestoreLevelInterpolators(void)
interp->sidescroll.side->textureoffset = interp->sidescroll.baktextureoffset;
interp->sidescroll.side->rowoffset = interp->sidescroll.bakrowoffset;
break;
case LVLINTERP_Polyobj:
for (ii = 0; ii < interp->polyobj.vertices_size; ii++)
{
interp->polyobj.polyobj->vertices[ii]->x = interp->polyobj.bakvertices[ii * 2 ];
interp->polyobj.polyobj->vertices[ii]->y = interp->polyobj.bakvertices[ii * 2 + 1];
}
interp->polyobj.polyobj->centerPt.x = interp->polyobj.bakcx;
interp->polyobj.polyobj->centerPt.y = interp->polyobj.bakcy;
break;
}
}
}

View file

@ -58,6 +58,7 @@ typedef enum {
LVLINTERP_SectorPlane,
LVLINTERP_SectorScroll,
LVLINTERP_SideScroll,
LVLINTERP_Polyobj,
} levelinterpolator_type_e;
// Tagged union of a level interpolator
@ -80,6 +81,13 @@ typedef struct levelinterpolator_s {
side_t *side;
fixed_t oldtextureoffset, oldrowoffset, baktextureoffset, bakrowoffset;
} sidescroll;
struct {
polyobj_t *polyobj;
fixed_t *oldvertices;
fixed_t *bakvertices;
size_t vertices_size;
fixed_t oldcx, oldcy, bakcx, bakcy;
} polyobj;
};
} levelinterpolator_t;
@ -99,6 +107,7 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
void R_CreateInterpolator_SectorPlane(thinker_t *thinker, sector_t *sector, boolean ceiling);
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);
// Initialize level interpolators after a level change
void R_InitializeLevelInterpolators(void);