- Use a flood-fill algorithm to define polyobjects with PolyObj_StartLine instead of a simple

loop-following algorithm. This fixes the polyobjects in http://www.doomworld.com/idgames/index.php?id=6291

SVN r2482 (trunk)
This commit is contained in:
Randy Heit 2010-08-01 05:16:09 +00:00
parent 8ce9e178d4
commit 58269a18f0
3 changed files with 69 additions and 44 deletions

View file

@ -128,27 +128,8 @@ FLightStack* LightStacks;
TArray<FMapThing> MapThingsConverted; TArray<FMapThing> MapThingsConverted;
int sidecount; int sidecount;
struct sidei_t // [RH] Only keep BOOM sidedef init stuff around for init sidei_t *sidetemp;
{
union
{
// Used when unpacking sidedefs and assigning
// properties based on linedefs.
struct
{
short tag, special;
short alpha;
DWORD map;
} a;
// Used when grouping sidedefs into loops.
struct
{
DWORD first, next;
char lineside;
} b;
};
} *sidetemp;
TArray<int> linemap; TArray<int> linemap;
bool UsingGLNodes; bool UsingGLNodes;
@ -2261,9 +2242,8 @@ static void P_LoopSidedefs ()
sides[right].LeftSide = i; sides[right].LeftSide = i;
} }
// Throw away sidedef init info now that we're done with it // We keep the sidedef init info around until after polyobjects are initialized,
delete[] sidetemp; // so don't delete just yet.
sidetemp = NULL;
} }
int P_DetermineTranslucency (int lumpnum) int P_DetermineTranslucency (int lumpnum)
@ -3866,6 +3846,10 @@ void P_SetupLevel (char *lumpname, int position)
PO_Init (); // Initialize the polyobjs PO_Init (); // Initialize the polyobjs
times[16].Unclock(); times[16].Unclock();
assert(sidetemp != NULL);
delete[] sidetemp;
sidetemp = NULL;
// if deathmatch, randomly spawn the active players // if deathmatch, randomly spawn the active players
if (deathmatch) if (deathmatch)
{ {

View file

@ -111,4 +111,27 @@ int P_TranslateSectorSpecial (int);
int GetUDMFInt(int type, int index, const char *key); int GetUDMFInt(int type, int index, const char *key);
fixed_t GetUDMFFixed(int type, int index, const char *key); fixed_t GetUDMFFixed(int type, int index, const char *key);
struct sidei_t // [RH] Only keep BOOM sidedef init stuff around for init
{
union
{
// Used when unpacking sidedefs and assigning
// properties based on linedefs.
struct
{
short tag, special;
short alpha;
DWORD map;
} a;
// Used when grouping sidedefs into loops.
struct
{
DWORD first, next;
char lineside;
} b;
};
};
extern sidei_t *sidetemp;
#endif #endif

View file

@ -27,6 +27,7 @@
#include "r_interpolate.h" #include "r_interpolate.h"
#include "g_level.h" #include "g_level.h"
#include "po_man.h" #include "po_man.h"
#include "p_setup.h"
// MACROS ------------------------------------------------------------------ // MACROS ------------------------------------------------------------------
@ -1334,41 +1335,58 @@ static void KillSideLists ()
KnownPolySides.ShrinkToFit (); KnownPolySides.ShrinkToFit ();
} }
//==========================================================================
//
// AddPolyVert
//
// Helper function for IterFindPolySides()
//
//==========================================================================
static void AddPolyVert(TArray<DWORD> &vnum, DWORD vert)
{
for (unsigned int i = vnum.Size() - 1; i-- != 0; )
{
if (vnum[i] == vert)
{ // Already in the set. No need to add it.
return;
}
}
vnum.Push(vert);
}
//========================================================================== //==========================================================================
// //
// IterFindPolySides // IterFindPolySides
// //
// Beginning with the first vertex of the starting side, for each vertex
// in vnum, add all the sides that use it as a first vertex to the polyobj,
// and add all their second vertices to vnum. This continues until there
// are no new vertices in vnum.
//
//========================================================================== //==========================================================================
static void IterFindPolySides (FPolyObj *po, side_t *side) static void IterFindPolySides (FPolyObj *po, side_t *side)
{ {
SDWORD j; static TArray<DWORD> vnum;
int i; unsigned int vnumat;
vertex_t *v1 = side->V1();
po->Sidedefs.Push(side); assert(sidetemp != NULL);
// This for loop exists solely to avoid infinitely looping on badly vnum.Clear();
// formed polyobjects. vnum.Push(DWORD(side->V1() - vertexes));
for (i = 0; i < numsides; i++) vnumat = 0;
while (vnum.Size() != vnumat)
{ {
int v2 = int(side->V2() - vertexes); DWORD sidenum = sidetemp[vnum[vnumat++]].b.first;
j = side->RightSide; while (sidenum != NO_SIDE)
if (j == NO_SIDE)
{ {
break; po->Sidedefs.Push(&sides[sidenum]);
AddPolyVert(vnum, DWORD(sides[sidenum].V2() - vertexes));
sidenum = sidetemp[sidenum].b.next;
} }
side = &sides[j];
if (side->V1() == v1)
{
return;
}
po->Sidedefs.Push(side);
} }
I_Error ("IterFindPolySides: Non-closed Polyobj at linedef %d.\n",
side->linedef-lines);
} }