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:
Bill Currie 2013-03-07 11:06:55 +09:00
parent eb2828e11c
commit 299ff8f575
4 changed files with 38 additions and 39 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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)