mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add baked offset parameters
This commit is contained in:
parent
0d9a67b8b5
commit
19fdf19eb4
16 changed files with 408 additions and 6 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
12
src/p_mobj.c
12
src/p_mobj.c
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue