This commit is contained in:
Jaime Ita Passos 2021-06-28 19:18:44 -03:00
parent ec3456b938
commit 5475b2432c
6 changed files with 149 additions and 145 deletions

View file

@ -80,6 +80,15 @@ void NodeBuilder_Clear(void)
if (builder == NULL)
return;
Z_Free(builder->Nodes);
Z_Free(builder->Subsectors);
Z_Free(builder->SubsectorSets);
Z_Free(builder->Segs);
Z_Free(builder->Vertices);
Z_Free(builder->SegList);
Z_Free(builder->PlaneChecked);
Z_Free(builder->Planes);
builder->Nodes = NULL;
builder->Subsectors = NULL;
builder->SubsectorSets = NULL;
@ -246,7 +255,7 @@ static double InterceptVector(const node_t *splitter, const FPrivSeg *seg)
double v1x, v1y;
double num, frac;
if (den == 0.0)
if (fpclassify(den) == FP_ZERO)
return 0.0; // parallel
v1x = FixedToDouble(splitter->x);
@ -820,6 +829,7 @@ static void CreateSubsectorsForReal(void)
PushSegPtr(&ptr);
set = ptr.SegPtr->next;
}
sub.numlines = (UINT32)(builder->SegListSize - firstline);
sub.firstline = (UINT16)firstline;
@ -850,15 +860,20 @@ void NodeBuilder_BuildMini(void)
BuildTree();
}
#define TryRealloc(oldsize, newsize, dest, type) \
size = (size_t)builder->newsize; \
if (size != bsp->oldsize) { \
bsp->oldsize = size; \
bsp->dest = Z_Realloc(bsp->dest, size * sizeof(type), PU_LEVEL, NULL); \
} \
size *= sizeof(type);
void NodeBuilder_ExtractMini(minibsp_t *bsp)
{
UINT32 i;
size_t size;
bsp->dirty = false;
bsp->numverts = (size_t)builder->NumVertices;
bsp->verts = Z_Malloc(bsp->numverts * sizeof(vertex_t), PU_LEVEL, NULL);
TryRealloc(numverts, NumVertices, verts, vertex_t);
for (i = 0; i < bsp->numverts; ++i)
{
@ -869,18 +884,13 @@ void NodeBuilder_ExtractMini(minibsp_t *bsp)
vert->floorz = vert->ceilingz = 0;
}
bsp->numnodes = (size_t)builder->NumNodes;
size = bsp->numnodes * sizeof(node_t);
bsp->nodes = Z_Malloc(size, PU_LEVEL, NULL);
TryRealloc(numnodes, NumNodes, nodes, node_t);
memcpy(bsp->nodes, builder->Nodes, size);
bsp->numsubsectors = (size_t)builder->NumSubsectors;
size = bsp->numsubsectors * sizeof(subsector_t);
bsp->subsectors = Z_Malloc(size, PU_LEVEL, NULL);
TryRealloc(numsubsectors, NumSubsectors, subsectors, subsector_t);
memcpy(bsp->subsectors, builder->Subsectors, size);
bsp->numsegs = (size_t)builder->NumSegs;
bsp->segs = Z_Malloc(bsp->numsegs * sizeof(seg_t), PU_LEVEL, NULL);
TryRealloc(numsegs, NumSegs, segs, seg_t);
for (i = 0; i < bsp->numsegs; ++i)
{
@ -906,8 +916,12 @@ void NodeBuilder_ExtractMini(minibsp_t *bsp)
out->polybackside = org->backside;
out->glseg = false;
}
bsp->dirty = false;
}
#undef TryRealloc
void NodeBuilder_AddSegs(seg_t *seglist, size_t segcount)
{
size_t i;

View file

@ -773,6 +773,7 @@ void Polyobj_ClearSubsectorLinks(polyobj_t *polyobj)
{
polynode_t *link = polyobj->subsectorlinks;
polynode_t *next = link->snext;
subsector_t *sub = link->subsector;
if (link->pnext != NULL)
link->pnext->pprev = link->pprev;
@ -780,10 +781,10 @@ void Polyobj_ClearSubsectorLinks(polyobj_t *polyobj)
if (link->pprev != NULL)
link->pprev->pnext = link->pnext;
else
link->subsector->polynodes = link->pnext;
sub->polynodes = link->pnext;
if (link->subsector->BSP != NULL)
link->subsector->BSP->dirty = true;
if (sub->BSP != NULL)
sub->BSP->dirty = true;
FreePolyNode(link);
polyobj->subsectorlinks = next;
@ -830,7 +831,7 @@ static boolean GetIntersection(polyseg_t *seg, node_t *bsp, polyobjvertex_t *v)
den = v1dy*v2dx - v1dx*v2dy;
if (den == 0.0)
if (fpclassify(den) == FP_ZERO)
return false; // parallel
num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx;
@ -1079,6 +1080,7 @@ static void Polyobj_CreateSubsectorLinks(polyobj_t *polyobj)
}
SplitPoly(node, (INT32)numnodes - 1, dummybbox);
ReleaseAllPolyNodes();
}
void Polyobj_LinkToSubsectors(void)
@ -1156,7 +1158,7 @@ static void Polyobj_linkToBlockmap(polyobj_t *po)
{
if (!(x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight))
{
polymaplink_t *l = Polyobj_getLink();
polymaplink_t *l = Polyobj_getLink();
l->po = po;

View file

@ -30,6 +30,7 @@ side_t *sidedef;
line_t *linedef;
sector_t *frontsector;
sector_t *backsector;
polynode_t *polynodes;
static minibsp_t *minibsp = NULL;
@ -393,14 +394,11 @@ static void R_AddLine(seg_t *line)
static sector_t tempsec;
boolean bothceilingssky = false, bothfloorssky = false;
portalline = false;
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
return;
angle1 = R_PointToAngleEx(viewx, viewy, line->v1->x, line->v1->y);
angle2 = R_PointToAngleEx(viewx, viewy, line->v2->x, line->v2->y);
curline = line;
portalline = false;
// Clip to view edges.
span = angle1 - angle2;
@ -677,7 +675,7 @@ void R_BuildPolyBSP(subsector_t *sub)
NodeBuilder_BuildMini();
if (sub->BSP == NULL)
sub->BSP = Z_Malloc(sizeof(minibsp_t), PU_LEVEL, NULL);
sub->BSP = Z_Calloc(sizeof(minibsp_t), PU_LEVEL, NULL);
NodeBuilder_ExtractMini(sub->BSP);
for (i = 0; i < sub->BSP->numsubsectors; ++i)
@ -981,6 +979,7 @@ void R_Subsector(size_t num)
if (minibsp && sub->polynodes)
{
polynode_t *pn = sub->polynodes;
polynodes = pn;
for (; pn != NULL; pn = pn->pnext)
{
@ -1059,6 +1058,8 @@ void R_Subsector(size_t num)
line++;
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */
}
polynodes = NULL;
}
//

View file

@ -23,6 +23,7 @@ extern side_t *sidedef;
extern line_t *linedef;
extern sector_t *frontsector;
extern sector_t *backsector;
extern polynode_t *polynodes;
extern boolean portalline; // is curline a portal seg?
// drawsegs are allocated on the fly... see r_segs.c

View file

@ -448,6 +448,42 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
return check;
}
static visplane_t *R_CreateVisplane(visplane_t *pl, INT32 start, INT32 stop)
{
visplane_t *new_pl;
if (pl->ffloor || pl->polyobj)
{
new_pl = new_visplane(MAXVISPLANES - 1);
}
else
{
unsigned hash =
visplane_hash(pl->picnum, pl->lightlevel, pl->height);
new_pl = new_visplane(hash);
}
new_pl->height = pl->height;
new_pl->picnum = pl->picnum;
new_pl->lightlevel = pl->lightlevel;
new_pl->xoffs = pl->xoffs;
new_pl->yoffs = pl->yoffs;
new_pl->extra_colormap = pl->extra_colormap;
new_pl->ffloor = pl->ffloor;
new_pl->viewx = pl->viewx;
new_pl->viewy = pl->viewy;
new_pl->viewz = pl->viewz;
new_pl->viewangle = pl->viewangle;
new_pl->plangle = pl->plangle;
new_pl->polyobj = pl->polyobj;
new_pl->slope = pl->slope;
new_pl->minx = start;
new_pl->maxx = stop;
memset(new_pl->top, 0xff, sizeof new_pl->top);
memset(new_pl->bottom, 0x00, sizeof new_pl->bottom);
return new_pl;
}
//
// R_CheckPlane: return same visplane or alloc a new one if needed
//
@ -457,6 +493,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
INT32 unionl, unionh;
INT32 x;
if (pl->polyobj)
return R_CreateVisplane(pl, start, stop);
if (start < pl->minx)
{
intrl = pl->minx;
@ -488,92 +527,29 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
{
pl->minx = unionl;
pl->maxx = unionh;
return pl;
}
else /* Cannot use existing plane; create a new one */
{
visplane_t *new_pl;
if (pl->ffloor)
{
new_pl = new_visplane(MAXVISPLANES - 1);
}
else
{
unsigned hash =
visplane_hash(pl->picnum, pl->lightlevel, pl->height);
new_pl = new_visplane(hash);
}
new_pl->height = pl->height;
new_pl->picnum = pl->picnum;
new_pl->lightlevel = pl->lightlevel;
new_pl->xoffs = pl->xoffs;
new_pl->yoffs = pl->yoffs;
new_pl->extra_colormap = pl->extra_colormap;
new_pl->ffloor = pl->ffloor;
new_pl->viewx = pl->viewx;
new_pl->viewy = pl->viewy;
new_pl->viewz = pl->viewz;
new_pl->viewangle = pl->viewangle;
new_pl->plangle = pl->plangle;
new_pl->polyobj = pl->polyobj;
new_pl->slope = pl->slope;
pl = new_pl;
pl->minx = start;
pl->maxx = stop;
memset(pl->top, 0xff, sizeof pl->top);
memset(pl->bottom, 0x00, sizeof pl->bottom);
}
return pl;
/* Cannot use existing plane; create a new one */
return R_CreateVisplane(pl, start, stop);
}
//
// R_ExpandPlane
//
// This function basically expands the visplane or I_Errors.
// This function basically expands the visplane.
// The reason for this is that when creating 3D floor planes, there is no
// need to create new ones with R_CheckPlane, because 3D floor planes
// are created by subsector and there is no way a subsector can graphically
// overlap.
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
{
// INT32 unionl, unionh;
// INT32 x;
// Don't expand polyobject planes here - we do that on our own.
if (pl->polyobj)
return;
if (pl->minx > start) pl->minx = start;
if (pl->maxx < stop) pl->maxx = stop;
/*
if (start < pl->minx)
{
unionl = start;
}
else
{
unionl = pl->minx;
}
if (stop > pl->maxx)
{
unionh = stop;
}
else
{
unionh = pl->maxx;
}
for (x = start; x <= stop; x++)
if (pl->top[x] != 0xffff || pl->bottom[x] != 0x0000)
break;
if (x <= stop)
I_Error("R_ExpandPlane: planes in same subsector overlap?!\nminx: %d, maxx: %d, start: %d, stop: %d\n", pl->minx, pl->maxx, start, stop);
pl->minx = unionl, pl->maxx = unionh;
*/
}
static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)

View file

@ -1466,10 +1466,16 @@ static void R_RenderSegLoop (void)
}
for (i = 0; i < numffloors; i++)
{
if (ffloor[i].polyobj && ffloor[i].polyobj != curline->polyseg)
continue;
ffloor[i].f_frac += ffloor[i].f_step;
}
for (i = 0; i < numbackffloors; i++)
{
if (ffloor[i].polyobj && ffloor[i].polyobj != curline->polyseg)
continue;
ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF);
ffloor[i].b_frac += ffloor[i].b_step;
}
@ -2206,7 +2212,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->numthicksides = numthicksides = i;
}
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures)
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures
&& !(curline->polyseg && !(curline->polyseg->flags & POF_RENDERSIDES)))
{
// masked midtexture
if (!ds_p->thicksidecol)
@ -2217,10 +2225,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
else
ds_p->maskedtexturecol = ds_p->thicksidecol;
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
maskedtextureheight = ds_p->maskedtextureheight;
// use REAL front and back floors please, so midtexture rendering isn't mucked up
if (curline->polyseg)
{ // use REAL front and back floors please, so midtexture rendering isn't mucked up
{
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
@ -2478,14 +2487,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
}
}
i = 0;
if (backsector->ffloors || frontsector->ffloors)
{
ffloor_t *rover;
fixed_t roverleft, roverright;
fixed_t planevistest;
i = 0;
if (backsector->ffloors)
{
for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next)
@ -2599,49 +2608,65 @@ void R_StoreWallRange(INT32 start, INT32 stop)
numbackffloors = i;
}
if (polynodes && numbackffloors < MAXFFLOORS)
{
polynode_t *pn = polynodes;
for (; pn != NULL; pn = pn->pnext)
{
polyobj_t *po = pn->poly;
sector_t *polysec;
if (!(po->flags & POF_RENDERPLANES)) // Don't draw planes
continue;
i = 0;
while (i < numffloors && ffloor[i].polyobj != po) i++;
polysec = po->lines[0]->backsector;
if (polysec->floorheight <= frontsector->ceilingheight &&
polysec->floorheight >= frontsector->floorheight &&
(viewz < polysec->floorheight))
{
ffloor[i].b_pos = polysec->floorheight;
ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
}
if (i >= MAXFFLOORS)
break;
if (polysec->ceilingheight >= frontsector->floorheight &&
polysec->ceilingheight <= frontsector->ceilingheight &&
(viewz > polysec->ceilingheight))
{
ffloor[i].b_pos = polysec->ceilingheight;
ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
}
if (i >= MAXFFLOORS)
break;
}
numbackffloors = i;
}
}
for (i = 0; i < numffloors; i++)
{
sector_t *polysec = curline->frontsector;
if (numbackffloors >= MAXFFLOORS)
break;
if (ffloor[i].polyobj && polysec->floorheight <= frontsector->ceilingheight &&
polysec->floorheight >= frontsector->floorheight &&
(viewz < polysec->floorheight))
if (curline->polyseg == ffloor[i].polyobj)
{
if (ffloor[i].plane->minx > ds_p->x1)
ffloor[i].plane->minx = ds_p->x1;
if (ffloor[i].plane->maxx < ds_p->x2)
ffloor[i].plane->maxx = ds_p->x2;
ffloor[i].b_pos = polysec->floorheight;
ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
i++;
numbackffloors++;
}
if (numbackffloors >= MAXFFLOORS)
break;
if (ffloor[i].polyobj && polysec->ceilingheight >= frontsector->floorheight &&
polysec->ceilingheight <= frontsector->ceilingheight &&
(viewz > polysec->ceilingheight))
{
if (ffloor[i].plane->minx > ds_p->x1)
ffloor[i].plane->minx = ds_p->x1;
if (ffloor[i].plane->maxx < ds_p->x2)
ffloor[i].plane->maxx = ds_p->x2;
ffloor[i].b_pos = polysec->ceilingheight;
ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4;
ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos);
ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale);
numbackffloors++;
}
}
@ -2693,21 +2718,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
for (i = 0; i < numffloors; i++)
R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1);
}
// FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red
if (curline->polyseg)
{
for (i = 0; i < numffloors; i++)
{
if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg)
continue;
if (ffloor[i].plane->minx > rw_x)
ffloor[i].plane->minx = rw_x;
if (ffloor[i].plane->maxx < rw_stopx - 1)
ffloor[i].plane->maxx = rw_stopx - 1;
}
}
}
rw_silhouette = &(ds_p->silhouette);