// 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); };