mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-27 04:41:23 +00:00
Large room fix
This commit is contained in:
parent
feb7b05e6e
commit
348ed1e43f
10 changed files with 128 additions and 83 deletions
|
@ -121,6 +121,13 @@ fixed_t FixedHypot(fixed_t x, fixed_t y)
|
||||||
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
|
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fixed_t FixedEuclidean(fixed_t x2, fixed_t y2, fixed_t x1, fixed_t y1)
|
||||||
|
{
|
||||||
|
INT64 dx = x2-x1;
|
||||||
|
INT64 dy = y2-y1;
|
||||||
|
return (fixed_t)llrint(sqrt(dx*dx+dy*dy));
|
||||||
|
}
|
||||||
|
|
||||||
vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y)
|
vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
vec->x = x;
|
vec->x = x;
|
||||||
|
|
|
@ -237,6 +237,17 @@ FUNCMATH fixed_t FixedSqrt(fixed_t x);
|
||||||
*/
|
*/
|
||||||
FUNCMATH fixed_t FixedHypot(fixed_t x, fixed_t y);
|
FUNCMATH fixed_t FixedHypot(fixed_t x, fixed_t y);
|
||||||
|
|
||||||
|
/** \brief The FixedEuclidean function
|
||||||
|
|
||||||
|
\param x fixed_t number
|
||||||
|
\param y fixed_t number
|
||||||
|
|
||||||
|
\return sqrt(x*x+y*y)
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
fixed_t FixedEuclidean(fixed_t x2, fixed_t y2, fixed_t x1, fixed_t y1);
|
||||||
|
|
||||||
/** \brief The FixedFloor function
|
/** \brief The FixedFloor function
|
||||||
|
|
||||||
\param x fixed_t number
|
\param x fixed_t number
|
||||||
|
|
|
@ -380,30 +380,24 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum)
|
||||||
Z_Free(data);
|
Z_Free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Computes the line length in fracunits, the OpenGL render needs this
|
|
||||||
//
|
|
||||||
|
|
||||||
/** Computes the length of a seg in fracunits.
|
/** Computes the length of a seg in fracunits.
|
||||||
* This is needed for splats.
|
|
||||||
*
|
*
|
||||||
* \param seg Seg to compute length for.
|
* \param seg Seg to compute length for.
|
||||||
* \return Length in fracunits.
|
* \return Length in fracunits.
|
||||||
*/
|
*/
|
||||||
fixed_t P_SegLength(seg_t *seg)
|
fixed_t P_SegLength(seg_t *seg)
|
||||||
{
|
{
|
||||||
fixed_t dx, dy;
|
return FixedEuclidean(seg->v2->x,seg->v2->y,seg->v1->x,seg->v1->y);
|
||||||
|
|
||||||
// make a vector (start at origin)
|
|
||||||
dx = seg->v2->x - seg->v1->x;
|
|
||||||
dy = seg->v2->y - seg->v1->y;
|
|
||||||
|
|
||||||
return FixedHypot(dx, dy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
static inline float P_SegLengthf(seg_t *seg)
|
/** Computes the length of a seg as a float.
|
||||||
|
* This is needed for OpenGL.
|
||||||
|
*
|
||||||
|
* \param seg Seg to compute length for.
|
||||||
|
* \return Length as a float.
|
||||||
|
*/
|
||||||
|
static inline float P_SegLengthFloat(seg_t *seg)
|
||||||
{
|
{
|
||||||
float dx, dy;
|
float dx, dy;
|
||||||
|
|
||||||
|
@ -439,11 +433,11 @@ static void P_LoadRawSegs(UINT8 *data, size_t i)
|
||||||
li->v1 = &vertexes[SHORT(ml->v1)];
|
li->v1 = &vertexes[SHORT(ml->v1)];
|
||||||
li->v2 = &vertexes[SHORT(ml->v2)];
|
li->v2 = &vertexes[SHORT(ml->v2)];
|
||||||
|
|
||||||
#ifdef HWRENDER // not win32 only 19990829 by Kin
|
li->length = P_SegLength(li);
|
||||||
// used for the hardware render
|
#ifdef HWRENDER
|
||||||
if (rendermode != render_soft && rendermode != render_none)
|
if (rendermode == render_opengl)
|
||||||
{
|
{
|
||||||
li->flength = P_SegLengthf(li);
|
li->flength = P_SegLengthFloat(li);
|
||||||
//Hurdler: 04/12/2000: for now, only used in hardware mode
|
//Hurdler: 04/12/2000: for now, only used in hardware mode
|
||||||
li->lightmaps = NULL; // list of static lightmap for this seg
|
li->lightmaps = NULL; // list of static lightmap for this seg
|
||||||
}
|
}
|
||||||
|
|
86
src/r_bsp.c
86
src/r_bsp.c
|
@ -403,17 +403,17 @@ static void R_AddLine(seg_t *line)
|
||||||
{
|
{
|
||||||
INT32 x1, x2;
|
INT32 x1, x2;
|
||||||
angle_t angle1, angle2, span, tspan;
|
angle_t angle1, angle2, span, tspan;
|
||||||
static sector_t tempsec; // ceiling/water hack
|
static sector_t tempsec;
|
||||||
|
|
||||||
|
portalline = false;
|
||||||
|
|
||||||
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
|
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// big room fix
|
||||||
|
angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y);
|
||||||
|
angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y);
|
||||||
curline = line;
|
curline = line;
|
||||||
portalline = false;
|
|
||||||
|
|
||||||
// OPTIMIZE: quickly reject orthogonal back sides.
|
|
||||||
angle1 = R_PointToAngle(line->v1->x, line->v1->y);
|
|
||||||
angle2 = R_PointToAngle(line->v2->x, line->v2->y);
|
|
||||||
|
|
||||||
// Clip to view edges.
|
// Clip to view edges.
|
||||||
span = angle1 - angle2;
|
span = angle1 - angle2;
|
||||||
|
@ -592,69 +592,35 @@ INT32 checkcoord[12][4] =
|
||||||
{2, 1, 3, 0}
|
{2, 1, 3, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static boolean R_CheckBBox(fixed_t *bspcoord)
|
static boolean R_CheckBBox(const fixed_t *bspcoord)
|
||||||
{
|
{
|
||||||
INT32 boxpos, sx1, sx2;
|
angle_t angle1, angle2;
|
||||||
fixed_t px1, py1, px2, py2;
|
INT32 sx1, sx2, boxpos;
|
||||||
angle_t angle1, angle2, span, tspan;
|
const INT32* check;
|
||||||
cliprange_t *start;
|
cliprange_t *start;
|
||||||
|
|
||||||
// Find the corners of the box that define the edges from current viewpoint.
|
// Find the corners of the box that define the edges from current viewpoint.
|
||||||
if (viewx <= bspcoord[BOXLEFT])
|
if ((boxpos = (viewx <= bspcoord[BOXLEFT] ? 0 : viewx < bspcoord[BOXRIGHT] ? 1 : 2) + (viewy >= bspcoord[BOXTOP] ? 0 : viewy > bspcoord[BOXBOTTOM] ? 4 : 8)) == 5)
|
||||||
boxpos = 0;
|
|
||||||
else if (viewx < bspcoord[BOXRIGHT])
|
|
||||||
boxpos = 1;
|
|
||||||
else
|
|
||||||
boxpos = 2;
|
|
||||||
|
|
||||||
if (viewy >= bspcoord[BOXTOP])
|
|
||||||
boxpos |= 0;
|
|
||||||
else if (viewy > bspcoord[BOXBOTTOM])
|
|
||||||
boxpos |= 1<<2;
|
|
||||||
else
|
|
||||||
boxpos |= 2<<2;
|
|
||||||
|
|
||||||
if (boxpos == 5)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
px1 = bspcoord[checkcoord[boxpos][0]];
|
check = checkcoord[boxpos];
|
||||||
py1 = bspcoord[checkcoord[boxpos][1]];
|
|
||||||
px2 = bspcoord[checkcoord[boxpos][2]];
|
|
||||||
py2 = bspcoord[checkcoord[boxpos][3]];
|
|
||||||
|
|
||||||
// check clip list for an open space
|
// big room fix
|
||||||
angle1 = R_PointToAngle2(viewx>>1, viewy>>1, px1>>1, py1>>1) - viewangle;
|
angle1 = R_PointToAngleEx(viewx, viewy, bspcoord[check[0]], bspcoord[check[1]]) - viewangle;
|
||||||
angle2 = R_PointToAngle2(viewx>>1, viewy>>1, px2>>1, py2>>1) - viewangle;
|
angle2 = R_PointToAngleEx(viewx, viewy, bspcoord[check[2]], bspcoord[check[3]]) - viewangle;
|
||||||
|
|
||||||
span = angle1 - angle2;
|
if ((signed)angle1 < (signed)angle2)
|
||||||
|
|
||||||
// Sitting on a line?
|
|
||||||
if (span >= ANGLE_180)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
tspan = angle1 + clipangle;
|
|
||||||
|
|
||||||
if (tspan > doubleclipangle)
|
|
||||||
{
|
{
|
||||||
tspan -= doubleclipangle;
|
if ((angle1 >= ANGLE_180) && (angle1 < ANGLE_270))
|
||||||
|
angle1 = ANGLE_180-1;
|
||||||
// Totally off the left edge?
|
else
|
||||||
if (tspan >= span)
|
angle2 = -ANGLE_180;
|
||||||
return false;
|
|
||||||
|
|
||||||
angle1 = clipangle;
|
|
||||||
}
|
}
|
||||||
tspan = clipangle - angle2;
|
|
||||||
if (tspan > doubleclipangle)
|
|
||||||
{
|
|
||||||
tspan -= doubleclipangle;
|
|
||||||
|
|
||||||
// Totally off the left edge?
|
if ((signed)angle2 >= (signed)clipangle) return false;
|
||||||
if (tspan >= span)
|
if ((signed)angle1 <= -(signed)clipangle) return false;
|
||||||
return false;
|
if ((signed)angle1 >= (signed)clipangle) angle1 = clipangle;
|
||||||
|
if ((signed)angle2 <= -(signed)clipangle) angle2 = 0-clipangle;
|
||||||
angle2 = -(signed)clipangle;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the first clippost that touches the source post (adjacent pixels are touching).
|
// Find the first clippost that touches the source post (adjacent pixels are touching).
|
||||||
angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
|
angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
|
||||||
|
@ -663,9 +629,7 @@ static boolean R_CheckBBox(fixed_t *bspcoord)
|
||||||
sx2 = viewangletox[angle2];
|
sx2 = viewangletox[angle2];
|
||||||
|
|
||||||
// Does not cross a pixel.
|
// Does not cross a pixel.
|
||||||
if (sx1 == sx2)
|
if (sx1 >= sx2) return false;
|
||||||
return false;
|
|
||||||
sx2--;
|
|
||||||
|
|
||||||
start = solidsegs;
|
start = solidsegs;
|
||||||
while (start->last < sx2)
|
while (start->last < sx2)
|
||||||
|
|
|
@ -573,6 +573,7 @@ typedef struct seg_s
|
||||||
sector_t *frontsector;
|
sector_t *frontsector;
|
||||||
sector_t *backsector;
|
sector_t *backsector;
|
||||||
|
|
||||||
|
fixed_t length; // precalculated seg length
|
||||||
#ifdef HWRENDER
|
#ifdef HWRENDER
|
||||||
// new pointers so that AdjustSegs doesn't mess with v1/v2
|
// new pointers so that AdjustSegs doesn't mess with v1/v2
|
||||||
void *pv1; // polyvertex_t
|
void *pv1; // polyvertex_t
|
||||||
|
|
23
src/r_main.c
23
src/r_main.c
|
@ -355,6 +355,29 @@ fixed_t R_PointToDist(fixed_t x, fixed_t y)
|
||||||
return R_PointToDist2(viewx, viewy, x, y);
|
return R_PointToDist2(viewx, viewy, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1)
|
||||||
|
{
|
||||||
|
INT64 dx = x1-x2;
|
||||||
|
INT64 dy = y1-y2;
|
||||||
|
if (dx < INT32_MIN || dx > INT32_MAX || dy < INT32_MIN || dy > INT32_MAX)
|
||||||
|
{
|
||||||
|
x1 = (int)(dx / 2 + x2);
|
||||||
|
y1 = (int)(dy / 2 + y2);
|
||||||
|
}
|
||||||
|
return (y1 -= y2, (x1 -= x2) || y1) ?
|
||||||
|
x1 >= 0 ?
|
||||||
|
y1 >= 0 ?
|
||||||
|
(x1 > y1) ? tantoangle[SlopeDivEx(y1,x1)] : // octant 0
|
||||||
|
ANGLE_90-tantoangle[SlopeDivEx(x1,y1)] : // octant 1
|
||||||
|
x1 > (y1 = -y1) ? 0-tantoangle[SlopeDivEx(y1,x1)] : // octant 8
|
||||||
|
ANGLE_270+tantoangle[SlopeDivEx(x1,y1)] : // octant 7
|
||||||
|
y1 >= 0 ? (x1 = -x1) > y1 ? ANGLE_180-tantoangle[SlopeDivEx(y1,x1)] : // octant 3
|
||||||
|
ANGLE_90 + tantoangle[SlopeDivEx(x1,y1)] : // octant 2
|
||||||
|
(x1 = -x1) > (y1 = -y1) ? ANGLE_180+tantoangle[SlopeDivEx(y1,x1)] : // octant 4
|
||||||
|
ANGLE_270-tantoangle[SlopeDivEx(x1,y1)] : // octant 5
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_ScaleFromGlobalAngle
|
// R_ScaleFromGlobalAngle
|
||||||
// Returns the texture mapping scale for the current line (horizontal span)
|
// Returns the texture mapping scale for the current line (horizontal span)
|
||||||
|
|
|
@ -58,6 +58,7 @@ INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node);
|
||||||
INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line);
|
INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line);
|
||||||
angle_t R_PointToAngle(fixed_t x, fixed_t y);
|
angle_t R_PointToAngle(fixed_t x, fixed_t y);
|
||||||
angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||||
|
angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1);
|
||||||
fixed_t R_PointToDist(fixed_t x, fixed_t y);
|
fixed_t R_PointToDist(fixed_t x, fixed_t y);
|
||||||
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
fixed_t R_PointToDist2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||||
|
|
||||||
|
|
41
src/r_segs.c
41
src/r_segs.c
|
@ -1674,6 +1674,23 @@ static void R_RenderSegLoop (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uses precalculated seg->length
|
||||||
|
static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
|
||||||
|
{
|
||||||
|
if (!seg->linedef->dy)
|
||||||
|
return abs(y2 - seg->v1->y);
|
||||||
|
else if (!seg->linedef->dx)
|
||||||
|
return abs(x2 - seg->v1->x);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INT64 dx = (seg->v2->x)-(seg->v1->x);
|
||||||
|
INT64 dy = (seg->v2->y)-(seg->v1->y);
|
||||||
|
INT64 vdx = x2-(seg->v1->x);
|
||||||
|
INT64 vdy = y2-(seg->v1->y);
|
||||||
|
return ((dy*vdx)-(dx*vdy))/(seg->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_StoreWallRange
|
// R_StoreWallRange
|
||||||
// A wall segment will be drawn
|
// A wall segment will be drawn
|
||||||
|
@ -1684,6 +1701,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
fixed_t hyp;
|
fixed_t hyp;
|
||||||
fixed_t sineval;
|
fixed_t sineval;
|
||||||
angle_t distangle, offsetangle;
|
angle_t distangle, offsetangle;
|
||||||
|
boolean longboi;
|
||||||
#ifndef ESLOPE
|
#ifndef ESLOPE
|
||||||
fixed_t vtop;
|
fixed_t vtop;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1729,10 +1747,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
offsetangle = ANGLE_90;
|
offsetangle = ANGLE_90;
|
||||||
|
|
||||||
distangle = ANGLE_90 - offsetangle;
|
distangle = ANGLE_90 - offsetangle;
|
||||||
hyp = R_PointToDist (curline->v1->x, curline->v1->y);
|
|
||||||
sineval = FINESINE(distangle>>ANGLETOFINESHIFT);
|
sineval = FINESINE(distangle>>ANGLETOFINESHIFT);
|
||||||
rw_distance = FixedMul (hyp, sineval);
|
|
||||||
|
|
||||||
|
hyp = R_PointToDist(curline->v1->x, curline->v1->y);
|
||||||
|
rw_distance = FixedMul(hyp, sineval);
|
||||||
|
longboi = (hyp >= INT32_MAX);
|
||||||
|
|
||||||
|
// big room fix
|
||||||
|
if (longboi)
|
||||||
|
rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy);
|
||||||
|
|
||||||
ds_p->x1 = rw_x = start;
|
ds_p->x1 = rw_x = start;
|
||||||
ds_p->x2 = stop;
|
ds_p->x2 = stop;
|
||||||
|
@ -2589,8 +2612,18 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
if (offsetangle > ANGLE_90)
|
if (offsetangle > ANGLE_90)
|
||||||
offsetangle = ANGLE_90;
|
offsetangle = ANGLE_90;
|
||||||
|
|
||||||
sineval = FINESINE(offsetangle >>ANGLETOFINESHIFT);
|
sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT);
|
||||||
rw_offset = FixedMul (hyp, sineval);
|
rw_offset = FixedMul(hyp, sineval);
|
||||||
|
|
||||||
|
// big room fix
|
||||||
|
if (longboi)
|
||||||
|
{
|
||||||
|
INT64 dx = (curline->v2->x)-(curline->v1->x);
|
||||||
|
INT64 dy = (curline->v2->y)-(curline->v1->y);
|
||||||
|
INT64 vdx = viewx-(curline->v1->x);
|
||||||
|
INT64 vdy = viewy-(curline->v1->y);
|
||||||
|
rw_offset = ((dx*vdx-dy*vdy))/(curline->length);
|
||||||
|
}
|
||||||
|
|
||||||
if (rw_normalangle-rw_angle1 < ANGLE_180)
|
if (rw_normalangle-rw_angle1 < ANGLE_180)
|
||||||
rw_offset = -rw_offset;
|
rw_offset = -rw_offset;
|
||||||
|
|
|
@ -37,6 +37,15 @@ unsigned SlopeDiv(unsigned num, unsigned den)
|
||||||
return ans <= SLOPERANGE ? ans : SLOPERANGE;
|
return ans <= SLOPERANGE ? ans : SLOPERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT64 SlopeDivEx(unsigned int num, unsigned int den)
|
||||||
|
{
|
||||||
|
UINT64 ans;
|
||||||
|
if (den < 512)
|
||||||
|
return SLOPERANGE;
|
||||||
|
ans = ((UINT64)num<<3)/(den>>8);
|
||||||
|
return ans <= SLOPERANGE ? ans : SLOPERANGE;
|
||||||
|
}
|
||||||
|
|
||||||
fixed_t AngleFixed(angle_t af)
|
fixed_t AngleFixed(angle_t af)
|
||||||
{
|
{
|
||||||
angle_t wa = ANGLE_180;
|
angle_t wa = ANGLE_180;
|
||||||
|
|
|
@ -83,6 +83,8 @@ extern angle_t tantoangle[SLOPERANGE+1];
|
||||||
|
|
||||||
// Utility function, called by R_PointToAngle.
|
// Utility function, called by R_PointToAngle.
|
||||||
FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den);
|
FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den);
|
||||||
|
// Only called by R_PointToAngleEx
|
||||||
|
UINT64 SlopeDivEx(unsigned int num, unsigned int den);
|
||||||
|
|
||||||
// 360 - angle_t(ANGLE_45) = ANGLE_315
|
// 360 - angle_t(ANGLE_45) = ANGLE_315
|
||||||
FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a)
|
FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a)
|
||||||
|
|
Loading…
Reference in a new issue