- Remove old polyobject sorting code.

- Use a simple linear scan vertex map for building mini-BSPs. This saves us from having to
  calculate the needed dimensions, and don't need to reallocate it for each run. The standard
  vertex map was meant for large areas, which a subsector containing polyobject fragments is
  unlikely to be.

SVN r2475 (polyobjects)
This commit is contained in:
Randy Heit 2010-07-30 03:50:56 +00:00
parent 828bb723e5
commit 1db702fb4a
7 changed files with 83 additions and 84 deletions

View file

@ -112,11 +112,10 @@ void FNodeBuilder::Clear()
Touched.Clear();
Colinear.Clear();
SplitSharers.Clear();
if (VertexMap != NULL)
if (VertexMap == NULL)
{
delete VertexMap;
VertexMap = new FVertexMapSimple(*this);
}
VertexMap = new FVertexMap(*this, Level.MinX, Level.MinY, Level.MaxX, Level.MaxY);
}
void FNodeBuilder::BuildTree ()

View file

@ -91,7 +91,17 @@ class FNodeBuilder
};
// Like a blockmap, but for vertices instead of lines
class FVertexMap
class IVertexMap
{
public:
virtual ~IVertexMap();
virtual int SelectVertexExact(FPrivVert &vert) = 0;
virtual int SelectVertexClose(FPrivVert &vert) = 0;
private:
IVertexMap &operator=(const IVertexMap &);
};
class FVertexMap : public IVertexMap
{
public:
FVertexMap (FNodeBuilder &builder, fixed_t minx, fixed_t miny, fixed_t maxx, fixed_t maxy);
@ -119,12 +129,23 @@ class FNodeBuilder
assert (y <= MaxY);
return (unsigned(x - MinX) >> BLOCK_SHIFT) + (unsigned(y - MinY) >> BLOCK_SHIFT) * BlocksWide;
}
};
FVertexMap &operator= (const FVertexMap &) { return *this; }
class FVertexMapSimple : public IVertexMap
{
public:
FVertexMapSimple(FNodeBuilder &builder);
int SelectVertexExact(FPrivVert &vert);
int SelectVertexClose(FPrivVert &vert);
private:
int InsertVertex(FPrivVert &vert);
FNodeBuilder &MyBuilder;
};
friend class FVertexMap;
friend class FVertexMapSimple;
public:
struct FLevel
@ -178,7 +199,7 @@ public:
static inline int PointOnSide (int x, int y, int x1, int y1, int dx, int dy);
private:
FVertexMap *VertexMap;
IVertexMap *VertexMap;
TArray<node_t> Nodes;
TArray<subsector_t> Subsectors;

View file

@ -588,6 +588,10 @@ void FNodeBuilder::FLevel::FindMapBounds ()
MaxY = maxy;
}
FNodeBuilder::IVertexMap::~IVertexMap()
{
}
FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder,
fixed_t minx, fixed_t miny, fixed_t maxx, fixed_t maxy)
: MyBuilder(builder)
@ -687,3 +691,52 @@ int FNodeBuilder::FVertexMap::InsertVertex (FNodeBuilder::FPrivVert &vert)
return vertnum;
}
FNodeBuilder::FVertexMapSimple::FVertexMapSimple(FNodeBuilder &builder)
: MyBuilder(builder)
{
}
int FNodeBuilder::FVertexMapSimple::SelectVertexExact(FNodeBuilder::FPrivVert &vert)
{
FPrivVert *verts = &MyBuilder.Vertices[0];
unsigned int stop = MyBuilder.Vertices.Size();
for (unsigned int i = 0; i < stop; ++i)
{
if (verts[i].x == vert.x && verts[i].y == vert.y)
{
return i;
}
}
// Not present: add it!
return InsertVertex(vert);
}
int FNodeBuilder::FVertexMapSimple::SelectVertexClose(FNodeBuilder::FPrivVert &vert)
{
FPrivVert *verts = &MyBuilder.Vertices[0];
unsigned int stop = MyBuilder.Vertices.Size();
for (unsigned int i = 0; i < stop; ++i)
{
#if VERTEX_EPSILON <= 1
if (verts[i].x == vert.x && verts[i].y == y)
#else
if (abs(verts[i].x - vert.x) < VERTEX_EPSILON &&
abs(verts[i].y - vert.y) < VERTEX_EPSILON)
#endif
{
return i;
}
}
// Not present: add it!
return InsertVertex (vert);
}
int FNodeBuilder::FVertexMapSimple::InsertVertex (FNodeBuilder::FPrivVert &vert)
{
vert.segs = DWORD_MAX;
vert.segs2 = DWORD_MAX;
return (int)MyBuilder.Vertices.Push (vert);
}

View file

@ -39,7 +39,6 @@ struct FPolyNode
FPolyNode *snext; // next subsector
TArray<FPolySeg> segs; // segs for this node
fixed_t dist; // distance for sorting
int state;
};

View file

@ -1027,30 +1027,6 @@ FMiniBSP::FMiniBSP()
bDirty = false;
}
//==========================================================================
//
// AddToMiniBBox
//
//==========================================================================
static void AddToMiniBBox(fixed_t v[2])
{
if (v[0] < PolyNodeLevel.MinX) PolyNodeLevel.MinX = v[0];
if (v[0] > PolyNodeLevel.MaxX) PolyNodeLevel.MaxX = v[0];
if (v[1] < PolyNodeLevel.MinY) PolyNodeLevel.MinY = v[1];
if (v[1] > PolyNodeLevel.MaxY) PolyNodeLevel.MaxY = v[1];
}
static void AddToMiniBBox(vertex_t *v)
{
AddToMiniBBox(&v->x);
}
static void AddToMiniBBox(FPolyVertex *v)
{
AddToMiniBBox(&v->x);
}
//==========================================================================
//
// P_BuildPolyBSP
@ -1062,24 +1038,10 @@ static void R_BuildPolyBSP(subsector_t *sub)
assert((sub->BSP == NULL || sub->BSP->bDirty) && "BSP computed more than once");
// Set up level information for the node builder.
PolyNodeLevel.ResetMapBounds();
PolyNodeLevel.Sides = sides;
PolyNodeLevel.NumSides = numsides;
PolyNodeLevel.Lines = lines;
PolyNodeLevel.NumLines = numlines;
for (unsigned int i = 0; i < sub->numlines; ++i)
{
AddToMiniBBox(sub->firstline[i].v1);
AddToMiniBBox(sub->firstline[i].v2);
}
for (FPolyNode *pn = sub->polys; pn != NULL; pn = pn->pnext)
{
for (unsigned int i = 0; i < pn->segs.Size(); ++i)
{
AddToMiniBBox(&pn->segs[i].v1);
AddToMiniBBox(&pn->segs[i].v2);
}
}
// Feed segs to the nodebuilder and build the nodes.
PolyNodeBuilder.Clear();
@ -1104,16 +1066,6 @@ static void R_BuildPolyBSP(subsector_t *sub)
}
}
static int STACK_ARGS polycmp(const void *a, const void *b)
{
const FPolyNode *A = *(FPolyNode **)a;
const FPolyNode *B = *(FPolyNode **)b;
return A->dist - B->dist;
}
void R_Subsector (subsector_t *sub);
static void R_AddPolyobjs(subsector_t *sub)
{
@ -1129,31 +1081,6 @@ static void R_AddPolyobjs(subsector_t *sub)
{
R_RenderBSPNode(&sub->BSP->Nodes.Last());
}
#if 0
static TArray<FPolyNode *> sortedpolys;
FPolyNode *pn = sub->polys;
sortedpolys.Clear();
while (pn != NULL)
{
sortedpolys.Push(pn);
pn->dist = R_PointToDist2(pn->poly->CenterSpot.x - viewx, pn->poly->CenterSpot.y - viewy);
pn = pn->pnext;
}
if (sortedpolys.Size() > 1)
{
qsort(&sortedpolys[0], sortedpolys.Size(), sizeof (sortedpolys[0]), polycmp);
}
for(unsigned i=0; i<sortedpolys.Size(); i++)
{
pn = sortedpolys[i];
for(unsigned j=0; j<pn->segs.Size(); j++)
{
R_AddLine(&pn->segs[j]);
}
}
#endif
}

View file

@ -1489,8 +1489,8 @@ int side_t::GetLightLevel (bool foggy, int baselight, int *pfakecontrast) const
}
else
{
rel = linedef->dx==0? level.WallVertLight :
linedef->dy==0? level.WallHorizLight : 0;
rel = linedef->dx == 0 ? level.WallVertLight :
linedef->dy == 0 ? level.WallHorizLight : 0;
}
if (pfakecontrast != NULL)
{

View file

@ -1772,7 +1772,7 @@ IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool)
assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT);
if (FAILED(FrontCopySurface->GetDesc(&desc)))
if (FrontCopySurface == NULL || FAILED(FrontCopySurface->GetDesc(&desc)))
{
return NULL;
}