mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-26 13:51:15 +00:00
- 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:
parent
828bb723e5
commit
1db702fb4a
7 changed files with 83 additions and 84 deletions
|
@ -112,11 +112,10 @@ void FNodeBuilder::Clear()
|
||||||
Touched.Clear();
|
Touched.Clear();
|
||||||
Colinear.Clear();
|
Colinear.Clear();
|
||||||
SplitSharers.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 ()
|
void FNodeBuilder::BuildTree ()
|
||||||
|
|
|
@ -91,7 +91,17 @@ class FNodeBuilder
|
||||||
};
|
};
|
||||||
|
|
||||||
// Like a blockmap, but for vertices instead of lines
|
// 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:
|
public:
|
||||||
FVertexMap (FNodeBuilder &builder, fixed_t minx, fixed_t miny, fixed_t maxx, fixed_t maxy);
|
FVertexMap (FNodeBuilder &builder, fixed_t minx, fixed_t miny, fixed_t maxx, fixed_t maxy);
|
||||||
|
@ -119,12 +129,23 @@ class FNodeBuilder
|
||||||
assert (y <= MaxY);
|
assert (y <= MaxY);
|
||||||
return (unsigned(x - MinX) >> BLOCK_SHIFT) + (unsigned(y - MinY) >> BLOCK_SHIFT) * BlocksWide;
|
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 FVertexMap;
|
||||||
|
friend class FVertexMapSimple;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct FLevel
|
struct FLevel
|
||||||
|
@ -178,7 +199,7 @@ public:
|
||||||
static inline int PointOnSide (int x, int y, int x1, int y1, int dx, int dy);
|
static inline int PointOnSide (int x, int y, int x1, int y1, int dx, int dy);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FVertexMap *VertexMap;
|
IVertexMap *VertexMap;
|
||||||
|
|
||||||
TArray<node_t> Nodes;
|
TArray<node_t> Nodes;
|
||||||
TArray<subsector_t> Subsectors;
|
TArray<subsector_t> Subsectors;
|
||||||
|
|
|
@ -588,6 +588,10 @@ void FNodeBuilder::FLevel::FindMapBounds ()
|
||||||
MaxY = maxy;
|
MaxY = maxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FNodeBuilder::IVertexMap::~IVertexMap()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder,
|
FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder,
|
||||||
fixed_t minx, fixed_t miny, fixed_t maxx, fixed_t maxy)
|
fixed_t minx, fixed_t miny, fixed_t maxx, fixed_t maxy)
|
||||||
: MyBuilder(builder)
|
: MyBuilder(builder)
|
||||||
|
@ -687,3 +691,52 @@ int FNodeBuilder::FVertexMap::InsertVertex (FNodeBuilder::FPrivVert &vert)
|
||||||
|
|
||||||
return vertnum;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ struct FPolyNode
|
||||||
FPolyNode *snext; // next subsector
|
FPolyNode *snext; // next subsector
|
||||||
|
|
||||||
TArray<FPolySeg> segs; // segs for this node
|
TArray<FPolySeg> segs; // segs for this node
|
||||||
fixed_t dist; // distance for sorting
|
|
||||||
int state;
|
int state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1027,30 +1027,6 @@ FMiniBSP::FMiniBSP()
|
||||||
bDirty = false;
|
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
|
// 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");
|
assert((sub->BSP == NULL || sub->BSP->bDirty) && "BSP computed more than once");
|
||||||
|
|
||||||
// Set up level information for the node builder.
|
// Set up level information for the node builder.
|
||||||
PolyNodeLevel.ResetMapBounds();
|
|
||||||
PolyNodeLevel.Sides = sides;
|
PolyNodeLevel.Sides = sides;
|
||||||
PolyNodeLevel.NumSides = numsides;
|
PolyNodeLevel.NumSides = numsides;
|
||||||
PolyNodeLevel.Lines = lines;
|
PolyNodeLevel.Lines = lines;
|
||||||
PolyNodeLevel.NumLines = numlines;
|
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.
|
// Feed segs to the nodebuilder and build the nodes.
|
||||||
PolyNodeBuilder.Clear();
|
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);
|
void R_Subsector (subsector_t *sub);
|
||||||
static void R_AddPolyobjs(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());
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1772,7 +1772,7 @@ IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool)
|
||||||
|
|
||||||
assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT);
|
assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT);
|
||||||
|
|
||||||
if (FAILED(FrontCopySurface->GetDesc(&desc)))
|
if (FrontCopySurface == NULL || FAILED(FrontCopySurface->GetDesc(&desc)))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue