Merge branch 'models-plus-final' into 'next'

3D models support for spritexoffset, spriteyoffset, spritexscale, spriteyscale, parity with sprite rollangle

See merge request STJr/SRB2!1840
This commit is contained in:
Nev3r 2023-07-24 12:46:10 +00:00
commit 022ddcf363
26 changed files with 210 additions and 151 deletions

View file

@ -912,7 +912,7 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame)
else if (fastcmp(word, "YPIVOT"))
sprinfo->pivot[frame].y = value;
else if (fastcmp(word, "ROTAXIS"))
sprinfo->pivot[frame].rotaxis = value;
deh_warning("SpriteInfo: ROTAXIS is deprecated and will be removed.");
else
{
f->curpos = lastline;

View file

@ -93,33 +93,22 @@ typedef struct FVector
//Hurdler: Transform (coords + angles)
//BP: transform order : scale(rotation_x(rotation_y(translation(v))))
// Kart features
//#define USE_FTRANSFORM_ANGLEZ
//#define USE_FTRANSFORM_MIRROR
// Vanilla features
#define USE_MODEL_NEXTFRAME
typedef struct
{
FLOAT x,y,z; // position
#ifdef USE_FTRANSFORM_ANGLEZ
FLOAT anglex,angley,anglez; // aimingangle / viewangle
#else
FLOAT anglex,angley; // aimingangle / viewangle
#endif
FLOAT scalex,scaley,scalez;
FLOAT fovxangle, fovyangle;
UINT8 splitscreen;
boolean flip; // screenflip
boolean roll;
SINT8 rollflip;
FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ
UINT8 rotaxis;
FLOAT centerx, centery;
#ifdef USE_FTRANSFORM_MIRROR
FLOAT rollx, rollz;
boolean mirror; // SRB2Kart: Encore Mode
#endif
boolean shearing; // 14042019
float viewaiming; // 17052019
} FTransform;

View file

@ -51,7 +51,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
//Hurdler: added for new development
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
@ -136,4 +136,3 @@ extern struct hwdriver_s hwdriver;
#endif //not defined _CREATE_DLL_
#endif //__HWR_DRV_H__

View file

@ -140,7 +140,7 @@ static fixed_t dup_viewx, dup_viewy, dup_viewz;
static angle_t dup_viewangle;
static float gl_viewx, gl_viewy, gl_viewz;
static float gl_viewsin, gl_viewcos;
float gl_viewsin, gl_viewcos;
// Maybe not necessary with the new T&L code (needs to be checked!)
static float gl_viewludsin, gl_viewludcos; // look up down kik test
@ -4158,7 +4158,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
angle = viewangle;
if (!spr->rotated)
angle += spr->mobj->rollangle;
angle += spr->mobj->spriteroll;
angle = -angle;
angle += ANGLE_90;
@ -5078,6 +5078,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
angle_t spriterotangle = 0;
#endif
// uncapped/interpolation
@ -5245,18 +5246,21 @@ static void HWR_ProjectSprite(mobj_t *thing)
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
#ifdef ROTSPRITE
if (thing->rollangle
spriterotangle = R_SpriteRotationAngle(&interp);
if (spriterotangle != 0
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
{
if (papersprite)
{
// a positive rollangle should should pitch papersprites upwards relative to their facing angle
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
rollangle = R_GetRollAngle(InvAngle(spriterotangle));
}
else
{
rollangle = R_GetRollAngle(thing->rollangle);
rollangle = R_GetRollAngle(spriterotangle);
}
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
if (rotsprite != NULL)
@ -5913,6 +5917,8 @@ static void HWR_DrawSkyBackground(player_t *player)
fixed_t rol = AngleFixed(player->viewrollangle);
dometransform.rollangle = FIXED_TO_FLOAT(rol);
dometransform.roll = true;
dometransform.rollx = 1.0f;
dometransform.rollz = 0.0f;
}
dometransform.splitscreen = splitscreen;
@ -6191,6 +6197,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
fixed_t rol = AngleFixed(player->viewrollangle);
atransform.rollangle = FIXED_TO_FLOAT(rol);
atransform.roll = true;
atransform.rollx = 1.0f;
atransform.rollz = 0.0f;
}
atransform.splitscreen = splitscreen;
@ -6405,6 +6413,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
fixed_t rol = AngleFixed(player->viewrollangle);
atransform.rollangle = FIXED_TO_FLOAT(rol);
atransform.roll = true;
atransform.rollx = 1.0f;
atransform.rollz = 0.0f;
}
atransform.splitscreen = splitscreen;

View file

@ -115,6 +115,7 @@ extern float gl_viewwindowx, gl_basewindowcentery;
// BP: big hack for a test in lighting ref : 1249753487AB
extern fixed_t *hwbbox;
extern FTransform atransform;
extern float gl_viewsin, gl_viewcos;
// Render stats

View file

@ -1346,10 +1346,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
const UINT8 hflip = (UINT8)(!(spr->mobj->mirrored) != !R_ThingHorizontallyFlipped(spr->mobj));
spritedef_t *sprdef;
spriteframe_t *sprframe;
spriteinfo_t *sprinfo;
angle_t ang;
INT32 mod;
float finalscale;
interpmobjstate_t interp;
if (R_UsingFrameInterpolation() && !paused)
@ -1388,12 +1385,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
{
md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins];
md2->skin = (skin_t*)spr->mobj->skin-skins;
sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2];
}
else
{
md2 = &md2_models[spr->mobj->sprite];
sprinfo = &spriteinfo[spr->mobj->sprite];
}
// texture loading before model init, so it knows if sprite graphics are used, which
@ -1455,7 +1450,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
}
//HWD.pfnSetBlend(blend); // This seems to actually break translucency?
finalscale = md2->scale;
//Hurdler: arf, I don't like that implementation at all... too much crappy
if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
@ -1614,61 +1608,56 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
p.angley = FIXED_TO_FLOAT(anglef);
}
p.rollangle = 0.0f;
p.rollflip = 1;
p.rotaxis = 0;
if (spr->mobj->rollangle)
{
fixed_t anglef = AngleFixed(spr->mobj->rollangle);
fixed_t anglef = AngleFixed(R_ModelRotationAngle(&interp));
p.rollangle = 0.0f;
if (anglef)
{
fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know
p.rollangle = FIXED_TO_FLOAT(anglef);
p.roll = true;
// rotation pivot
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius/2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height/(flip ? -2 : 2));
p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2);
p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2);
// rotation axis
if (sprinfo->available)
p.rotaxis = (UINT8)(sprinfo->pivot[(spr->mobj->frame & FF_FRAMEMASK)].rotaxis);
// for NiGHTS specifically but should work everywhere else
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
p.rollflip = 1;
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
p.rollflip = -1;
if (flip)
p.rollflip *= -1;
// rotation axes relative to camera
p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT));
}
}
p.anglex = 0.0f;
#ifdef USE_FTRANSFORM_ANGLEZ
// Slope rotation from Kart
p.anglez = 0.0f;
if (spr->mobj->standingslope)
{
fixed_t tempz = spr->mobj->standingslope->normal.z;
fixed_t tempy = spr->mobj->standingslope->normal.y;
fixed_t tempx = spr->mobj->standingslope->normal.x;
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
p.anglez = FIXED_TO_FLOAT(tempangle);
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
p.anglex = FIXED_TO_FLOAT(tempangle);
}
#if 0
p.anglez = FIXED_TO_FLOAT(AngleFixed(interp.pitch));
p.anglex = FIXED_TO_FLOAT(AngleFixed(interp.roll));
#else
p.anglez = 0.f;
p.anglex = 0.f;
#endif
// SRB2CBTODO: MD2 scaling support
finalscale *= FIXED_TO_FLOAT(interp.scale);
p.flip = atransform.flip;
#ifdef USE_FTRANSFORM_MIRROR
p.mirror = atransform.mirror; // from Kart
#endif
p.mirror = atransform.mirror;
HWD.pfnSetShader(SHADER_MODEL); // model shader
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf);
{
float this_scale = FIXED_TO_FLOAT(interp.scale);
float xs = this_scale * FIXED_TO_FLOAT(interp.spritexscale);
float ys = this_scale * FIXED_TO_FLOAT(interp.spriteyscale);
float ox = xs * FIXED_TO_FLOAT(interp.spritexoffset);
float oy = ys * FIXED_TO_FLOAT(interp.spriteyoffset);
// offset perpendicular to the camera angle
p.x -= ox * gl_viewsin;
p.y += ox * gl_viewcos;
p.z += oy;
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, md2->scale * xs, md2->scale * ys, flip, hflip, &Surf);
}
}
return true;

View file

@ -2679,7 +2679,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
#define BUFFER_OFFSET(i) ((void*)(i))
static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
{
static GLRGBAFloat poly = {0,0,0,0};
static GLRGBAFloat tint = {0,0,0,0};
@ -2703,10 +2703,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
#endif
// Affect input model scaling
scale *= 0.5f;
scalex = scale;
scaley = scale;
scalez = scale;
hscale *= 0.5f;
vscale *= 0.5f;
scalex = hscale;
scaley = vscale;
scalez = hscale;
if (duration > 0.0 && tics >= 0.0) // don't interpolate if instantaneous or infinite in length
{
@ -2782,7 +2783,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
pglEnable(GL_CULL_FACE);
pglEnable(GL_NORMALIZE);
#ifdef USE_FTRANSFORM_MIRROR
// flipped is if the object is vertically flipped
// hflipped is if the object is horizontally flipped
// pos->flip is if the screen is flipped vertically
@ -2795,17 +2795,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
else
pglCullFace(GL_BACK);
}
#else
// pos->flip is if the screen is flipped too
if (flipped ^ hflipped ^ pos->flip) // If one or three of these are active, but not two, invert the model's culling
{
pglCullFace(GL_FRONT);
}
else
{
pglCullFace(GL_BACK);
}
#endif
pglPushMatrix(); // should be the same as glLoadIdentity
//Hurdler: now it seems to work
@ -2815,22 +2804,14 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
if (hflipped)
scalez = -scalez;
#ifdef USE_FTRANSFORM_ANGLEZ
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f); // rotate by slope from Kart
#endif
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
pglRotatef(pos->anglez, 0.0f, 0.0f, -1.0f);
pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f);
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
if (pos->roll)
{
float roll = (1.0f * pos->rollflip);
pglTranslatef(pos->centerx, pos->centery, 0);
if (pos->rotaxis == 2) // Z
pglRotatef(pos->rollangle, 0.0f, 0.0f, roll);
else if (pos->rotaxis == 1) // Y
pglRotatef(pos->rollangle, 0.0f, roll, 0.0f);
else // X
pglRotatef(pos->rollangle, roll, 0.0f, 0.0f);
pglRotatef(pos->rollangle, pos->rollx, 0.0f, pos->rollz);
pglTranslatef(-pos->centerx, -pos->centery, 0);
}
@ -2984,9 +2965,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
// -----------------+
// HWRAPI DrawModel : Draw a model
// -----------------+
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface)
{
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface);
DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface);
}
// -----------------+
@ -3003,13 +2984,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
if (stransform)
{
used_fov = stransform->fovxangle;
#ifdef USE_FTRANSFORM_MIRROR
// mirroring from Kart
if (stransform->mirror)
pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez);
else
#endif
if (stransform->flip)
else if (stransform->flip)
pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez);
else
pglScalef(stransform->scalex, stransform->scaley, -stransform->scalez);

View file

@ -319,7 +319,7 @@ static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, in
else if (ikey == 2 || (key && fastcmp(key, "y")))
pivot[idx].y = (INT32)value;
else if (ikey == 3 || (key && fastcmp(key, "rotaxis")))
pivot[idx].rotaxis = (UINT8)value;
LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed.")
else if (ikey == -1 && (key != NULL))
FIELDERROR("pivot key", va("invalid option %s", key));
okcool = 1;
@ -576,7 +576,10 @@ static int framepivot_get(lua_State *L)
else if (fastcmp("y", field))
lua_pushinteger(L, framepivot->y);
else if (fastcmp("rotaxis", field))
lua_pushinteger(L, (UINT8)framepivot->rotaxis);
{
LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed.");
lua_pushinteger(L, 0);
}
else
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));
@ -602,7 +605,7 @@ static int framepivot_set(lua_State *L)
else if (fastcmp("y", field))
framepivot->y = luaL_checkinteger(L, 3);
else if (fastcmp("rotaxis", field))
framepivot->rotaxis = luaL_checkinteger(L, 3);
LUA_UsageWarning(L, "\"rotaxis\" is deprecated and will be removed.")
else
return luaL_error(L, va("Field %s does not exist in spriteframepivot_t", field));

View file

@ -33,7 +33,8 @@ enum mobj_e {
mobj_angle,
mobj_pitch,
mobj_roll,
mobj_rollangle,
mobj_spriteroll,
mobj_rollangle, // backwards compat
mobj_sprite,
mobj_frame,
mobj_sprite2,
@ -110,7 +111,8 @@ static const char *const mobj_opt[] = {
"angle",
"pitch",
"roll",
"rollangle",
"spriteroll",
"rollangle", // backwards compat
"sprite",
"frame",
"sprite2",
@ -229,8 +231,9 @@ static int mobj_get(lua_State *L)
case mobj_roll:
lua_pushangle(L, mo->roll);
break;
case mobj_rollangle:
lua_pushangle(L, mo->rollangle);
case mobj_spriteroll:
case mobj_rollangle: // backwards compat
lua_pushangle(L, mo->spriteroll);
break;
case mobj_sprite:
lua_pushinteger(L, mo->sprite);
@ -518,8 +521,9 @@ static int mobj_set(lua_State *L)
case mobj_roll:
mo->roll = luaL_checkangle(L, 3);
break;
case mobj_rollangle:
mo->rollangle = luaL_checkangle(L, 3);
case mobj_spriteroll:
case mobj_rollangle: // backwards compat
mo->spriteroll = luaL_checkangle(L, 3);
break;
case mobj_sprite:
mo->sprite = luaL_checkinteger(L, 3);

View file

@ -8738,10 +8738,10 @@ void A_RollAngle(mobj_t *actor)
// relative (default)
if (!locvar2)
actor->rollangle += angle;
actor->spriteroll += angle;
// absolute
else
actor->rollangle = angle;
actor->spriteroll = angle;
}
// Function: A_ChangeRollAngleRelative
@ -8766,7 +8766,7 @@ void A_ChangeRollAngleRelative(mobj_t *actor)
I_Error("A_ChangeRollAngleRelative: var1 is greater than var2");
#endif
actor->rollangle += FixedAngle(P_RandomRange(amin, amax));
actor->spriteroll += FixedAngle(P_RandomRange(amin, amax));
}
// Function: A_ChangeRollAngleAbsolute
@ -8791,7 +8791,7 @@ void A_ChangeRollAngleAbsolute(mobj_t *actor)
I_Error("A_ChangeRollAngleAbsolute: var1 is greater than var2");
#endif
actor->rollangle = FixedAngle(P_RandomRange(amin, amax));
actor->spriteroll = FixedAngle(P_RandomRange(amin, amax));
}
// Function: A_PlaySound

View file

@ -3117,7 +3117,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN);
S_StartSound(target, sfx_nghurt);
player->mo->rollangle = 0;
player->mo->spriteroll = 0;
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)

View file

@ -537,5 +537,6 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move);
void P_DoSuperTransformation(player_t *player, boolean giverings);
void P_ExplodeMissile(mobj_t *mo);
void P_CheckGravity(mobj_t *mo, boolean affect);
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope);
#endif // __P_LOCAL__

View file

@ -2928,6 +2928,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->momz <= 0)
{
thing->standingslope = tmfloorslope;
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
P_PlayerHitFloor(thing->player, true);
}
@ -2939,6 +2941,8 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
if (thing->momz >= 0)
{
thing->standingslope = tmceilingslope;
P_SetPitchRollFromSlope(thing, thing->standingslope);
if (thing->momz == 0 && thing->player && !startingonground)
P_PlayerHitFloor(thing->player, true);
}

View file

@ -1551,6 +1551,31 @@ void P_CheckGravity(mobj_t *mo, boolean affect)
}
}
//
// P_SetPitchRollFromSlope
//
void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope)
{
#if 0
if (slope)
{
fixed_t tempz = slope->normal.z;
fixed_t tempy = slope->normal.y;
fixed_t tempx = slope->normal.x;
mo->pitch = R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx);
mo->roll = R_PointToAngle2(0, 0, tempz, tempy);
}
else
{
mo->pitch = mo->roll = 0;
}
#else
(void)mo;
(void)slope;
#endif
}
#define STOPSPEED (FRACUNIT)
//
@ -1985,6 +2010,7 @@ void P_XYMovement(mobj_t *mo)
// Now compare the Zs of the different quantizations
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
mo->standingslope = oldslope;
P_SetPitchRollFromSlope(mo, mo->standingslope);
P_SlopeLaunch(mo);
//CONS_Printf("launched off of slope - ");
@ -2557,6 +2583,7 @@ boolean P_ZMovement(mobj_t *mo)
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
{
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
P_SetPitchRollFromSlope(mo, mo->standingslope);
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
}
@ -9846,9 +9873,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
break;
case MT_MINUS:
if (P_IsObjectOnGround(mobj))
mobj->rollangle = 0;
mobj->spriteroll = 0;
else
mobj->rollangle = R_PointToAngle2(0, 0, P_MobjFlip(mobj)*mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1));
mobj->spriteroll = R_PointToAngle2(0, 0, P_MobjFlip(mobj)*mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1));
break;
case MT_PUSH:
P_PointPushThink(mobj);
@ -14145,6 +14172,13 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo
newmobj->old_angle = mobj->old_angle;
}
newmobj->old_pitch2 = mobj->old_pitch2;
newmobj->old_pitch = mobj->old_pitch;
newmobj->old_roll2 = mobj->old_roll2;
newmobj->old_roll = mobj->old_roll;
newmobj->old_spriteroll2 = mobj->old_spriteroll2;
newmobj->old_spriteroll = mobj->old_spriteroll;
newmobj->old_scale2 = mobj->old_scale2;
newmobj->old_scale = mobj->old_scale;
newmobj->old_spritexscale = mobj->old_spritexscale;

View file

@ -292,7 +292,7 @@ typedef struct mobj_s
angle_t angle, pitch, roll; // orientation
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
angle_t old_angle2, old_pitch2, old_roll2;
angle_t rollangle;
angle_t spriteroll, old_spriteroll, old_spriteroll2;
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT8 sprite2; // player sprites
@ -429,7 +429,7 @@ typedef struct precipmobj_s
angle_t angle, pitch, roll; // orientation
angle_t old_angle, old_pitch, old_roll; // orientation interpolation
angle_t old_angle2, old_pitch2, old_roll2;
angle_t rollangle;
angle_t spriteroll, old_spriteroll, old_spriteroll2;
spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT8 sprite2; // player sprites

View file

@ -1565,7 +1565,7 @@ typedef enum
MD2_SLOPE = 1<<11,
MD2_COLORIZED = 1<<12,
MD2_MIRRORED = 1<<13,
MD2_ROLLANGLE = 1<<14,
MD2_SPRITEROLL = 1<<14,
MD2_SHADOWSCALE = 1<<15,
MD2_RENDERFLAGS = 1<<16,
MD2_BLENDMODE = 1<<17,
@ -1783,8 +1783,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_COLORIZED;
if (mobj->mirrored)
diff2 |= MD2_MIRRORED;
if (mobj->rollangle)
diff2 |= MD2_ROLLANGLE;
if (mobj->spriteroll)
diff2 |= MD2_SPRITEROLL;
if (mobj->shadowscale)
diff2 |= MD2_SHADOWSCALE;
if (mobj->renderflags)
@ -1951,8 +1951,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT8(save_p, mobj->colorized);
if (diff2 & MD2_MIRRORED)
WRITEUINT8(save_p, mobj->mirrored);
if (diff2 & MD2_ROLLANGLE)
WRITEANGLE(save_p, mobj->rollangle);
if (diff2 & MD2_SPRITEROLL)
WRITEANGLE(save_p, mobj->spriteroll);
if (diff2 & MD2_SHADOWSCALE)
WRITEFIXED(save_p, mobj->shadowscale);
if (diff2 & MD2_RENDERFLAGS)
@ -3001,8 +3001,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->colorized = READUINT8(save_p);
if (diff2 & MD2_MIRRORED)
mobj->mirrored = READUINT8(save_p);
if (diff2 & MD2_ROLLANGLE)
mobj->rollangle = READANGLE(save_p);
if (diff2 & MD2_SPRITEROLL)
mobj->spriteroll = READANGLE(save_p);
if (diff2 & MD2_SHADOWSCALE)
mobj->shadowscale = READFIXED(save_p);
if (diff2 & MD2_RENDERFLAGS)

View file

@ -899,6 +899,8 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope
{
thing->standingslope = slope;
P_SetPitchRollFromSlope(thing, slope);
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
thing->momz = -P_MobjFlip(thing);
}
@ -915,6 +917,7 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
thing->momx = mom.x;
thing->momy = mom.y;
thing->standingslope = slope;
P_SetPitchRollFromSlope(thing, slope);
if (!thing->player || !(thing->player->pflags & PF_BOUNCING))
thing->momz = -P_MobjFlip(thing);
}

View file

@ -676,7 +676,7 @@ static void P_DeNightserizePlayer(player_t *player)
player->marebonuslap = 0;
player->flyangle = 0;
player->anotherflyangle = 0;
player->mo->rollangle = 0;
player->mo->spriteroll = 0;
P_SetTarget(&player->mo->target, NULL);
P_SetTarget(&player->axis1, P_SetTarget(&player->axis2, NULL));
@ -802,7 +802,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->secondjump = 0;
player->flyangle = 0;
player->anotherflyangle = 0;
player->mo->rollangle = 0;
player->mo->spriteroll = 0;
player->powers[pw_shield] = SH_NONE;
player->powers[pw_super] = 0;
@ -1976,7 +1976,9 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->colorized = mobj->colorized; // alternatively, "true" for sonic advance style colourisation
ghost->angle = (mobj->player ? mobj->player->drawangle : mobj->angle);
ghost->rollangle = mobj->rollangle;
ghost->roll = mobj->roll;
ghost->pitch = mobj->pitch;
ghost->spriteroll = mobj->spriteroll;
ghost->sprite = mobj->sprite;
ghost->sprite2 = mobj->sprite2;
@ -1995,6 +1997,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->fuse = ghost->info->damage;
ghost->skin = mobj->skin;
ghost->standingslope = mobj->standingslope;
if (mobj->flags2 & MF2_OBJECTFLIP)
ghost->flags |= MF2_OBJECTFLIP;
@ -2014,6 +2017,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->old_angle = (mobj->player ? mobj->player->old_drawangle2 : mobj->old_angle2);
ghost->old_pitch = mobj->old_pitch2;
ghost->old_roll = mobj->old_roll2;
ghost->old_spriteroll = mobj->old_spriteroll2;
return ghost;
}
@ -6790,9 +6794,9 @@ static void P_DoNiGHTSCapsule(player_t *player)
{
if ((player->mo->state == &states[S_PLAY_NIGHTS_PULL])
&& (player->mo->sprite2 == SPR2_NPUL))
player->mo->rollangle -= ANG30;
player->mo->spriteroll -= ANG30;
else
player->mo->rollangle = 0;
player->mo->spriteroll = 0;
}
if (G_IsSpecialStage(gamemap))
@ -7245,7 +7249,7 @@ static void P_NiGHTSMovement(player_t *player)
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
{
player->mo->momx = player->mo->momy = player->mo->momz = 0;
player->mo->rollangle = 0;
player->mo->spriteroll = 0;
return;
}
@ -7263,7 +7267,7 @@ static void P_NiGHTSMovement(player_t *player)
{
if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL])
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL);
player->mo->rollangle = ANGLE_90;
player->mo->spriteroll = ANGLE_90;
}
else
#endif
@ -7596,9 +7600,9 @@ static void P_NiGHTSMovement(player_t *player)
P_SetPlayerMobjState(player->mo, flystate);
if (player->charflags & SF_NONIGHTSROTATION)
player->mo->rollangle = 0;
player->mo->spriteroll = 0;
else
player->mo->rollangle = rollangle;
player->mo->spriteroll = rollangle;
P_SetPlayerAngle(player, player->mo->angle);

View file

@ -294,6 +294,9 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
out->scale = mobj->scale;
out->subsector = mobj->subsector;
out->angle = mobj->player ? mobj->player->drawangle : mobj->angle;
out->pitch = mobj->pitch;
out->roll = mobj->roll;
out->spriteroll = mobj->spriteroll;
out->spritexscale = mobj->spritexscale;
out->spriteyscale = mobj->spriteyscale;
out->spritexoffset = mobj->spritexoffset;
@ -323,6 +326,10 @@ void R_InterpolateMobjState(mobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
{
out->angle = mobj->resetinterp ? mobj->angle : R_LerpAngle(mobj->old_angle, mobj->angle, frac);
}
out->pitch = mobj->resetinterp ? mobj->pitch : R_LerpAngle(mobj->old_pitch, mobj->pitch, frac);
out->roll = mobj->resetinterp ? mobj->roll : R_LerpAngle(mobj->old_roll, mobj->roll, frac);
out->spriteroll = mobj->resetinterp ? mobj->spriteroll : R_LerpAngle(mobj->old_spriteroll, mobj->spriteroll, frac);
}
void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjstate_t *out)
@ -335,6 +342,9 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
out->scale = FRACUNIT;
out->subsector = mobj->subsector;
out->angle = mobj->angle;
out->pitch = mobj->angle;
out->roll = mobj->roll;
out->spriteroll = mobj->spriteroll;
out->spritexscale = mobj->spritexscale;
out->spriteyscale = mobj->spriteyscale;
out->spritexoffset = mobj->spritexoffset;
@ -354,6 +364,9 @@ void R_InterpolatePrecipMobjState(precipmobj_t *mobj, fixed_t frac, interpmobjst
out->subsector = R_PointInSubsector(out->x, out->y);
out->angle = R_LerpAngle(mobj->old_angle, mobj->angle, frac);
out->pitch = R_LerpAngle(mobj->old_pitch, mobj->pitch, frac);
out->roll = R_LerpAngle(mobj->old_roll, mobj->roll, frac);
out->spriteroll = R_LerpAngle(mobj->old_spriteroll, mobj->spriteroll, frac);
}
static void AddInterpolator(levelinterpolator_t* interpolator)
@ -766,6 +779,7 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
mobj->old_angle2 = mobj->old_angle;
mobj->old_pitch2 = mobj->old_pitch;
mobj->old_roll2 = mobj->old_roll;
mobj->old_spriteroll2 = mobj->old_spriteroll;
mobj->old_scale2 = mobj->old_scale;
mobj->old_x = mobj->x;
mobj->old_y = mobj->y;
@ -773,6 +787,7 @@ void R_ResetMobjInterpolationState(mobj_t *mobj)
mobj->old_angle = mobj->angle;
mobj->old_pitch = mobj->pitch;
mobj->old_roll = mobj->roll;
mobj->old_spriteroll = mobj->spriteroll;
mobj->old_scale = mobj->scale;
mobj->old_spritexscale = mobj->spritexscale;
mobj->old_spriteyscale = mobj->spriteyscale;
@ -801,10 +816,14 @@ void R_ResetPrecipitationMobjInterpolationState(precipmobj_t *mobj)
mobj->old_angle2 = mobj->old_angle;
mobj->old_pitch2 = mobj->old_pitch;
mobj->old_roll2 = mobj->old_roll;
mobj->old_spriteroll2 = mobj->old_spriteroll;
mobj->old_x = mobj->x;
mobj->old_y = mobj->y;
mobj->old_z = mobj->z;
mobj->old_angle = mobj->angle;
mobj->old_pitch = mobj->pitch;
mobj->old_roll = mobj->roll;
mobj->old_spriteroll = mobj->spriteroll;
mobj->old_spritexscale = mobj->spritexscale;
mobj->old_spriteyscale = mobj->spriteyscale;
mobj->old_spritexoffset = mobj->spritexoffset;

View file

@ -59,6 +59,9 @@ typedef struct {
fixed_t z;
subsector_t *subsector;
angle_t angle;
angle_t pitch;
angle_t roll;
angle_t spriteroll;
fixed_t scale;
fixed_t spritexscale;
fixed_t spriteyscale;

View file

@ -14,6 +14,7 @@
#include "r_defs.h"
#include "r_picformats.h"
#include "r_fps.h"
#include "doomdef.h"
// Patch functions
@ -38,6 +39,8 @@ patch_t *Patch_GetRotatedSprite(
size_t frame, size_t spriteangle,
boolean flip, boolean adjustfeet,
void *info, INT32 rotationangle);
angle_t R_ModelRotationAngle(interpmobjstate_t *interp);
angle_t R_SpriteRotationAngle(interpmobjstate_t *interp);
INT32 R_GetRollAngle(angle_t rollangle);
#endif

View file

@ -13,11 +13,33 @@
#include "r_things.h" // FEETADJUST
#include "z_zone.h"
#include "w_wad.h"
#include "r_main.h" // R_PointToAngle
#ifdef ROTSPRITE
fixed_t rollcosang[ROTANGLES];
fixed_t rollsinang[ROTANGLES];
angle_t R_ModelRotationAngle(interpmobjstate_t *interp)
{
return interp->spriteroll;
}
angle_t R_SpriteRotationAngle(interpmobjstate_t *interp)
{
#if 0
angle_t viewingAngle = R_PointToAngle(interp->x, interp->y);
fixed_t pitchMul = -FINESINE(viewingAngle >> ANGLETOFINESHIFT);
fixed_t rollMul = FINECOSINE(viewingAngle >> ANGLETOFINESHIFT);
angle_t rollOrPitch = FixedMul(interp->pitch, pitchMul) + FixedMul(interp->roll, rollMul);
return (rollOrPitch + R_ModelRotationAngle(interp));
#else
return R_ModelRotationAngle(interp);
#endif
}
INT32 R_GetRollAngle(angle_t rollangle)
{
INT32 ra = AngleFixed(rollangle)>>FRACBITS;

View file

@ -1407,7 +1407,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
UINT8 frameFrame = 0xFF;
INT16 frameXPivot = 0;
INT16 frameYPivot = 0;
rotaxis_t frameRotAxis = 0;
// Sprite identifier
sprinfoToken = M_GetToken(NULL);
@ -1458,12 +1457,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
{
Z_Free(sprinfoToken);
sprinfoToken = M_GetToken(NULL);
if ((stricmp(sprinfoToken, "X")==0) || (stricmp(sprinfoToken, "XAXIS")==0) || (stricmp(sprinfoToken, "ROLL")==0))
frameRotAxis = ROTAXIS_X;
else if ((stricmp(sprinfoToken, "Y")==0) || (stricmp(sprinfoToken, "YAXIS")==0) || (stricmp(sprinfoToken, "PITCH")==0))
frameRotAxis = ROTAXIS_Y;
else if ((stricmp(sprinfoToken, "Z")==0) || (stricmp(sprinfoToken, "ZAXIS")==0) || (stricmp(sprinfoToken, "YAW")==0))
frameRotAxis = ROTAXIS_Z;
}
Z_Free(sprinfoToken);
@ -1480,7 +1473,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info)
// set fields
info->pivot[frameFrame].x = frameXPivot;
info->pivot[frameFrame].y = frameYPivot;
info->pivot[frameFrame].rotaxis = frameRotAxis;
}
//

View file

@ -95,7 +95,6 @@ typedef enum
typedef struct
{
INT32 x, y;
rotaxis_t rotaxis;
} spriteframepivot_t;
typedef struct

View file

@ -191,7 +191,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
splatangle = spr->viewpoint.angle;
if (!(spr->cut & SC_ISROTATED))
splatangle += mobj->rollangle;
splatangle += mobj->spriteroll;
splat.angle = -splatangle;
splat.angle += ANGLE_90;

View file

@ -1594,6 +1594,7 @@ static void R_ProjectSprite(mobj_t *thing)
#ifdef ROTSPRITE
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
angle_t spriterotangle = 0;
#endif
// uncapped/interpolation
@ -1743,17 +1744,19 @@ static void R_ProjectSprite(mobj_t *thing)
patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE);
#ifdef ROTSPRITE
if (thing->rollangle
spriterotangle = R_SpriteRotationAngle(&interp);
if (spriterotangle != 0
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
{
if (papersprite && ang >= ANGLE_180)
{
// Makes Software act much more sane like OpenGL
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
rollangle = R_GetRollAngle(InvAngle(spriterotangle));
}
else
{
rollangle = R_GetRollAngle(thing->rollangle);
rollangle = R_GetRollAngle(spriterotangle);
}
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);