Add baked offset parameters

This commit is contained in:
Chearii 2025-03-12 08:13:53 -04:00 committed by Eidolon
parent 0d9a67b8b5
commit 19fdf19eb4
16 changed files with 408 additions and 6 deletions

View file

@ -3367,6 +3367,12 @@ enum
THING_PROP_HNEXT,
THING_PROP_HPREV,
THING_PROP_ITNEXT,
THING_PROP_BAKEDXOFFSET,
THING_PROP_BAKEDYOFFSET,
THING_PROP_BAKEDZOFFSET,
THING_PROP_BAKEDXPIVOT,
THING_PROP_BAKEDYPIVOT,
THING_PROP_BAKEDZPIVOT,
THING_PROP__MAX
};
@ -3552,6 +3558,12 @@ bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, A
PROP_MOBJ(THING_PROP_HNEXT, hnext)
PROP_MOBJ(THING_PROP_HPREV, hprev)
PROP_MOBJ(THING_PROP_ITNEXT, itnext)
PROP_INT(THING_PROP_BAKEDXOFFSET, bakexoff)
PROP_INT(THING_PROP_BAKEDYOFFSET, bakeyoff)
PROP_INT(THING_PROP_BAKEDZOFFSET, bakezoff)
PROP_INT(THING_PROP_BAKEDXPIVOT, bakexpiv)
PROP_INT(THING_PROP_BAKEDYPIVOT, bakeypiv)
PROP_INT(THING_PROP_BAKEDZPIVOT, bakezpiv)
default:
{
CONS_Alert(CONS_WARNING, "GetThingProperty type %d out of range (expected 0 - %d).\n", property, THING_PROP__MAX-1);

View file

@ -4756,6 +4756,7 @@ struct int_const_s const INT_CONST[] = {
{"OV_DONT3DOFFSET", OV_DONT3DOFFSET},
{"OV_DONTXYSCALE", OV_DONTXYSCALE},
{"OV_DONTROLL", OV_DONTROLL},
{"OV_DONTBAKEOFFSET", OV_DONTBAKEOFFSET},
// Player state (playerstate_t)
{"PST_LIVE",PST_LIVE}, // Playing or camping.

View file

@ -4670,6 +4670,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
angle_t spriterotangle = 0;
vector2_t visoffs;
#endif
// uncapped/interpolation
@ -4869,12 +4870,31 @@ static void HWR_ProjectSprite(mobj_t *thing)
flip = 0;
}
}
// initialize and rotate pitch/roll vector
visoffs.x = 0;
visoffs.y = 0;
const fixed_t visoffymul = (vflip ? -FRACUNIT : FRACUNIT);
if (R_ThingIsUsingBakedOffsets(thing))
{
R_RotateSpriteOffsetsByPitchRoll(thing,
vflip,
hflip,
&visoffs);
}
#endif
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
{
spr_offset = interp.spritexoffset;
#ifdef ROTSPRITE
spr_topoffset = (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
mapobjectscale));
#else
spr_topoffset = interp.spriteyoffset;
#endif
}
else
{
@ -4884,7 +4904,13 @@ static void HWR_ProjectSprite(mobj_t *thing)
flipoffset = -1;
spr_offset += interp.spritexoffset * flipoffset;
#ifdef ROTSPRITE
spr_topoffset += (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
mapobjectscale))
* flipoffset;
#else
spr_topoffset += interp.spriteyoffset * flipoffset;
#endif
}
if (papersprite)
@ -4942,17 +4968,28 @@ static void HWR_ProjectSprite(mobj_t *thing)
}
else
{
#ifdef ROTSPRITE
if (visoffs.x)
{
visoffs.x = (FixedDiv((visoffs.x * FRACUNIT), mapobjectscale));
}
#endif
if (flip)
{
x1 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_xscale);
#ifdef ROTSPRITE
spr_offset -= visoffs.x;
#endif
x1 = (FIXED_TO_FLOAT((spr_width - spr_offset)) * this_xscale);
x2 = (FIXED_TO_FLOAT(spr_offset) * this_xscale);
}
else
{
#ifdef ROTSPRITE
spr_offset += visoffs.x;
#endif
x1 = (FIXED_TO_FLOAT(spr_offset) * this_xscale);
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_xscale);
}
// test if too close
/*
if (papersprite)

View file

@ -1674,14 +1674,23 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.angley = FIXED_TO_FLOAT(anglef);
}
angle_t pitchR, rollR, fixedAngY;
pitchR = 0;
rollR = 0;
fixedAngY = 0;
{
fixed_t anglef = AngleFixed(R_ModelRotationAngle(spr->mobj, NULL));
p.rollangle = 0.0f;
// make fixedAngY a disguised fixed_t first
fixedAngY = FLOAT_TO_FIXED(p.angley);
if (anglef)
{
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
fixed_t camAngleDiff = AngleFixed(viewangle) - (fixed_t)(fixedAngY); // dumb reconversion back, I know
p.rollangle = FIXED_TO_FLOAT(anglef);
p.roll = true;
@ -1691,9 +1700,19 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2);
// rotation axes relative to camera
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
pitchR = FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT);
rollR = FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT);
p.rollx = FIXED_TO_FLOAT((fixed_t)rollR);
p.rollz = FIXED_TO_FLOAT((fixed_t)pitchR);
// convert to angles
pitchR = FixedAngle((fixed_t)pitchR);
rollR = FixedAngle((fixed_t)rollR);
}
// make this a proper angle now
fixedAngY = FixedAngle(fixedAngY);
}
p.anglez = FIXED_TO_FLOAT(AngleFixed(R_InterpolateAngle(spr->mobj->old_pitch, spr->mobj->pitch)));
@ -1717,6 +1736,88 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.y += ox * gl_viewcos;
p.z += oy;
if (R_ThingIsUsingBakedOffsets(spr->mobj))
{
// visoffset stuff
float xx, xy, yx, yy;
float zx, zy, zz;
float xpiv, ypiv, zpiv;
fixed_t zh;
fixed_t xoffs, yoffs;
// xoffs = (cos(xoff) + sin(yoff))
xoffs =
FixedMul(spr->mobj->bakeyoff, -FINECOSINE(fixedAngY >> ANGLETOFINESHIFT)) +
FixedMul(spr->mobj->bakexoff, FINESINE(fixedAngY >> ANGLETOFINESHIFT));
// yoffs = (-sin(xoff) + cos(yoff))
yoffs =
FixedMul(spr->mobj->bakeyoff, -FINESINE(fixedAngY >> ANGLETOFINESHIFT)) +
FixedMul(spr->mobj->bakexoff, FINECOSINE(fixedAngY >> ANGLETOFINESHIFT));
const fixed_t hflipmul = hflip ? -FRACUNIT : FRACUNIT;
xpiv = FIXED_TO_FLOAT(
FixedMul(
FixedMul(spr->mobj->bakeypiv,
-FINECOSINE(fixedAngY >> ANGLETOFINESHIFT)) +
FixedMul(spr->mobj->bakexpiv,
FINESINE(fixedAngY >> ANGLETOFINESHIFT)),
hflipmul));
ypiv = FIXED_TO_FLOAT(
FixedMul(
FixedMul(spr->mobj->bakeypiv,
-FINESINE(fixedAngY >> ANGLETOFINESHIFT)) +
FixedMul(spr->mobj->bakexpiv,
FINECOSINE(fixedAngY >> ANGLETOFINESHIFT)),
hflipmul));
zpiv = FIXED_TO_FLOAT(spr->mobj->bakezpiv * ((flip) ? -1 : 1));
pitchR = ((pitchR + spr->mobj->pitch) * ((flip) ? -1 : 1));
rollR = ((rollR + spr->mobj->roll) * ((flip) ? -1 : 1));
// x offset
xx = FIXED_TO_FLOAT(FixedMul(FixedMul(
FixedMul(xoffs,spr->mobj->spritexscale),
hflipmul),
FINECOSINE(pitchR >> ANGLETOFINESHIFT)
));
xy = FIXED_TO_FLOAT(FixedMul(FixedMul(
FixedMul(xoffs,spr->mobj->spritexscale),
hflipmul),
-FINESINE(pitchR >> ANGLETOFINESHIFT)
));
// y offset
yx = FIXED_TO_FLOAT(FixedMul(FixedMul(
FixedMul(yoffs,spr->mobj->spritexscale),
hflipmul),
FINECOSINE(rollR >> ANGLETOFINESHIFT)
));
yy = FIXED_TO_FLOAT(FixedMul(FixedMul(
FixedMul(yoffs,spr->mobj->spritexscale),
hflipmul),
-FINESINE(rollR >> ANGLETOFINESHIFT)
));
// z offset
zh = FixedMul(FixedMul(spr->mobj->bakezoff,spr->mobj->spriteyscale),
FINECOSINE(rollR >> ANGLETOFINESHIFT));
zz = FIXED_TO_FLOAT(FixedMul(zh,
FINECOSINE(pitchR >> ANGLETOFINESHIFT)));
zx = FIXED_TO_FLOAT(FixedMul(zh,
FINESINE(pitchR >> ANGLETOFINESHIFT)));
zy = FIXED_TO_FLOAT(FixedMul(zh,
FINESINE(rollR >> ANGLETOFINESHIFT)));
// do these namings even make sense at this point?
p.x += xx + zx + xpiv;
p.z += (xy + yy + zz * (flip ? -1 : 1)) + zpiv;
p.y += yx + zy + ypiv;
}
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
}
}

View file

@ -8514,6 +8514,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->mo->spritexoffset = 0;
player->mo->spriteyoffset = 0;
player->mo->bakexoff = 0;
player->mo->bakeyoff = 0;
player->mo->bakezoff = 0;
player->mo->bakexpiv = 0;
player->mo->bakeypiv = 0;
player->mo->bakezpiv = 0;
player->cameraOffset = 0;
player->pflags &= ~(PF_CASTSHADOW);

View file

@ -101,6 +101,12 @@ enum mobj_e {
mobj_sprxoff,
mobj_spryoff,
mobj_sprzoff,
mobj_bakexoff,
mobj_bakeyoff,
mobj_bakezoff,
mobj_bakexpiv,
mobj_bakeypiv,
mobj_bakezpiv,
mobj_terrain,
mobj_hitlag,
mobj_waterskip,
@ -192,6 +198,12 @@ static const char *const mobj_opt[] = {
"sprxoff",
"spryoff",
"sprzoff",
"bakexoff",
"bakeyoff",
"bakezoff",
"bakexpiv",
"bakeypiv",
"bakezpiv",
"terrain",
"hitlag",
"waterskip",
@ -481,6 +493,23 @@ static int mobj_get(lua_State *L)
case mobj_sprzoff:
lua_pushfixed(L, mo->sprzoff);
break;
case mobj_bakexoff:
lua_pushfixed(L, mo->bakexoff);
break;
case mobj_bakeyoff:
lua_pushfixed(L, mo->bakeyoff);
break;
case mobj_bakezoff:
lua_pushfixed(L, mo->bakezoff);
break;
case mobj_bakexpiv:
lua_pushfixed(L, mo->bakexpiv);
break;
case mobj_bakeypiv:
lua_pushfixed(L, mo->bakeypiv);
break;
case mobj_bakezpiv:
lua_pushfixed(L, mo->bakezpiv);
case mobj_terrain:
LUA_PushUserdata(L, mo->terrain, META_TERRAIN);
break;
@ -899,6 +928,23 @@ static int mobj_set(lua_State *L)
case mobj_sprzoff:
mo->sprzoff = luaL_checkfixed(L, 3);
break;
case mobj_bakexoff:
mo->bakexoff = luaL_checkfixed(L, 3);
break;
case mobj_bakeyoff:
mo->bakeyoff = luaL_checkfixed(L, 3);
break;
case mobj_bakezoff:
mo->bakezoff = luaL_checkfixed(L, 3);
break;
case mobj_bakexpiv:
mo->bakexpiv = luaL_checkfixed(L, 3);
break;
case mobj_bakeypiv:
mo->bakeypiv = luaL_checkfixed(L, 3);
break;
case mobj_bakezpiv:
mo->bakezpiv = luaL_checkfixed(L, 3);
case mobj_terrain:
mo->terrain = *((terrain_t **)luaL_checkudata(L, 3, META_TERRAIN));
break;

View file

@ -207,6 +207,13 @@ struct Mobj : mobj_t
FIXED_METHOD(spryoff)
FIXED_METHOD(sprzoff)
FIXED_METHOD(bakexoff)
FIXED_METHOD(bakeyoff)
FIXED_METHOD(bakezoff)
FIXED_METHOD(bakexpiv)
FIXED_METHOD(bakeypiv)
FIXED_METHOD(bakezpiv)
vec2 spritescale() const { return {spritexscale(), spriteyscale()}; }
void spritescale(const vec2& v)
{

View file

@ -276,6 +276,7 @@ void P_RunOverlays(void);
#define OV_DONT3DOFFSET 1<<1
#define OV_DONTXYSCALE 1<<2
#define OV_DONTROLL 1<<3
#define OV_DONTBAKEOFFSET 1<<4
void P_HandleMinecartSegments(mobj_t *mobj);
void P_MobjThinker(mobj_t *mobj);

View file

@ -5442,6 +5442,18 @@ void P_RunOverlays(void)
mo->roll = mo->target->roll;
}
if (!(mo->threshold & OV_DONTBAKEOFFSET))
{
// offsets
mo->bakexoff = mo->target->bakexoff;
mo->bakeyoff = mo->target->bakeyoff;
mo->bakezoff = mo->target->bakezoff;
// pivots
mo->bakexpiv = mo->target->bakexpiv;
mo->bakeypiv = mo->target->bakeypiv;
mo->bakezpiv = mo->target->bakezpiv;
}
mo->hitlag = mo->target->hitlag;
mo->eflags = (mo->eflags & ~MFE_DAMAGEHITLAG) | (mo->target->eflags & MFE_DAMAGEHITLAG);

View file

@ -420,6 +420,8 @@ struct mobj_t
UINT8 shadowcolor; // Palette index to use for rendering the shadow
fixed_t sprxoff, spryoff, sprzoff; // Sprite offsets in real space, does NOT affect position or collision
fixed_t bakexoff, bakeyoff, bakezoff; // BAKED sprite offsets. Simulates visuals in real space, and rotates along the object's sprite
fixed_t bakexpiv, bakeypiv, bakezpiv; // Pivot points for baked offsets. These are *not* rotated with a sprite
terrain_t *terrain; // Terrain definition of the floor this object last hit. NULL when in the air.
mobj_t *terrainOverlay; // Overlay sprite object for terrain

View file

@ -2884,6 +2884,7 @@ typedef enum
MD3_REAPPEAR = 1<<1,
MD3_PUNT_REF = 1<<2,
MD3_OWNER = 1<<3,
MD3_BAKEDOFFSET = 1<<4,
} mobj_diff3_t;
typedef enum
@ -3210,6 +3211,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff3 |= MD3_PUNT_REF;
if (mobj->owner)
diff3 |= MD3_OWNER;
if (mobj->bakexoff || mobj->bakeyoff || mobj->bakezoff || mobj->bakexpiv ||
mobj->bakeypiv || mobj->bakezpiv)
diff3 |= MD3_BAKEDOFFSET;
if (diff3 != 0)
diff2 |= MD2_MORE;
@ -3502,6 +3506,15 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
{
WRITEUINT32(save->p, mobj->owner->mobjnum);
}
if (diff3 & MD3_BAKEDOFFSET)
{
WRITEFIXED(save->p, mobj->bakexoff);
WRITEFIXED(save->p, mobj->bakeyoff);
WRITEFIXED(save->p, mobj->bakezoff);
WRITEFIXED(save->p, mobj->bakexpiv);
WRITEFIXED(save->p, mobj->bakeypiv);
WRITEFIXED(save->p, mobj->bakezpiv);
}
WRITEUINT32(save->p, mobj->mobjnum);
}
@ -4788,6 +4801,20 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
{
mobj->owner = (mobj_t *)(size_t)READUINT32(save->p);
}
if (diff3 & MD3_BAKEDOFFSET)
{
mobj->bakexoff = READFIXED(save->p);
mobj->bakeyoff = READFIXED(save->p);
mobj->bakezoff = READFIXED(save->p);
mobj->bakexpiv = READFIXED(save->p);
mobj->bakeypiv = READFIXED(save->p);
mobj->bakezpiv = READFIXED(save->p);
}
else
{
mobj->bakexoff = mobj->bakeyoff = mobj->bakezoff = 0;
mobj->bakexpiv = mobj->bakeypiv = mobj->bakezpiv = 0;
}
// link tid set earlier
P_AddThingTID(mobj);

View file

@ -1098,6 +1098,15 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->sprxoff = mobj->sprxoff;
ghost->spryoff = mobj->spryoff;
ghost->sprzoff = mobj->sprzoff;
// baked offsets
ghost->bakexoff = mobj->bakexoff;
ghost->bakeyoff = mobj->bakeyoff;
ghost->bakezoff = mobj->bakezoff;
ghost->bakexpiv = mobj->bakexpiv;
ghost->bakeypiv = mobj->bakeypiv;
ghost->bakezpiv = mobj->bakezpiv;
ghost->rollangle = mobj->rollangle;
ghost->spritexscale = mobj->spritexscale;

View file

@ -52,6 +52,11 @@ INT32 R_GetRollAngle(angle_t rollangle);
angle_t R_GetPitchRollAngle(mobj_t *mobj, player_t *viewPlayer);
angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer);
angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer);
vector2_t* R_RotateSpriteOffsetsByPitchRoll(
mobj_t* mobj,
boolean vflip,
boolean hflip,
vector2_t* out);
#endif
#ifdef __cplusplus

View file

@ -105,6 +105,98 @@ INT32 R_GetRollAngle(angle_t rollangle)
return ra;
}
#define VISROTMUL (ANG1 * ROTANGDIFF)
vector2_t* R_RotateSpriteOffsetsByPitchRoll(
mobj_t* mobj,
boolean vflip,
boolean hflip,
vector2_t* out)
{
fixed_t rotcos, rotsin, finx, finy;
vector2_t xvec, yvec;
// input offsets
fixed_t xoffs, yoffs, xpiv, ypiv;
// final offsets
INT16 visx, visy, visz;
INT16 vxpiv, vypiv;
// visual rotation
angle_t visrollang;
// camera angle
angle_t viewingAngle = R_PointToAngle(mobj->x, mobj->y);
// rotate ourselves entirely by the sprite's own rotation angle
angle_t visrot = R_SpriteRotationAngle(mobj, NULL);
// xoffs = (-cos(xoff) + sin(yoff))
xoffs =
FixedMul(mobj->bakeyoff, -FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)) +
FixedMul(mobj->bakexoff, FINESINE(mobj->angle >> ANGLETOFINESHIFT));
xpiv =
FixedMul(mobj->bakeypiv, -FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)) +
FixedMul(mobj->bakexpiv, FINESINE(mobj->angle >> ANGLETOFINESHIFT));
// yoffs = (-sin(yoff) + cos(xoff))
yoffs =
FixedMul(mobj->bakeyoff, -FINESINE(mobj->angle >> ANGLETOFINESHIFT)) +
FixedMul(mobj->bakexoff, FINECOSINE(mobj->angle >> ANGLETOFINESHIFT));
ypiv =
FixedMul(mobj->bakeypiv, -FINESINE(mobj->angle >> ANGLETOFINESHIFT)) +
FixedMul(mobj->bakexpiv, FINECOSINE(mobj->angle >> ANGLETOFINESHIFT));
visrollang = (R_GetRollAngle(visrot) * VISROTMUL) * (hflip ? -1 : 1);
// get pitch and roll multipliers, mainly used to align the
// viewpoint with the camera
fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT);
fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT);
// get visual positions
visz = visy = visx = 0;
visz = (INT16)(-(mobj->bakezoff / FRACUNIT));
visx = (INT16)(FixedMul((yoffs / FRACUNIT), rollMul));
visy = (INT16)(FixedMul((xoffs / FRACUNIT), pitchMul));
vxpiv = (INT16)(FixedMul((ypiv / FRACUNIT), rollMul));
vypiv = (INT16)(FixedMul((xpiv / FRACUNIT), pitchMul));
// rotate by rollangle
finx = (visx + visy);
finy = -visz;
rotcos = FINECOSINE(visrollang >> ANGLETOFINESHIFT);
rotsin = FINESINE(visrollang >> ANGLETOFINESHIFT);
xvec.x = FixedMul(finx, rotcos);
xvec.y = FixedMul(finx, -rotsin);
yvec.x = FixedMul(finy, rotsin);
yvec.y = FixedMul(finy, -rotcos);
// set finalized offsets
out->x = (fixed_t)(xvec.x + yvec.x + vxpiv + vypiv);
out->y = (fixed_t)(xvec.y - yvec.y) + (mobj->bakezpiv / FRACUNIT);
// flip based on vflip and hflip
// flip the view angle if we're horizontally flipped
if (hflip)
{
out->x *= -1;
}
if (vflip)
{
out->y *= -1;
}
return out;
}
#undef VISROTMUL
patch_t *Patch_GetRotated(patch_t *patch, INT32 angle, boolean flip)
{
rotsprite_t *rotsprite = patch->rotated;

View file

@ -834,6 +834,12 @@ boolean R_ThingIsFlashing(mobj_t *thing)
baddie_is_flashing(thing);
}
boolean R_ThingIsUsingBakedOffsets(mobj_t* thing)
{
return ((thing->bakexoff) || (thing->bakeyoff) || (thing->bakezoff) ||
(thing->bakexpiv) || (thing->bakeypiv) || (thing->bakezpiv));
}
UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
{
if (vis->cut & SC_PRECIP)
@ -1777,6 +1783,7 @@ static void R_ProjectSprite(mobj_t *thing)
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
angle_t spriterotangle = 0;
vector2_t visoffs;
#endif
// uncapped/interpolation
@ -1987,10 +1994,31 @@ static void R_ProjectSprite(mobj_t *thing)
if (spritexscale < 1 || spriteyscale < 1)
return;
#ifdef ROTSPRITE
// initialize and rotate pitch/roll vector
visoffs.x = 0;
visoffs.y = 0;
const fixed_t visoffymul = (vflip ? -FRACUNIT : FRACUNIT);
if (R_ThingIsUsingBakedOffsets(thing))
{
R_RotateSpriteOffsetsByPitchRoll(thing,
vflip,
hflip,
&visoffs);
}
#endif
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
{
spr_offset = interp.spritexoffset;
#ifdef ROTSPRITE
spr_topoffset = (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
mapobjectscale));
#else
spr_topoffset = interp.spriteyoffset;
#endif
}
else
{
@ -1999,8 +2027,14 @@ static void R_ProjectSprite(mobj_t *thing)
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
flipoffset = -1;
spr_offset += interp.spritexoffset * flipoffset;
spr_offset += (interp.spritexoffset) * flipoffset;
#ifdef ROTSPRITE
spr_topoffset += (interp.spriteyoffset + FixedDiv((visoffs.y * visoffymul),
mapobjectscale))
* flipoffset;
#else
spr_topoffset += interp.spriteyoffset * flipoffset;
#endif
}
if (flip)
@ -2008,6 +2042,13 @@ static void R_ProjectSprite(mobj_t *thing)
else
offset = -spr_offset;
#ifdef ROTSPRITE
if (visoffs.x)
{
offset -= FixedDiv((visoffs.x * FRACUNIT), mapobjectscale);
}
#endif
offset = FixedMul(offset, FixedMul(spritexscale, this_scale));
offset2 = FixedMul(spr_width, FixedMul(spritexscale, this_scale));

View file

@ -96,6 +96,8 @@ boolean R_ThingModelUsesDirectionalLighting(mobj_t *thing);
boolean R_ThingIsFlashing(mobj_t *thing);
boolean R_ThingIsUsingBakedOffsets(mobj_t *thing);
INT32 R_ThingLightLevel(mobj_t *thing);
boolean R_SplatSlope(mobj_t *thing, vector3_t position, pslope_t *slope);
boolean R_CustomShadowZ(mobj_t *thing, fixed_t *return_z, pslope_t **return_slope);