Make affines respect SPRTINFO
"Things yama forgets about until the last minute"
This commit is contained in:
parent
de8f2e40da
commit
00a9e94161
3 changed files with 92 additions and 11 deletions
|
|
@ -4914,6 +4914,8 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
boolean affinesprite = ((thing->player != NULL) || R_ThingIsAffineSprite(thing));
|
||||
affine_t affine_transform = {0};
|
||||
vector2_t affine_scale = {0};
|
||||
f_vector2_t affine_pivotoffsetdiff = {0};
|
||||
|
||||
polyvertex_t affine_rootpoint = {0};
|
||||
f_vector2_t affine_point[4] = {0};
|
||||
float leftbound = 0, backbound = 0, topbound = 0;
|
||||
|
|
@ -5136,6 +5138,18 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (affinesprite)
|
||||
{
|
||||
vector2_t affine_pivot = {0};
|
||||
|
||||
vector2_t patch_defaultpivot = {.x = spr_offset, .y = (spr_height / 2)};
|
||||
|
||||
R_GetPivotVectorFromSpriteInfo(&affine_pivot,
|
||||
&patch_defaultpivot,
|
||||
sprinfo,
|
||||
(thing->frame & FF_FRAMEMASK));
|
||||
|
||||
affine_pivotoffsetdiff.x = FIXED_TO_FLOAT(affine_pivot.x - spr_offset);
|
||||
affine_pivotoffsetdiff.y = FIXED_TO_FLOAT(affine_pivot.y - spr_topoffset);
|
||||
|
||||
affine_scale.x = FLOAT_TO_FIXED(spritexscale * this_scale);
|
||||
affine_scale.y = FLOAT_TO_FIXED(spriteyscale * this_scale);
|
||||
|
||||
|
|
@ -5147,7 +5161,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
|
||||
const fixed_t rolloffs_x = FixedDiv(interptarg->rollingxoffset, highresscale) * (((thing->renderflags & RF_FLIPOFFSETS) && flip) ? -1 : 1);
|
||||
const fixed_t rolloffs_y = FixedDiv(interptarg->rollingyoffset, highresscale);
|
||||
fixed_t y_piv = spr_topoffset;
|
||||
fixed_t y_piv = affine_pivot.y;
|
||||
|
||||
if (vflip)
|
||||
{
|
||||
|
|
@ -5173,11 +5187,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
affine_transform.d = FixedDiv(ca, affine_scale.y);
|
||||
}
|
||||
|
||||
affine_transform.ox = spr_offset - rolloffs_x;
|
||||
affine_transform.ox = affine_pivot.x - rolloffs_x;
|
||||
affine_transform.oy = y_piv - rolloffs_y;
|
||||
|
||||
spritexscale = 1.0;
|
||||
spriteyscale = 1,0;
|
||||
spriteyscale = 1.0;
|
||||
}
|
||||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
|
|
@ -5328,10 +5342,18 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
// loops take more processing time. If we can help it, it's better to just cut corners.
|
||||
float f_left = 0;
|
||||
float f_bottom = 0;
|
||||
float f_right = 0;
|
||||
float f_top = 0;
|
||||
float f_xlen = 0;
|
||||
float f_ylen = 0;
|
||||
#define BOUNDCHECK(i) \
|
||||
{ \
|
||||
f_left = min(affine_point[i].x, f_left); \
|
||||
f_bottom = max(affine_point[i].y, f_bottom); \
|
||||
f_top = min(affine_point[i].y, f_top); \
|
||||
f_right = max(affine_point[i].x, f_right); \
|
||||
f_xlen = (f_right - f_left); \
|
||||
f_ylen = (f_bottom - f_top); \
|
||||
}
|
||||
|
||||
BOUNDCHECK(0);
|
||||
|
|
@ -5354,6 +5376,16 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
affine_rootpoint.x = tr_x;
|
||||
affine_rootpoint.z = tr_y;
|
||||
|
||||
// Rescale X and Y so we can multiply the pivot offset differences by them.
|
||||
const float f_affinexscale = f_xlen / (FIXED_TO_FLOAT(spr_width));
|
||||
const float f_affineyscale = f_ylen / (FIXED_TO_FLOAT(spr_height));
|
||||
|
||||
affine_pivotoffsetdiff.x *= f_affinexscale;
|
||||
affine_pivotoffsetdiff.y *= f_affineyscale;
|
||||
|
||||
affine_rootpoint.x -= (affine_pivotoffsetdiff.x * rightcos);
|
||||
affine_rootpoint.z -= (affine_pivotoffsetdiff.x * rightsin);
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
const float xrescale = this_xscale / FIXED_TO_FLOAT(mapobjectscale);
|
||||
float f_visx = (FIXED_TO_FLOAT(FixedMul(visoffs.x, mapobjectscale))) * xrescale;
|
||||
|
|
@ -5422,15 +5454,15 @@ nodeterminant:
|
|||
|
||||
affine_rootpoint.y = 0;
|
||||
|
||||
const float f_topoffs = FIXED_TO_FLOAT(spr_topoffset);
|
||||
const float f_topoffs = (FIXED_TO_FLOAT(spr_topoffset));
|
||||
|
||||
if (vflip)
|
||||
{
|
||||
affine_rootpoint.y = FIXED_TO_FLOAT(interp.z + thing->height) - (f_topoffs * this_yscale);
|
||||
affine_rootpoint.y = (FIXED_TO_FLOAT(interp.z + thing->height) + affine_pivotoffsetdiff.y) - (f_topoffs * this_yscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
affine_rootpoint.y = FIXED_TO_FLOAT(interp.z) + (f_topoffs * this_yscale);
|
||||
affine_rootpoint.y = (FIXED_TO_FLOAT(interp.z) - affine_pivotoffsetdiff.y) + (f_topoffs * this_yscale);
|
||||
}
|
||||
|
||||
if (!affinesprite)
|
||||
|
|
|
|||
|
|
@ -1971,6 +1971,28 @@ fixed_t R_GetSpriteDirectionalLighting(angle_t angle)
|
|||
return extralight;
|
||||
}
|
||||
|
||||
void R_GetPivotVectorFromSpriteInfo(vector2_t* out,
|
||||
vector2_t* defaultpiv,
|
||||
spriteinfo_t* sprinfo,
|
||||
size_t frame)
|
||||
{
|
||||
if (in_bit_array(sprinfo->available, frame))
|
||||
{
|
||||
out->x = (sprinfo->pivot[frame].x * FRACUNIT);
|
||||
out->y = (sprinfo->pivot[frame].y * FRACUNIT);
|
||||
}
|
||||
else if (in_bit_array(sprinfo->available, SPRINFO_DEFAULT_PIVOT))
|
||||
{
|
||||
out->x = (sprinfo->pivot[SPRINFO_DEFAULT_PIVOT].x * FRACUNIT);
|
||||
out->y = (sprinfo->pivot[SPRINFO_DEFAULT_PIVOT].y * FRACUNIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
out->x = defaultpiv->x;
|
||||
out->y = defaultpiv->y;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_ProjectSprite
|
||||
// Generates a vissprite for a thing
|
||||
|
|
@ -2060,6 +2082,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
affine_bounding_t affine_bounds = {0};
|
||||
vector2_t affine_scale = {0};
|
||||
vector2_t affine_distscale = {0};
|
||||
vector2_t affine_pivotoffsetdiff = {0};
|
||||
|
||||
if (R_IsOverlayingSMonitorPlayer(thing))
|
||||
{
|
||||
|
|
@ -2319,6 +2342,18 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
if (affinesprite)
|
||||
{
|
||||
vector2_t affine_pivot = {0};
|
||||
|
||||
vector2_t patch_defaultpivot = {.x = (patch->leftoffset * FRACUNIT), .y = (patch->height * FRACHALF)};
|
||||
|
||||
R_GetPivotVectorFromSpriteInfo(&affine_pivot,
|
||||
&patch_defaultpivot,
|
||||
sprinfo,
|
||||
(thing->frame & FF_FRAMEMASK));
|
||||
|
||||
affine_pivotoffsetdiff.x = affine_pivot.x - (patch->leftoffset * FRACUNIT);
|
||||
affine_pivotoffsetdiff.y = affine_pivot.y - (patch->topoffset * FRACUNIT);
|
||||
|
||||
affine_scale.x = FixedMul(affine_scale.x, FixedMul(spritexscale, this_scale));
|
||||
affine_scale.y = FixedMul(affine_scale.y, FixedMul(spriteyscale, this_scale));
|
||||
|
||||
|
|
@ -2330,7 +2365,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
|
||||
const fixed_t rolloffs_x = FixedDiv(interptarg->rollingxoffset, highresscale) * (((thing->renderflags & RF_FLIPOFFSETS) && flip) ? -1 : 1);
|
||||
const fixed_t rolloffs_y = FixedDiv(interptarg->rollingyoffset, highresscale);
|
||||
fixed_t y_piv = ((patch->pivot.y + patch->topoffset) * FRACUNIT);
|
||||
fixed_t y_piv = affine_pivot.y;
|
||||
|
||||
if (vflip)
|
||||
{
|
||||
|
|
@ -2356,13 +2391,20 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
affine_transform.d = FixedDiv(ca, affine_scale.y);
|
||||
}
|
||||
|
||||
affine_transform.ox = ((patch->pivot.x + patch->leftoffset) * FRACUNIT) - rolloffs_x;
|
||||
affine_transform.ox = affine_pivot.x - rolloffs_x;
|
||||
affine_transform.oy = y_piv - rolloffs_y;
|
||||
|
||||
V_GetAffineBounds(&affine_transform, patch, FRACUNIT, &affine_bounds);
|
||||
|
||||
// Rescale X and Y so we can multiply the pivot offset differences by them.
|
||||
const fixed_t _affinexscale = FixedDiv(affine_bounds.xlen * FRACUNIT, patch->width * FRACUNIT);
|
||||
const fixed_t _affineyscale = FixedDiv(affine_bounds.ylen * FRACUNIT, patch->height * FRACUNIT);
|
||||
|
||||
affine_pivotoffsetdiff.x = FixedMul(affine_pivotoffsetdiff.x, _affinexscale);
|
||||
affine_pivotoffsetdiff.y = FixedMul(affine_pivotoffsetdiff.y, _affineyscale);
|
||||
|
||||
spr_width = (affine_bounds.xlen * FRACUNIT);
|
||||
spr_offset = (affine_bounds.xleft * FRACUNIT);
|
||||
spr_offset = (affine_bounds.xleft * FRACUNIT) - affine_pivotoffsetdiff.x;
|
||||
|
||||
//spr_height = (affine_bounds.ylen * FRACUNIT);
|
||||
//spr_topoffset = (affine_bounds.yup * FRACUNIT);
|
||||
|
|
@ -2713,7 +2755,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
|||
fixed_t rawyscale = FixedDiv(affine_scale.y, FixedMul(this_scale, sortscale));
|
||||
|
||||
const float affineyscale = FIXED_TO_FLOAT(affine_scale.y);
|
||||
const fixed_t real_topoffset = FLOAT_TO_FIXED(static_cast<float>(affine_bounds.yup) / affineyscale) + thingyoffset;
|
||||
const float pivydiff = FIXED_TO_FLOAT(affine_pivotoffsetdiff.y) * ((vflip) ? -1.0f : 1.0f);
|
||||
const fixed_t real_topoffset = FLOAT_TO_FIXED(static_cast<float>(affine_bounds.yup - pivydiff) / affineyscale) + thingyoffset;
|
||||
const fixed_t real_height = FLOAT_TO_FIXED(static_cast<float>(affine_bounds.ylen) / affineyscale);
|
||||
|
||||
useoffset = FixedMul(real_topoffset, FixedMul(rawyscale, this_scale));
|
||||
|
|
|
|||
|
|
@ -91,12 +91,18 @@ boolean R_ThingVerticallyFlipped (mobj_t *thing);
|
|||
|
||||
boolean R_ThingIsPaperSprite (mobj_t *thing);
|
||||
boolean R_ThingIsFloorSprite (mobj_t *thing);
|
||||
boolean R_ThingIsAffineSprite (mobj_t *thing);
|
||||
|
||||
|
||||
boolean R_ThingIsFullBright (mobj_t *thing);
|
||||
boolean R_ThingIsSemiBright (mobj_t *thing);
|
||||
boolean R_ThingIsFullDark (mobj_t *thing);
|
||||
|
||||
boolean R_ThingIsAffineSprite (mobj_t *thing);
|
||||
boolean R_AffinePreScale (mobj_t *thing);
|
||||
void R_GetPivotVectorFromSpriteInfo(vector2_t* out,
|
||||
vector2_t* defaultpiv,
|
||||
spriteinfo_t* sprinfo,
|
||||
size_t frame);
|
||||
|
||||
boolean R_ThingIsFlashing(mobj_t *thing);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue