mirror of
https://github.com/ZDoom/zdbsp.git
synced 2024-11-24 12:51:24 +00:00
24d4f0b45c
SVN r12 (trunk)
211 lines
4.9 KiB
C++
211 lines
4.9 KiB
C++
// A slight adaptation of Quake's vis utility.
|
|
|
|
#include "zdbsp.h"
|
|
#include "tarray.h"
|
|
#include "doomdata.h"
|
|
|
|
class FRejectBuilder
|
|
{
|
|
public:
|
|
FRejectBuilder (FLevel &level);
|
|
~FRejectBuilder ();
|
|
|
|
BYTE *GetReject ();
|
|
|
|
private:
|
|
void BuildReject ();
|
|
void LoadPortals ();
|
|
inline const WideVertex *GetVertex (WORD vertnum);
|
|
FLevel &Level;
|
|
|
|
/* Looky! Stuff from vis.h: */
|
|
|
|
// seperator caching helps a bit
|
|
//#define SEPERATORCACHE
|
|
|
|
// can't have more seperators than the max number of points on a winding
|
|
static const int MAX_SEPERATORS = 2;
|
|
static const int MAX_PORTALS = 65536*2/3;
|
|
static const int MAX_MAP_LEAFS = 32768;
|
|
static const int MAX_PORTALS_ON_LEAF = MAX_PORTALS;
|
|
|
|
struct FPoint
|
|
{
|
|
fixed_t x, y;
|
|
|
|
const FPoint &operator= (const WideVertex *other)
|
|
{
|
|
x = other->x;
|
|
y = other->y;
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
struct FLine : public FPoint
|
|
{
|
|
fixed_t dx, dy;
|
|
|
|
void Flip ()
|
|
{
|
|
x += dx;
|
|
y += dy;
|
|
dx = -dx;
|
|
dy = -dy;
|
|
}
|
|
};
|
|
|
|
struct FWinding
|
|
{
|
|
FPoint points[2];
|
|
};
|
|
|
|
struct FPassage
|
|
{
|
|
FPassage *next;
|
|
BYTE cansee[1]; //all portals that can be seen through this passage
|
|
};
|
|
|
|
enum VStatus
|
|
{
|
|
STAT_None,
|
|
STAT_Working,
|
|
STAT_Done
|
|
};
|
|
|
|
struct VPortal
|
|
{
|
|
bool removed;
|
|
bool hint;
|
|
FLine line; // neighbor is on front/right side
|
|
int leaf; // neighbor
|
|
|
|
FWinding winding;
|
|
VStatus status;
|
|
BYTE *portalfront; // [portals], preliminary
|
|
BYTE *portalflood; // [portals], intermediate
|
|
BYTE *portalvis; // [portals], final
|
|
|
|
int nummightsee; // bit count on portalflood for sort
|
|
FPassage *passages; // there are just as many passages as there
|
|
// are portals in the leaf this portal leads to
|
|
};
|
|
|
|
struct FLeaf
|
|
{
|
|
FLeaf ();
|
|
~FLeaf ();
|
|
|
|
int numportals;
|
|
int merged;
|
|
VPortal **portals;
|
|
};
|
|
|
|
struct PStack
|
|
{
|
|
BYTE mightsee[MAX_PORTALS/8]; // bit string
|
|
PStack *next;
|
|
FLeaf *leaf;
|
|
VPortal *portal; // portal exiting
|
|
FWinding *source;
|
|
FWinding *pass;
|
|
|
|
FWinding windings[3]; // source, pass, temp in any order
|
|
bool freewindings[3];
|
|
|
|
FLine portalline;
|
|
int depth;
|
|
#ifdef SEPERATORCACHE
|
|
FLine seperators[2][MAX_SEPERATORS];
|
|
int numseperators[2];
|
|
#endif
|
|
};
|
|
|
|
struct FThreadData
|
|
{
|
|
VPortal *base;
|
|
int c_chains;
|
|
PStack pstack_head;
|
|
};
|
|
|
|
int numportals;
|
|
int portalclusters;
|
|
|
|
VPortal *portals;
|
|
FLeaf *leafs;
|
|
|
|
int c_portaltest, c_portalpass, c_portalcheck;
|
|
int c_portalskip, c_leafskip;
|
|
int c_vistest, c_mighttest;
|
|
int c_chains;
|
|
|
|
int testlevel;
|
|
|
|
BYTE *uncompressed;
|
|
|
|
int leafbytes, leaflongs;
|
|
int portalbytes, portallongs;
|
|
|
|
int numVisBytes;
|
|
BYTE *visBytes;
|
|
|
|
int totalvis;
|
|
|
|
void LeafFlow (int leafnum);
|
|
|
|
void BasePortalVis (int portalnum);
|
|
void BetterPortalVis (int portalnum);
|
|
void PortalFlow (int portalnum);
|
|
void PassagePortalFlow (int portalnum);
|
|
void CreatePassages (int portalnum);
|
|
void PassageFlow (int portalnum);
|
|
|
|
VPortal *sorted_portals[65536];
|
|
|
|
static int CountBits (BYTE *bits, int numbits);
|
|
|
|
void SortPortals ();
|
|
static int PComp (const void *a, const void *b);
|
|
int LeafVectorFromPortalVector (BYTE *portalbits, BYTE *leafbits);
|
|
void ClusterMerge (int leafnum);
|
|
|
|
void PassageMemory ();
|
|
void CalcFastVis ();
|
|
void CalcVis ();
|
|
void CalcPortalVis ();
|
|
void CalcPassagePortalVis ();
|
|
|
|
int CountActivePortals ();
|
|
|
|
bool pacifier;
|
|
int workcount;
|
|
int dispatch;
|
|
int oldf;
|
|
int oldcount;
|
|
|
|
void RunThreadsOnIndividual (int workcnt, bool showpacifire, void (FRejectBuilder::*func)(int));
|
|
int GetThreadWork ();
|
|
|
|
void CheckStack (FLeaf *leaf, FThreadData *thread);
|
|
|
|
FWinding *AllocStackWinding (PStack *stack) const;
|
|
void FreeStackWinding (FWinding *w, PStack *stack) const;
|
|
|
|
FWinding *VisChopWinding (FWinding *in, PStack *stack, FLine *split);
|
|
FWinding *ClipToSeperators (FWinding *source, FWinding *pass, FWinding *target, bool flipclip, PStack *stack);
|
|
void RecursiveLeafFlow (int leafnum, FThreadData *thread, PStack *prevstack);
|
|
void RecursivePassageFlow (VPortal *portal, FThreadData *thread, PStack *prevstack);
|
|
void RecursivePassagePortalFlow (VPortal *portal, FThreadData *thread, PStack *prevstack);
|
|
FWinding *PassageChopWinding (FWinding *in, FWinding *out, FLine *split);
|
|
int AddSeperators (FWinding *source, FWinding *pass, bool flipclip, FLine *seperators, int maxseperators);
|
|
void SimpleFlood (VPortal *srcportal, int leafnum);
|
|
void RecursiveLeafBitFlow (int leafnum, BYTE *mightsee, BYTE *cansee);
|
|
|
|
int PointOnSide (const FPoint &point, const FLine &line);
|
|
|
|
bool TryMergeLeaves (int l1num, int l2num);
|
|
void UpdatePortals ();
|
|
void MergeLeaves ();
|
|
FWinding *TryMergeWinding (FWinding *f1, FWinding *f2, const FLine &line);
|
|
void MergeLeafPortals ();
|
|
bool Winding_PlanesConcave (const FWinding *w1, const FWinding *w2, const FLine &line1, const FLine &line2);
|
|
};
|