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 #define UNLOCK
#endif #endif
#include "QF/set.h"
#define MAX_PORTALS 32768 #define MAX_PORTALS 32768
#define PORTALFILE "PRT1" #define PORTALFILE "PRT1"
#define PORTALFILE_AM "PRT1-AM" #define PORTALFILE_AM "PRT1-AM"
@ -68,8 +70,8 @@ typedef struct {
int cluster; // neighbor int cluster; // neighbor
winding_t *winding; winding_t *winding;
vstatus_t status; vstatus_t status;
byte *visbits; set_t *visbits;
byte *mightsee; set_t *mightsee;
int nummightsee; int nummightsee;
int numcansee; int numcansee;
} portal_t; } portal_t;
@ -98,11 +100,11 @@ typedef struct pstack_s {
portal_t *portal; // portal exiting portal_t *portal; // portal exiting
winding_t *source, *pass; winding_t *source, *pass;
plane_t portalplane; plane_t portalplane;
byte *mightsee; // bit string set_t *mightsee;
} pstack_t; } pstack_t;
typedef struct { typedef struct {
byte *clustervis; // bit string set_t *clustervis;
portal_t *base; portal_t *base;
pstack_t pstack_head; pstack_t pstack_head;
} threaddata_t; } threaddata_t;

View file

@ -71,9 +71,9 @@ SimpleFlood (portal_t *srcportal, int clusternum)
cluster_t *cluster; cluster_t *cluster;
portal_t *portal; portal_t *portal;
if (srcportal->mightsee[clusternum >> 3] & (1 << (clusternum & 7))) if (set_is_member (srcportal->mightsee, clusternum))
return; return;
srcportal->mightsee[clusternum >> 3] |= (1 << (clusternum & 7)); set_add (srcportal->mightsee, clusternum);
clustersee++; clustersee++;
cluster = &clusters[clusternum]; cluster = &clusters[clusternum];
@ -95,7 +95,7 @@ BasePortalVis (void)
winding_t *winding; winding_t *winding;
for (i = 0, portal = portals; i < numportals * 2; i++, portal++) { 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); memset (portalsee, 0, numportals * 2);

View file

@ -196,8 +196,8 @@ ClipToSeparators (winding_t *source, winding_t *pass, winding_t *target,
static void static void
RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack) RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
{ {
int i, j; int i;
long *test, *might, *vis; set_t *test, *might, *vis;
qboolean more; qboolean more;
cluster_t *cluster; cluster_t *cluster;
pstack_t stack; pstack_t stack;
@ -212,8 +212,8 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
return; return;
// mark the cluster as visible // mark the cluster as visible
if (!(thread->clustervis[clusternum >> 3] & (1 << (clusternum & 7)))) { if (!set_is_member (thread->clustervis, clusternum)) {
thread->clustervis[clusternum >> 3] |= 1 << (clusternum & 7); set_add (thread->clustervis, clusternum);
thread->base->numcansee++; thread->base->numcansee++;
} }
@ -221,31 +221,29 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
stack.next = NULL; stack.next = NULL;
stack.cluster = cluster; stack.cluster = cluster;
stack.portal = NULL; stack.portal = NULL;
stack.mightsee = malloc(bitbytes); LOCK;
might = (long *) stack.mightsee; stack.mightsee = set_new_size (portalclusters);
vis = (long *) thread->clustervis; UNLOCK;
might = stack.mightsee;
vis = thread->clustervis;
// check all portals for flowing into other clusters // check all portals for flowing into other clusters
for (i = 0; i < cluster->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
portal = cluster->portals[i]; portal = cluster->portals[i];
if (!(prevstack->mightsee[portal->cluster >> 3] if (!set_is_member (prevstack->mightsee, portal->cluster))
& (1 << (portal->cluster & 7))))
continue; // can't possibly see it continue; // can't possibly see it
// if the portal can't see anything we haven't already seen, skip it // if the portal can't see anything we haven't already seen, skip it
if (portal->status == stat_done) { if (portal->status == stat_done) {
c_vistest++; c_vistest++;
test = (long *) portal->visbits; test = portal->visbits;
} else { } else {
c_mighttest++; c_mighttest++;
test = (long *) portal->mightsee; test = 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;
} }
set_assign (might, prevstack->mightsee);
set_intersection (might, test);
more = !set_is_subset (might, vis);
if (!more) // can't see anything new if (!more) // can't see anything new
continue; continue;
@ -347,7 +345,9 @@ RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
FreeWinding (target); FreeWinding (target);
} }
free (stack.mightsee); LOCK;
set_delete (stack.mightsee);
UNLOCK;
} }
void void
@ -359,10 +359,9 @@ PortalFlow (portal_t *portal)
if (portal->status != stat_selected) if (portal->status != stat_selected)
Sys_Error ("PortalFlow: reflowed"); Sys_Error ("PortalFlow: reflowed");
portal->status = stat_working; portal->status = stat_working;
portal->visbits = set_new_size (portalclusters);
UNLOCK; UNLOCK;
portal->visbits = calloc (1, bitbytes);
memset (&data, 0, sizeof (data)); memset (&data, 0, sizeof (data));
data.clustervis = portal->visbits; data.clustervis = portal->visbits;
data.base = portal; data.base = portal;

View file

@ -371,12 +371,12 @@ CompressRow (byte *vis, byte *dest)
} }
static void static void
ClusterFlowExpand (byte *src, byte *dest) ClusterFlowExpand (const set_t *src, byte *dest)
{ {
int i, j; int i, j;
for (j = 1, i = 0; i < numrealleafs; i++) { 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; *dest |= j;
j <<= 1; j <<= 1;
if (j == 256) { if (j == 256) {
@ -394,9 +394,10 @@ ClusterFlowExpand (byte *src, byte *dest)
void void
ClusterFlow (int clusternum) ClusterFlow (int clusternum)
{ {
set_t *visclusters;
byte compressed[MAX_MAP_LEAFS / 8]; byte compressed[MAX_MAP_LEAFS / 8];
byte *outbuffer; byte *outbuffer;
int numvis, i, j; int numvis, i;
cluster_t *cluster; cluster_t *cluster;
portal_t *portal; portal_t *portal;
@ -406,26 +407,23 @@ ClusterFlow (int clusternum)
// flow through all portals, collecting visible bits // flow through all portals, collecting visible bits
memset (compressed, 0, sizeof (compressed)); memset (compressed, 0, sizeof (compressed));
visclusters = set_new ();
for (i = 0; i < cluster->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
portal = cluster->portals[i]; portal = cluster->portals[i];
if (portal->status != stat_done) if (portal->status != stat_done)
Sys_Error ("portal not done"); Sys_Error ("portal not done");
for (j = 0; j < bitbytes; j++) set_union (visclusters, portal->visbits);
compressed[j] |= portal->visbits[j];
} }
if (compressed[clusternum >> 3] & (1 << (clusternum & 7))) if (set_is_member (visclusters, clusternum))
Sys_Error ("Cluster portals saw into cluster"); Sys_Error ("Cluster portals saw into cluster");
compressed[clusternum >> 3] |= (1 << (clusternum & 7)); set_add (visclusters, clusternum);
numvis = 0; numvis = set_size (visclusters);
for (i = 0; i < portalclusters; i++)
if (compressed[i >> 3] & (1 << (i & 3)))
numvis++;
// expand to cluster->leaf PVS // expand to cluster->leaf PVS
ClusterFlowExpand (compressed, outbuffer); ClusterFlowExpand (visclusters, outbuffer);
// compress the bit string // compress the bit string
if (options.verbosity > 0) if (options.verbosity > 0)