mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
Use set functions for qfvis.
While noticeably slower than the previous expanded set manipulation code, this is much easier to read. I can worry about optimizing the set code when I get qfvis behaving better.
This commit is contained in:
parent
eb2828e11c
commit
299ff8f575
4 changed files with 38 additions and 39 deletions
|
@ -43,6 +43,8 @@ extern pthread_mutex_t *my_mutex;
|
|||
#define UNLOCK
|
||||
#endif
|
||||
|
||||
#include "QF/set.h"
|
||||
|
||||
#define MAX_PORTALS 32768
|
||||
#define PORTALFILE "PRT1"
|
||||
#define PORTALFILE_AM "PRT1-AM"
|
||||
|
@ -68,8 +70,8 @@ typedef struct {
|
|||
int cluster; // neighbor
|
||||
winding_t *winding;
|
||||
vstatus_t status;
|
||||
byte *visbits;
|
||||
byte *mightsee;
|
||||
set_t *visbits;
|
||||
set_t *mightsee;
|
||||
int nummightsee;
|
||||
int numcansee;
|
||||
} portal_t;
|
||||
|
@ -98,11 +100,11 @@ typedef struct pstack_s {
|
|||
portal_t *portal; // portal exiting
|
||||
winding_t *source, *pass;
|
||||
plane_t portalplane;
|
||||
byte *mightsee; // bit string
|
||||
set_t *mightsee;
|
||||
} pstack_t;
|
||||
|
||||
typedef struct {
|
||||
byte *clustervis; // bit string
|
||||
set_t *clustervis;
|
||||
portal_t *base;
|
||||
pstack_t pstack_head;
|
||||
} threaddata_t;
|
||||
|
|
|
@ -71,9 +71,9 @@ SimpleFlood (portal_t *srcportal, int clusternum)
|
|||
cluster_t *cluster;
|
||||
portal_t *portal;
|
||||
|
||||
if (srcportal->mightsee[clusternum >> 3] & (1 << (clusternum & 7)))
|
||||
if (set_is_member (srcportal->mightsee, clusternum))
|
||||
return;
|
||||
srcportal->mightsee[clusternum >> 3] |= (1 << (clusternum & 7));
|
||||
set_add (srcportal->mightsee, clusternum);
|
||||
clustersee++;
|
||||
|
||||
cluster = &clusters[clusternum];
|
||||
|
@ -95,7 +95,7 @@ BasePortalVis (void)
|
|||
winding_t *winding;
|
||||
|
||||
for (i = 0, portal = portals; i < numportals * 2; i++, portal++) {
|
||||
portal->mightsee = calloc (1, bitbytes);
|
||||
portal->mightsee = set_new_size (portalclusters);
|
||||
|
||||
memset (portalsee, 0, numportals * 2);
|
||||
|
||||
|
|
|
@ -196,8 +196,8 @@ ClipToSeparators (winding_t *source, winding_t *pass, winding_t *target,
|
|||
static void
|
||||
RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||
{
|
||||
int i, j;
|
||||
long *test, *might, *vis;
|
||||
int i;
|
||||
set_t *test, *might, *vis;
|
||||
qboolean more;
|
||||
cluster_t *cluster;
|
||||
pstack_t stack;
|
||||
|
@ -212,8 +212,8 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
|||
return;
|
||||
|
||||
// mark the cluster as visible
|
||||
if (!(thread->clustervis[clusternum >> 3] & (1 << (clusternum & 7)))) {
|
||||
thread->clustervis[clusternum >> 3] |= 1 << (clusternum & 7);
|
||||
if (!set_is_member (thread->clustervis, clusternum)) {
|
||||
set_add (thread->clustervis, clusternum);
|
||||
thread->base->numcansee++;
|
||||
}
|
||||
|
||||
|
@ -221,31 +221,29 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
|||
stack.next = NULL;
|
||||
stack.cluster = cluster;
|
||||
stack.portal = NULL;
|
||||
stack.mightsee = malloc(bitbytes);
|
||||
might = (long *) stack.mightsee;
|
||||
vis = (long *) thread->clustervis;
|
||||
LOCK;
|
||||
stack.mightsee = set_new_size (portalclusters);
|
||||
UNLOCK;
|
||||
might = stack.mightsee;
|
||||
vis = thread->clustervis;
|
||||
|
||||
// check all portals for flowing into other clusters
|
||||
for (i = 0; i < cluster->numportals; i++) {
|
||||
portal = cluster->portals[i];
|
||||
|
||||
if (!(prevstack->mightsee[portal->cluster >> 3]
|
||||
& (1 << (portal->cluster & 7))))
|
||||
if (!set_is_member (prevstack->mightsee, portal->cluster))
|
||||
continue; // can't possibly see it
|
||||
// if the portal can't see anything we haven't already seen, skip it
|
||||
if (portal->status == stat_done) {
|
||||
c_vistest++;
|
||||
test = (long *) portal->visbits;
|
||||
test = portal->visbits;
|
||||
} else {
|
||||
c_mighttest++;
|
||||
test = (long *) portal->mightsee;
|
||||
}
|
||||
more = false;
|
||||
for (j = 0; j < bitlongs; j++) {
|
||||
might[j] = ((long *) prevstack->mightsee)[j] & test[j];
|
||||
if (might[j] & ~vis[j])
|
||||
more = true;
|
||||
test = portal->mightsee;
|
||||
}
|
||||
set_assign (might, prevstack->mightsee);
|
||||
set_intersection (might, test);
|
||||
more = !set_is_subset (might, vis);
|
||||
|
||||
if (!more) // can't see anything new
|
||||
continue;
|
||||
|
@ -347,7 +345,9 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
|||
FreeWinding (target);
|
||||
}
|
||||
|
||||
free (stack.mightsee);
|
||||
LOCK;
|
||||
set_delete (stack.mightsee);
|
||||
UNLOCK;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -359,10 +359,9 @@ PortalFlow (portal_t *portal)
|
|||
if (portal->status != stat_selected)
|
||||
Sys_Error ("PortalFlow: reflowed");
|
||||
portal->status = stat_working;
|
||||
portal->visbits = set_new_size (portalclusters);
|
||||
UNLOCK;
|
||||
|
||||
portal->visbits = calloc (1, bitbytes);
|
||||
|
||||
memset (&data, 0, sizeof (data));
|
||||
data.clustervis = portal->visbits;
|
||||
data.base = portal;
|
||||
|
|
|
@ -371,12 +371,12 @@ CompressRow (byte *vis, byte *dest)
|
|||
}
|
||||
|
||||
static void
|
||||
ClusterFlowExpand (byte *src, byte *dest)
|
||||
ClusterFlowExpand (const set_t *src, byte *dest)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 1, i = 0; i < numrealleafs; i++) {
|
||||
if (src[leafcluster[i] >> 3] & (1 << (leafcluster[i] & 7)))
|
||||
if (set_is_member (src, leafcluster[i]))
|
||||
*dest |= j;
|
||||
j <<= 1;
|
||||
if (j == 256) {
|
||||
|
@ -394,9 +394,10 @@ ClusterFlowExpand (byte *src, byte *dest)
|
|||
void
|
||||
ClusterFlow (int clusternum)
|
||||
{
|
||||
set_t *visclusters;
|
||||
byte compressed[MAX_MAP_LEAFS / 8];
|
||||
byte *outbuffer;
|
||||
int numvis, i, j;
|
||||
int numvis, i;
|
||||
cluster_t *cluster;
|
||||
portal_t *portal;
|
||||
|
||||
|
@ -406,26 +407,23 @@ ClusterFlow (int clusternum)
|
|||
// flow through all portals, collecting visible bits
|
||||
|
||||
memset (compressed, 0, sizeof (compressed));
|
||||
visclusters = set_new ();
|
||||
for (i = 0; i < cluster->numportals; i++) {
|
||||
portal = cluster->portals[i];
|
||||
if (portal->status != stat_done)
|
||||
Sys_Error ("portal not done");
|
||||
for (j = 0; j < bitbytes; j++)
|
||||
compressed[j] |= portal->visbits[j];
|
||||
set_union (visclusters, portal->visbits);
|
||||
}
|
||||
|
||||
if (compressed[clusternum >> 3] & (1 << (clusternum & 7)))
|
||||
if (set_is_member (visclusters, clusternum))
|
||||
Sys_Error ("Cluster portals saw into cluster");
|
||||
|
||||
compressed[clusternum >> 3] |= (1 << (clusternum & 7));
|
||||
set_add (visclusters, clusternum);
|
||||
|
||||
numvis = 0;
|
||||
for (i = 0; i < portalclusters; i++)
|
||||
if (compressed[i >> 3] & (1 << (i & 3)))
|
||||
numvis++;
|
||||
numvis = set_size (visclusters);
|
||||
|
||||
// expand to cluster->leaf PVS
|
||||
ClusterFlowExpand (compressed, outbuffer);
|
||||
ClusterFlowExpand (visclusters, outbuffer);
|
||||
|
||||
// compress the bit string
|
||||
if (options.verbosity > 0)
|
||||
|
|
Loading…
Reference in a new issue