shithub: nanobsp

Download patch

ref: 908d85b4c9dbb09f7b01ef2f1be9c8af59d2372e
parent: cf107929d8081a23a99affb4e5244f4ac5691215
author: Andrew Apted <ajapted@gmail.com>
date: Sun Dec 10 16:30:39 EST 2023

ensure a final partition's delta is not too small.

Well this "bug" took all day to investigate, but the culprit turns out
to be the existing R_PointOnSide() code, which has very poor accuracy
when the delta is small, leading to bad results during BSP traversals.

I wasted the better part of two hours yesterday to discover that the
existing M_AddToBox() code in m_bbox.c has a serious bug.  Such are
the joys of programming I guess :)

--- a/nano_bsp.c
+++ b/nano_bsp.c
@@ -347,6 +347,11 @@
 	eval->right = 0;
 	eval->split = 0;
 
+	// do not create tiny partitions
+	if (abs (part->v2->x - part->v1->x) < 4*DIST_EPSILON &&
+		abs (part->v2->y - part->v1->y) < 4*DIST_EPSILON)
+		return false;
+
 	seg_t * S;
 	for (S = soup ; S != NULL ; S = S->next)
 	{
@@ -657,6 +662,18 @@
 	N->y  = part->v1->y;
 	N->dx = part->v2->x - N->x;
 	N->dy = part->v2->y - N->y;
+
+	// ensure partitions are a minimum length, since the engine's
+	// R_PointOnSide() functions have very poor accuracy when the
+	// delta is too small, and that WILL BREAK a map.
+
+	fixed_t min_size = 64 * FRACUNIT;
+
+	while (abs (N->dx) < min_size && abs (N->dy) < min_size)
+	{
+		N->dx *= 2;
+		N->dy *= 2;
+	}
 
 	// these are the new lists (after splitting)
 	seg_t * lefts  = NULL;
--