revert some of the vis stuff, but re-implement it in a more working state
This commit is contained in:
parent
dfa1282d40
commit
b21920841d
|
|
@ -784,20 +784,11 @@ public:
|
|||
return w;
|
||||
}
|
||||
|
||||
void flip_to(winding_base_t &winding_out) const
|
||||
{
|
||||
if (winding_out.size() < size()) {
|
||||
winding_out.resize(size());
|
||||
}
|
||||
|
||||
std::reverse_copy(begin(), end(), winding_out.begin());
|
||||
}
|
||||
|
||||
winding_base_t flip() const
|
||||
{
|
||||
winding_base_t result(count);
|
||||
|
||||
flip_to(result);
|
||||
std::reverse_copy(begin(), end(), result.begin());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ struct portal_t
|
|||
int numcansee;
|
||||
};
|
||||
|
||||
inline float winding_t::distFromPortal(struct portal_t *p)
|
||||
inline float winding_t::distFromPortal(portal_t *p)
|
||||
{
|
||||
vec_t mindist = 1e20;
|
||||
|
||||
|
|
@ -153,16 +153,16 @@ struct pstack_t
|
|||
portal_t *portal; // portal exiting
|
||||
winding_t *source, *pass;
|
||||
winding_t windings[STACK_WINDINGS]; // Fixed size windings
|
||||
bool windings_used[STACK_WINDINGS]; // whether the winding is used currently
|
||||
bool windings_used[STACK_WINDINGS];
|
||||
qplane3d portalplane;
|
||||
leafbits_t *mightsee; // bit string
|
||||
qplane3d separators[2][MAX_SEPARATORS]; /* Separator cache */
|
||||
int numseparators[2];
|
||||
};
|
||||
|
||||
winding_t *AllocStackWinding(pstack_t &stack);
|
||||
void FreeStackWinding(winding_t *&w, pstack_t &stack);
|
||||
winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &split);
|
||||
winding_t *AllocStackWinding(pstack_t *stack);
|
||||
void FreeStackWinding(winding_t *&w, pstack_t *stack);
|
||||
winding_t *ClipStackWinding(winding_t *in, pstack_t *stack, qplane3d *split);
|
||||
|
||||
struct threaddata_t
|
||||
{
|
||||
|
|
|
|||
76
vis/flow.cc
76
vis/flow.cc
|
|
@ -29,8 +29,8 @@ static int c_leafskip;
|
|||
pointer, was measurably faster
|
||||
==============
|
||||
*/
|
||||
static void ClipToSeparators(winding_t *const &source, const qplane3d src_pl,
|
||||
winding_t *const &pass, winding_t *&target, unsigned int test, pstack_t &stack)
|
||||
static void ClipToSeparators(const winding_t *source, const qplane3d src_pl,
|
||||
const winding_t *pass, winding_t *&target, unsigned int test, pstack_t *stack)
|
||||
{
|
||||
int i, j, k, l;
|
||||
qplane3d sep;
|
||||
|
|
@ -107,13 +107,13 @@ static void ClipToSeparators(winding_t *const &source, const qplane3d src_pl,
|
|||
|
||||
/* Cache separating planes for tests 0, 1 */
|
||||
if (test < 2) {
|
||||
if (stack.numseparators[test] == MAX_SEPARATORS)
|
||||
if (stack->numseparators[test] == MAX_SEPARATORS)
|
||||
FError("MAX_SEPARATORS");
|
||||
stack.separators[test][stack.numseparators[test]] = sep;
|
||||
stack.numseparators[test]++;
|
||||
stack->separators[test][stack->numseparators[test]] = sep;
|
||||
stack->numseparators[test]++;
|
||||
}
|
||||
|
||||
target = ClipStackWinding(target, stack, sep);
|
||||
target = ClipStackWinding(target, stack, &sep);
|
||||
|
||||
if (!target)
|
||||
return; // target is not visible
|
||||
|
|
@ -141,9 +141,9 @@ static int CheckStack(leaf_t *leaf, threaddata_t *thread)
|
|||
If src_portal is NULL, this is the originating leaf
|
||||
==================
|
||||
*/
|
||||
static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevstack)
|
||||
static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevstack)
|
||||
{
|
||||
pstack_t stack;
|
||||
pstack_t stack {};
|
||||
portal_t *p;
|
||||
qplane3d backplane;
|
||||
leaf_t *leaf;
|
||||
|
|
@ -170,16 +170,9 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
thread->base->numcansee++;
|
||||
}
|
||||
|
||||
prevstack.next = &stack;
|
||||
prevstack->next = &stack;
|
||||
|
||||
stack.next = NULL;
|
||||
stack.leaf = leaf;
|
||||
stack.portal = NULL;
|
||||
stack.numseparators[0] = 0;
|
||||
stack.numseparators[1] = 0;
|
||||
|
||||
for (i = 0; i < STACK_WINDINGS; i++)
|
||||
stack.windings_used[i] = false;
|
||||
|
||||
leafbits_t local(portalleafs);
|
||||
stack.mightsee = &local;
|
||||
|
|
@ -191,7 +184,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
for (i = 0; i < leaf->numportals; i++) {
|
||||
p = leaf->portals[i];
|
||||
|
||||
if (!(*prevstack.mightsee)[p->leaf]) {
|
||||
if (!(*prevstack->mightsee)[p->leaf]) {
|
||||
c_leafskip++;
|
||||
continue; // can't possibly see it
|
||||
}
|
||||
|
|
@ -210,7 +203,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
uint32_t more = 0;
|
||||
numblocks = (portalleafs + leafbits_t::mask) >> leafbits_t::shift;
|
||||
for (j = 0; j < numblocks; j++) {
|
||||
might[j] = prevstack.mightsee->data()[j] & test[j];
|
||||
might[j] = prevstack->mightsee->data()[j] & test[j];
|
||||
more |= (might[j] & ~vis[j]);
|
||||
}
|
||||
|
||||
|
|
@ -223,7 +216,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
stack.portalplane = p->plane;
|
||||
backplane = -p->plane;
|
||||
|
||||
if (qv::epsilonEqual(prevstack.portalplane.normal, backplane.normal, EQUAL_EPSILON))
|
||||
if (qv::epsilonEqual(prevstack->portalplane.normal, backplane.normal, EQUAL_EPSILON))
|
||||
continue; // can't go out a coplanar face
|
||||
|
||||
c_portalcheck++;
|
||||
|
|
@ -243,28 +236,27 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
*/
|
||||
|
||||
/* Clip any part of the target portal behind the source portal */
|
||||
stack.pass = &p->winding;
|
||||
stack.pass = ClipStackWinding(stack.pass, stack, thread->pstack_head.portalplane);
|
||||
stack.pass = ClipStackWinding(&p->winding, &stack, &thread->pstack_head.portalplane);
|
||||
if (!stack.pass)
|
||||
continue;
|
||||
|
||||
if (!prevstack.pass) {
|
||||
if (!prevstack->pass) {
|
||||
// the second leaf can only be blocked if coplanar
|
||||
stack.source = prevstack.source;
|
||||
RecursiveLeafFlow(p->leaf, thread, stack);
|
||||
FreeStackWinding(stack.pass, stack);
|
||||
stack.source = prevstack->source;
|
||||
RecursiveLeafFlow(p->leaf, thread, &stack);
|
||||
FreeStackWinding(stack.pass, &stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Clip any part of the target portal behind the pass portal */
|
||||
stack.pass = ClipStackWinding(stack.pass, stack, prevstack.portalplane);
|
||||
stack.pass = ClipStackWinding(stack.pass, &stack, &prevstack->portalplane);
|
||||
if (!stack.pass)
|
||||
continue;
|
||||
|
||||
/* Clip any part of the source portal in front of the target portal */
|
||||
stack.source = ClipStackWinding(prevstack.source, stack, backplane);
|
||||
stack.source = ClipStackWinding(prevstack->source, &stack, &backplane);
|
||||
if (!stack.source) {
|
||||
FreeStackWinding(stack.pass, stack);
|
||||
FreeStackWinding(stack.pass, &stack);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -274,17 +266,17 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
if (options.level.value() > 0) {
|
||||
if (stack.numseparators[0]) {
|
||||
for (j = 0; j < stack.numseparators[0]; j++) {
|
||||
stack.pass = ClipStackWinding(stack.pass, stack, stack.separators[0][j]);
|
||||
stack.pass = ClipStackWinding(stack.pass, &stack, &stack.separators[0][j]);
|
||||
if (!stack.pass)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Using prevstack source for separator cache correctness */
|
||||
ClipToSeparators(
|
||||
prevstack.source, thread->pstack_head.portalplane, prevstack.pass, stack.pass, 0, stack);
|
||||
prevstack->source, thread->pstack_head.portalplane, prevstack->pass, stack.pass, 0, &stack);
|
||||
}
|
||||
if (!stack.pass) {
|
||||
FreeStackWinding(stack.source, stack);
|
||||
FreeStackWinding(stack.source, &stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -293,34 +285,34 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
if (options.level.value() > 1) {
|
||||
if (stack.numseparators[1]) {
|
||||
for (j = 0; j < stack.numseparators[1]; j++) {
|
||||
stack.pass = ClipStackWinding(stack.pass, stack, stack.separators[1][j]);
|
||||
stack.pass = ClipStackWinding(stack.pass, &stack, &stack.separators[1][j]);
|
||||
if (!stack.pass)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* Using prevstack source for separator cache correctness */
|
||||
ClipToSeparators(prevstack.pass, prevstack.portalplane, prevstack.source, stack.pass, 1, stack);
|
||||
ClipToSeparators(prevstack->pass, prevstack->portalplane, prevstack->source, stack.pass, 1, &stack);
|
||||
}
|
||||
if (!stack.pass) {
|
||||
FreeStackWinding(stack.source, stack);
|
||||
FreeStackWinding(stack.source, &stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* TEST 2 :: target -> pass -> source */
|
||||
if (options.level.value() > 2) {
|
||||
ClipToSeparators(stack.pass, stack.portalplane, prevstack.pass, stack.source, 2, stack);
|
||||
ClipToSeparators(stack.pass, stack.portalplane, prevstack->pass, stack.source, 2, &stack);
|
||||
if (!stack.source) {
|
||||
FreeStackWinding(stack.pass, stack);
|
||||
FreeStackWinding(stack.pass, &stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* TEST 3 :: pass -> target -> source */
|
||||
if (options.level.value() > 3) {
|
||||
ClipToSeparators(prevstack.pass, prevstack.portalplane, stack.pass, stack.source, 3, stack);
|
||||
ClipToSeparators(prevstack->pass, prevstack->portalplane, stack.pass, stack.source, 3, &stack);
|
||||
if (!stack.source) {
|
||||
FreeStackWinding(stack.pass, stack);
|
||||
FreeStackWinding(stack.pass, &stack);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -328,10 +320,10 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevs
|
|||
c_portalpass++;
|
||||
|
||||
// flow through it for real
|
||||
RecursiveLeafFlow(p->leaf, thread, stack);
|
||||
RecursiveLeafFlow(p->leaf, thread, &stack);
|
||||
|
||||
FreeStackWinding(stack.source, stack);
|
||||
FreeStackWinding(stack.pass, stack);
|
||||
FreeStackWinding(stack.source, &stack);
|
||||
FreeStackWinding(stack.pass, &stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -356,7 +348,7 @@ void PortalFlow(portal_t *p)
|
|||
data.pstack_head.portalplane = p->plane;
|
||||
data.pstack_head.mightsee = &p->mightsee;
|
||||
|
||||
RecursiveLeafFlow(p->leaf, &data, data.pstack_head);
|
||||
RecursiveLeafFlow(p->leaf, &data, &data.pstack_head);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
71
vis/vis.cc
71
vis/vis.cc
|
|
@ -71,12 +71,13 @@ fs::path portalfile, statefile, statetmpfile;
|
|||
Return a pointer to a free fixed winding on the stack
|
||||
==================
|
||||
*/
|
||||
winding_t *AllocStackWinding(pstack_t &stack)
|
||||
winding_t *AllocStackWinding(pstack_t *stack)
|
||||
{
|
||||
for (size_t i = 0; i < STACK_WINDINGS; i++) {
|
||||
if (!stack.windings_used[i]) {
|
||||
stack.windings_used[i] = true;
|
||||
return &stack.windings[i];
|
||||
if (!stack->windings_used[i]) {
|
||||
stack->windings[i].clear();
|
||||
stack->windings_used[i] = true;
|
||||
return &stack->windings[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,14 +91,12 @@ winding_t *AllocStackWinding(pstack_t &stack)
|
|||
As long as the winding passed in is local to the stack, free it. Otherwise,
|
||||
do nothing (the winding either belongs to a portal or another stack
|
||||
structure further up the call chain).
|
||||
|
||||
FIXME: is there some way we can refactor this out entirely?
|
||||
==================
|
||||
*/
|
||||
void FreeStackWinding(winding_t *&w, pstack_t &stack)
|
||||
void FreeStackWinding(winding_t *&w, pstack_t *stack)
|
||||
{
|
||||
if (w >= stack.windings && w <= &stack.windings[STACK_WINDINGS]) {
|
||||
stack.windings_used[w - stack.windings] = false;
|
||||
if (w >= stack->windings && w <= &stack->windings[STACK_WINDINGS]) {
|
||||
stack->windings_used[w - stack->windings] = false;
|
||||
w = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -112,7 +111,7 @@ void FreeStackWinding(winding_t *&w, pstack_t &stack)
|
|||
is returned.
|
||||
==================
|
||||
*/
|
||||
winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &split)
|
||||
winding_t *ClipStackWinding(winding_t *in, pstack_t *stack, qplane3d *split)
|
||||
{
|
||||
vec_t *dists = (vec_t *)alloca(sizeof(vec_t) * (in->size() + 1));
|
||||
int *sides = (int *)alloca(sizeof(int) * (in->size() + 1));
|
||||
|
|
@ -120,10 +119,10 @@ winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &spl
|
|||
int i, j;
|
||||
|
||||
/* Fast test first */
|
||||
vec_t dot = split.distance_to(in->origin);
|
||||
vec_t dot = split->distance_to(in->origin);
|
||||
if (dot < -in->radius) {
|
||||
FreeStackWinding(in, stack);
|
||||
return nullptr;
|
||||
return NULL;
|
||||
} else if (dot > in->radius) {
|
||||
return in;
|
||||
}
|
||||
|
|
@ -135,7 +134,7 @@ winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &spl
|
|||
|
||||
/* determine sides for each point */
|
||||
for (i = 0; i < in->size(); i++) {
|
||||
dot = split.distance_to((*in)[i]);
|
||||
dot = split->distance_to((*in)[i]);
|
||||
dists[i] = dot;
|
||||
if (dot > ON_EPSILON)
|
||||
sides[i] = SIDE_FRONT;
|
||||
|
|
@ -158,7 +157,7 @@ winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &spl
|
|||
|
||||
if (!counts[0]) {
|
||||
FreeStackWinding(in, stack);
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
if (!counts[1])
|
||||
return in;
|
||||
|
|
@ -192,10 +191,10 @@ winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &spl
|
|||
vec_t fraction = dists[i] / (dists[i] - dists[i + 1]);
|
||||
for (j = 0; j < 3; j++) {
|
||||
/* avoid round off error when possible */
|
||||
if (split.normal[j] == 1)
|
||||
mid[j] = split.dist;
|
||||
else if (split.normal[j] == -1)
|
||||
mid[j] = -split.dist;
|
||||
if (split->normal[j] == 1)
|
||||
mid[j] = split->dist;
|
||||
else if (split->normal[j] == -1)
|
||||
mid[j] = -split->dist;
|
||||
else
|
||||
mid[j] = p1[j] + fraction * (p2[j] - p1[j]);
|
||||
}
|
||||
|
|
@ -270,14 +269,16 @@ portal_t *GetNextPortal(void)
|
|||
Called with the lock held.
|
||||
=============
|
||||
*/
|
||||
static void UpdateMightsee(const leaf_t &source, const leaf_t &dest)
|
||||
static void UpdateMightsee(const leaf_t *source, const leaf_t *dest)
|
||||
{
|
||||
size_t leafnum = &dest - leafs;
|
||||
for (size_t i = 0; i < source.numportals; i++) {
|
||||
portal_t *p = source.portals[i];
|
||||
if (p->status != pstat_none) {
|
||||
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]) {
|
||||
p->mightsee[leafnum] = false;
|
||||
p->nummightsee--;
|
||||
|
|
@ -301,6 +302,7 @@ static void PortalCompleted(portal_t *completed)
|
|||
int i, j, k, bit, numblocks;
|
||||
int leafnum;
|
||||
const portal_t *p, *p2;
|
||||
const leaf_t *myleaf;
|
||||
const uint32_t *might, *vis;
|
||||
uint32_t changed;
|
||||
|
||||
|
|
@ -312,9 +314,9 @@ static void PortalCompleted(portal_t *completed)
|
|||
* For each portal on the leaf, check the leafs we eliminated from
|
||||
* mightsee during the full vis so far.
|
||||
*/
|
||||
const leaf_t &myleaf = leafs[completed->leaf];
|
||||
for (i = 0; i < myleaf.numportals; i++) {
|
||||
p = myleaf.portals[i];
|
||||
myleaf = &leafs[completed->leaf];
|
||||
for (i = 0; i < myleaf->numportals; i++) {
|
||||
p = myleaf->portals[i];
|
||||
if (p->status != pstat_done)
|
||||
continue;
|
||||
|
||||
|
|
@ -330,10 +332,10 @@ static void PortalCompleted(portal_t *completed)
|
|||
* If any of these changed bits are still visible from another
|
||||
* portal, we can't update yet.
|
||||
*/
|
||||
for (k = 0; k < myleaf.numportals; k++) {
|
||||
for (k = 0; k < myleaf->numportals; k++) {
|
||||
if (k == i)
|
||||
continue;
|
||||
p2 = myleaf.portals[k];
|
||||
p2 = myleaf->portals[k];
|
||||
if (p2->status == pstat_done)
|
||||
changed &= ~p2->visbits.data()[j];
|
||||
else
|
||||
|
|
@ -349,7 +351,7 @@ static void PortalCompleted(portal_t *completed)
|
|||
bit = ffsl(changed) - 1;
|
||||
changed &= ~nth_bit(bit);
|
||||
leafnum = (j << leafbits_t::shift) + bit;
|
||||
UpdateMightsee(leafs[leafnum], myleaf);
|
||||
UpdateMightsee(leafs + leafnum, myleaf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -648,8 +650,7 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
|||
|
||||
for (i = 0, p = portals; i < numportals; i++) {
|
||||
const auto &sourceportal = prtfile.portals[i];
|
||||
p->winding = { sourceportal.winding.begin(), sourceportal.winding.end() };
|
||||
p->winding.SetWindingSphere();
|
||||
p->winding = winding_t{sourceportal.winding.begin(), sourceportal.winding.end()};
|
||||
|
||||
// calc plane
|
||||
plane = p->winding.plane();
|
||||
|
|
@ -663,6 +664,7 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
|||
|
||||
p->plane = -plane;
|
||||
p->leaf = sourceportal.leafnums[1];
|
||||
p->winding.SetWindingSphere();
|
||||
p++;
|
||||
|
||||
// create backwards portal
|
||||
|
|
@ -673,10 +675,11 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp)
|
|||
l->numportals++;
|
||||
|
||||
// Create a reverse winding
|
||||
sourceportal.winding.flip_to(p->winding);
|
||||
p->winding.SetWindingSphere();
|
||||
const auto flipped = sourceportal.winding.flip();
|
||||
p->winding = winding_t{flipped.begin(), flipped.end()};
|
||||
p->plane = plane;
|
||||
p->leaf = sourceportal.leafnums[0];
|
||||
p->winding.SetWindingSphere();
|
||||
p++;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue