From 2bbcdff9313c9129ba03fb5f5798b07c98d4a611 Mon Sep 17 00:00:00 2001 From: Kevin Shanahan Date: Tue, 25 Dec 2012 21:32:26 +1030 Subject: [PATCH] vis: Try to propogate some extra vis info from completed portals When a portal is completed, check the updated vis information for leafs that can no longer be seen from the leaf the portal is attached to. Update the portals on these no-longer-visible leaves to indicated that they can no longer see our leaf. Seems to be at least a small gain on my test maps. I suspect there is some further improvement to be gained by taking better advantage of this optimisation by changing out choice of portals in GetNextPortal. Couldn't find anything trivial that worked though. Signed-off-by: Kevin Shanahan --- vis/flow.c | 2 - vis/vis.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/vis/flow.c b/vis/flow.c index 41aaaf99..7a710c9e 100644 --- a/vis/flow.c +++ b/vis/flow.c @@ -370,8 +370,6 @@ PortalFlow(portal_t * p) data.pstack_head.mightsee = p->mightsee; RecursiveLeafFlow(p->leaf, &data, &data.pstack_head); - - p->status = pstat_done; } diff --git a/vis/vis.c b/vis/vis.c index 4a3573c0..b07dd4e0 100644 --- a/vis/vis.c +++ b/vis/vis.c @@ -22,7 +22,7 @@ int progress; portal_t *portals; leaf_t *leafs; -int c_portaltest, c_portalpass, c_portalcheck; +int c_portaltest, c_portalpass, c_portalcheck, c_mightseeupdate; int c_noclip = 0; qboolean showgetleaf = true; @@ -370,6 +370,121 @@ GetNextPortal(void) return ret; } + +/* + ============= + UpdateMightSee + + Called after completing a portal and finding that the source leaf is no + longer visible from the dest leaf. Visibility is symetrical, so the reverse + must also be true. Update mightsee for any portals on the source leaf which + haven't yet started processing. + + Called with the lock held. + ============= +*/ +static void +UpdateMightsee(const leaf_t *source, const leaf_t *dest) +{ + int i, leafnum; + portal_t *p; + + leafnum = dest - leafs; + for (i = 0; i < source->numportals; i++) { + p = source->portals[i]; + if (p->status != pstat_none) + continue; + if (p->mightsee[leafnum >> 3] & (1 << (leafnum & 7))) { + p->mightsee[leafnum >> 3] &= ~(1 << (leafnum & 7)); + p->nummightsee--; + c_mightseeupdate++; + } + } +} + + +/* + ============= + PortalCompleted + + Mark the portal completed and propogate new vis information across + to the complementry portals. + + Called with the lock held. + ============= +*/ +static void +PortalCompleted(portal_t *completed) +{ + int i, j, k, bit; + int leafnum; + portal_t *p, *p2; + leaf_t *myleaf; + unsigned long *might, *vis, *check; + unsigned long changed; + byte *bcheck, bmask; + + LOCK; + + completed->status = pstat_done; + + /* + * For each portal on the leaf, check the leafs we eliminated from + * mightsee during the full vis so far. + */ + myleaf = &leafs[completed->leaf]; + for (i = 0; i < myleaf->numportals; i++) { + p = myleaf->portals[i]; + if (p->status != pstat_done) + continue; + + might = (unsigned long *)p->mightsee; + vis = (unsigned long *)p->visbits; + for (j = 0; j < leaflongs; j++) { + changed = might[j] & ~vis[j]; + if (!changed) + continue; + + /* + * If any of these changed bits are still visible from another + * portal, we can't update yet. + */ + for (k = 0; k < myleaf->numportals; k++) { + if (k == i) + continue; + p2 = myleaf->portals[k]; + if (p2->status == pstat_done) + check = (unsigned long *)p2->visbits; + else + check = (unsigned long *)p2->mightsee; + changed &= ~check[j]; + if (!changed) + break; + } + if (!changed) + continue; + + /* + * Update mightsee for any of the changed bits that survived + */ + bcheck = (byte *)&changed; + for (k = 0; k < sizeof(changed); k++, bcheck++) { + if (!*bcheck) + continue; + for (bit = 0, bmask = 1; bit < 8; bit++, bmask <<= 1) { + if (!(*bcheck & bmask)) + continue; + leafnum = j * (sizeof(changed) << 3) + (k << 3) + bit; + UpdateMightsee(leafs + leafnum, myleaf); + } + } + } + } + + UNLOCK; +} + + /* ============== LeafThread @@ -387,6 +502,8 @@ LeafThread(void *unused) PortalFlow(p); + PortalCompleted(p); + if (verbose) { printf("\r"); logprint("portal:%4i mightsee:%4i cansee:%4i\n", @@ -566,7 +683,8 @@ CalcPortalVis(void) if (verbose) { logprint("portalcheck: %i portaltest: %i portalpass: %i\n", c_portalcheck, c_portaltest, c_portalpass); - logprint("c_vistest: %i c_mighttest: %i\n", c_vistest, c_mighttest); + logprint("c_vistest: %i c_mighttest: %i c_mightseeupdate %i\n", + c_vistest, c_mighttest, c_mightseeupdate); } }