- Merge BSP-able polyobjects back into the trunk.

SVN r2480 (trunk)
This commit is contained in:
Randy Heit 2010-08-01 02:41:56 +00:00
commit 677d07f837
17 changed files with 1171 additions and 739 deletions

View file

@ -142,6 +142,9 @@ static void TranslateToStartSpot (int tag, int originX, int originY);
static void DoMovePolyobj (FPolyObj *po, int x, int y);
static void InitSegLists ();
static void KillSegLists ();
static FPolyNode *NewPolyNode();
static void FreePolyNode();
static void ReleaseAllPolyNodes();
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
@ -157,6 +160,7 @@ polyspawns_t *polyspawns; // [RH] Let P_SpawnMapThings() find our thingies for u
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static TArray<SDWORD> KnownPolySides;
static FPolyNode *FreePolyNodes;
// CODE --------------------------------------------------------------------
@ -758,7 +762,6 @@ FPolyObj::FPolyObj()
subsectorlinks = NULL;
specialdata = NULL;
interpolation = NULL;
SVIndex = -1;
}
//==========================================================================
@ -1279,20 +1282,6 @@ void FPolyObj::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy, si
}
}
vertex_t *FPolyObj::GetNewVertex()
{
if (SVIndex == ~0u || SplitVertices[SVIndex]->used == 10)
{
SVIndex++;
if (SVIndex >= SplitVertices.Size())
{
SplitVertices.Push(new FPolyVertexBlock);
}
SplitVertices[SVIndex]->clear();
}
return &SplitVertices[SVIndex]->vertices[SplitVertices[SVIndex]->used++];
}
//==========================================================================
//
// InitBlockMap
@ -1699,11 +1688,6 @@ bool PO_Busy (int polyobj)
void FPolyObj::ClearSubsectorLinks()
{
for(unsigned i=0; i<SplitVertices.Size(); i++)
{
SplitVertices[i]->clear();
}
SVIndex = -1;
while (subsectorlinks != NULL)
{
assert(subsectorlinks->state == 1337);
@ -1725,6 +1709,12 @@ void FPolyObj::ClearSubsectorLinks()
{
subsectorlinks->subsector->polys = subsectorlinks->pnext;
}
if (subsectorlinks->subsector->BSP != NULL)
{
subsectorlinks->subsector->BSP->bDirty = true;
}
subsectorlinks->state = -1;
delete subsectorlinks;
subsectorlinks = next;
@ -1734,10 +1724,11 @@ void FPolyObj::ClearSubsectorLinks()
void FPolyObj::ClearAllSubsectorLinks()
{
for(int i=0;i<po_NumPolyobjs;i++)
for (int i = 0; i < po_NumPolyobjs; i++)
{
polyobjs[i].ClearSubsectorLinks();
}
ReleaseAllPolyNodes();
}
//==========================================================================
@ -1748,16 +1739,16 @@ void FPolyObj::ClearAllSubsectorLinks()
//
//==========================================================================
static bool GetIntersection(seg_t *seg, node_t *bsp, vertex_t *v)
static bool GetIntersection(FPolySeg *seg, node_t *bsp, FPolyVertex *v)
{
double frac;
double num;
double den;
double v2x = (double)seg->v1->x;
double v2y = (double)seg->v1->y;
double v2dx = (double)(seg->v2->x - seg->v1->x);
double v2dy = (double)(seg->v2->y - seg->v1->y);
double v2x = (double)seg->v1.x;
double v2y = (double)seg->v1.y;
double v2dx = (double)(seg->v2.x - seg->v1.x);
double v2dy = (double)(seg->v2.y - seg->v1.y);
double v1x = (double)bsp->x;
double v1y = (double)bsp->y;
double v1dx = (double)bsp->dx;
@ -1786,7 +1777,7 @@ static bool GetIntersection(seg_t *seg, node_t *bsp, vertex_t *v)
//
//==========================================================================
static double PartitionDistance(vertex_t *vt, node_t *node)
static double PartitionDistance(FPolyVertex *vt, node_t *node)
{
return fabs(double(-node->dy) * (vt->x - node->x) + double(node->dx) * (vt->y - node->y)) / node->len;
}
@ -1823,7 +1814,7 @@ static void AddToBBox(fixed_t child[4], fixed_t parent[4])
//
//==========================================================================
static void AddToBBox(vertex_t *v, fixed_t bbox[4])
static void AddToBBox(FPolyVertex *v, fixed_t bbox[4])
{
if (v->x < bbox[BOXLEFT])
{
@ -1851,7 +1842,7 @@ static void AddToBBox(vertex_t *v, fixed_t bbox[4])
static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
{
static TArray<seg_t> lists[2];
static TArray<FPolySeg> lists[2];
static const double POLY_EPSILON = 0.3125;
if (!((size_t)node & 1)) // Keep going until found a subsector
@ -1864,7 +1855,7 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
lists[1].Clear();
for(unsigned i=0;i<pnode->segs.Size(); i++)
{
seg_t *seg = &pnode->segs[i];
FPolySeg *seg = &pnode->segs[i];
// Parts of the following code were taken from Eternity and are
// being used with permission.
@ -1872,8 +1863,8 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
// get distance of vertices from partition line
// If the distance is too small, we may decide to
// change our idea of sidedness.
double dist_v1 = PartitionDistance(seg->v1, bsp);
double dist_v2 = PartitionDistance(seg->v2, bsp);
double dist_v1 = PartitionDistance(&seg->v1, bsp);
double dist_v2 = PartitionDistance(&seg->v2, bsp);
// If the distances are less than epsilon, consider the points as being
// on the same side as the polyobj origin. Why? People like to build
@ -1894,27 +1885,27 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
}
else
{
int side = R_PointOnSide(seg->v2->x, seg->v2->y, bsp);
int side = R_PointOnSide(seg->v2.x, seg->v2.y, bsp);
lists[side].Push(*seg);
}
}
else if (dist_v2 <= POLY_EPSILON)
{
int side = R_PointOnSide(seg->v1->x, seg->v1->y, bsp);
int side = R_PointOnSide(seg->v1.x, seg->v1.y, bsp);
lists[side].Push(*seg);
}
else
{
int side1 = R_PointOnSide(seg->v1->x, seg->v1->y, bsp);
int side2 = R_PointOnSide(seg->v2->x, seg->v2->y, bsp);
int side1 = R_PointOnSide(seg->v1.x, seg->v1.y, bsp);
int side2 = R_PointOnSide(seg->v2.x, seg->v2.y, bsp);
if(side1 != side2)
{
// if the partition line crosses this seg, we must split it.
vertex_t *vert = pnode->poly->GetNewVertex();
FPolyVertex vert;
if (GetIntersection(seg, bsp, vert))
if (GetIntersection(seg, bsp, &vert))
{
lists[0].Push(*seg);
lists[1].Push(*seg);
@ -1947,13 +1938,8 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
else
{
// create the new node
FPolyNode *newnode = new FPolyNode;
newnode->state = 1337;
FPolyNode *newnode = NewPolyNode();
newnode->poly = pnode->poly;
newnode->pnext = NULL;
newnode->pprev = NULL;
newnode->subsector = NULL;
newnode->snext = NULL;
newnode->segs = lists[1];
// set segs for original node
@ -1995,8 +1981,8 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
for (unsigned i = 0; i < pnode->segs.Size(); ++i)
{
AddToBBox(pnode->segs[i].v1, subbbox);
AddToBBox(pnode->segs[i].v2, subbbox);
AddToBBox(&pnode->segs[i].v1, subbbox);
AddToBBox(&pnode->segs[i].v2, subbbox);
}
// Potentially expand the parent node's bounding box to contain these bits of polyobject.
AddToBBox(subbbox, bbox);
@ -2011,31 +1997,23 @@ static void SplitPoly(FPolyNode *pnode, void *node, fixed_t bbox[4])
void FPolyObj::CreateSubsectorLinks()
{
FPolyNode *node = new FPolyNode;
fixed_t dummybbox[4];
FPolyNode *node = NewPolyNode();
// Even though we don't care about it, we need to initialize this
// bounding box to something so that Valgrind won't complain about it
// when SplitPoly modifies it.
fixed_t dummybbox[4] = { 0 };
node->state = 1337;
node->poly = this;
node->pnext = NULL;
node->pprev = NULL;
node->snext = NULL;
node->segs.Resize(Sidedefs.Size());
for(unsigned i=0; i<Sidedefs.Size(); i++)
{
seg_t *seg = &node->segs[i];
FPolySeg *seg = &node->segs[i];
side_t *side = Sidedefs[i];
seg->v1 = side->V1();
seg->v2 = side->V2();
seg->sidedef = side;
seg->linedef = side->linedef;
seg->frontsector = side->sector;
seg->backsector = side->linedef->frontsector == side->sector?
side->linedef->backsector : side->linedef->frontsector;
seg->Subsector = NULL;
seg->PartnerSeg = NULL;
seg->bPolySeg = true;
seg->wall = side;
}
SplitPoly(node, nodes + numnodes - 1, dummybbox);
}
@ -2055,4 +2033,62 @@ void PO_LinkToSubsectors()
polyobjs[i].CreateSubsectorLinks();
}
}
}
}
//==========================================================================
//
// NewPolyNode
//
//==========================================================================
static FPolyNode *NewPolyNode()
{
FPolyNode *node;
if (FreePolyNodes != NULL)
{
node = FreePolyNodes;
FreePolyNodes = node->pnext;
}
else
{
node = new FPolyNode;
}
node->state = 1337;
node->poly = NULL;
node->pnext = NULL;
node->pprev = NULL;
node->subsector = NULL;
node->snext = NULL;
return node;
}
//==========================================================================
//
// FreePolyNode
//
//==========================================================================
void FreePolyNode(FPolyNode *node)
{
node->segs.Clear();
node->pnext = FreePolyNodes;
FreePolyNodes = node;
}
//==========================================================================
//
// ReleaseAllPolyNodes
//
//==========================================================================
void ReleaseAllPolyNodes()
{
FPolyNode *node, *next;
for (node = FreePolyNodes; node != NULL; node = next)
{
next = node->pnext;
delete node;
}
}