From 19a8dc29c4f7d6f97a3127ae47971dd1e29bbc75 Mon Sep 17 00:00:00 2001 From: Kevin Shanahan Date: Mon, 25 Feb 2013 12:05:41 +1030 Subject: [PATCH] qbsp: calculate a useful contents value for detail clusters Update PortalThru() to take the portal as it's argument, then we can examine the two nodes on either side of the cluster. The nodes could either be leafs or clusters. Walk the detail clusters recursively and if the contents are all the same, return that, otherwise if there is some empty space, leave it as empty. Similarly, if there is some water, return water, etc. Basically non-solids take precedence over solids in calculating the contents of the cluster. Signed-off-by: Kevin Shanahan --- qbsp/portals.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/qbsp/portals.c b/qbsp/portals.c index 9f9d8087..33ce97e4 100644 --- a/qbsp/portals.c +++ b/qbsp/portals.c @@ -49,13 +49,47 @@ WriteFloat(vec_t v) fprintf(PortalFile, "%f ", v); } +static int +ClusterContents(const node_t *node) +{ + int contents0, contents1; + + /* Either a leaf or non-detail node */ + if (node->contents || !node->detail_separator) + return node->contents; + + contents0 = ClusterContents(node->children[0]); + contents1 = ClusterContents(node->children[1]); + + if (contents0 == contents1) + return contents0; + + /* + * Clusters may be partially solid but still be seen into + * ?? - Should we do something more explicit with mixed liquid contents? + */ + if (contents0 == CONTENTS_EMPTY || contents1 == CONTENTS_EMPTY) + return CONTENTS_EMPTY; + + if (contents0 >= CONTENTS_LAVA && contents0 <= CONTENTS_WATER) + return contents0; + if (contents1 >= CONTENTS_LAVA && contents1 <= CONTENTS_WATER) + return contents1; + if (contents0 == CONTENTS_SKY || contents1 == CONTENTS_SKY) + return CONTENTS_SKY; + + return CONTENTS_SOLID; +} + /* - * Return true if possible to see from a leaf with content0 into an adjacent - * leaf with content1 + * Return true if possible to see the through the contents of the portals nodes */ static bool -PortalThru(int contents0, int contents1) +PortalThru(const portal_t *p) { + int contents0 = ClusterContents(p->nodes[0]); + int contents1 = ClusterContents(p->nodes[1]); + /* Can't see through solids */ if (contents0 == CONTENTS_SOLID || contents1 == CONTENTS_SOLID) return false; @@ -106,7 +140,7 @@ WritePortals_r(node_t *node, bool clusters) next = (p->nodes[0] == node) ? p->next[0] : p->next[1]; if (!p->winding || p->nodes[0] != node) continue; - if (!PortalThru(p->nodes[0]->contents, p->nodes[1]->contents)) + if (!PortalThru(p)) continue; w = p->winding; @@ -199,7 +233,7 @@ NumberLeafs_r(node_t *node, int cluster) for (p = node->portals; p;) { /* only write out from first leaf */ if (p->nodes[0] == node) { - if (PortalThru(p->nodes[0]->contents, p->nodes[1]->contents)) + if (PortalThru(p)) num_visportals++; p = p->next[0]; } else