mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-06-01 01:01:13 +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
|
#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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue