diff --git a/include/qbsp/brush.hh b/include/qbsp/brush.hh index 020dcb40..eaf700a1 100644 --- a/include/qbsp/brush.hh +++ b/include/qbsp/brush.hh @@ -49,5 +49,6 @@ bool PlaneEqual(const qbsp_plane_t *p1, const qbsp_plane_t *p2); bool PlaneInvEqual(const qbsp_plane_t *p1, const qbsp_plane_t *p2); vec_t BrushVolume (const brush_t *brush); +int BrushMostlyOnSide (const brush_t *brush, const plane_t *plane); #endif diff --git a/qbsp/brush.cc b/qbsp/brush.cc index 64590d23..df10fb23 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -1243,3 +1243,38 @@ vec_t BrushVolume (const brush_t *brush) return volume; } +/* +================== +BrushMostlyOnSide + +from q3map +================== +*/ +int BrushMostlyOnSide (const brush_t *brush, const plane_t *plane) +{ + vec_t max; + int side; + + max = 0; + side = SIDE_FRONT; + + for (const face_t *face = brush->faces; face; face = face->next) { + const winding_t *w = &face->w; + if (!w->numpoints) + continue; + + for (int j=0 ; jnumpoints ; j++) { + const vec_t d = DotProduct (w->points[j], plane->normal) - plane->dist; + if (d > max) { + max = d; + side = SIDE_FRONT; + } + if (-d > max) { + max = -d; + side = SIDE_BACK; + } + } + } + + return side; +} diff --git a/qbsp/test_qbsp.cc b/qbsp/test_qbsp.cc index adfadf4d..7302a993 100644 --- a/qbsp/test_qbsp.cc +++ b/qbsp/test_qbsp.cc @@ -121,7 +121,8 @@ TEST(qbsp, duplicatePlanes) { FreeMem(brush, BRUSH, 1); } -TEST(qbsp, brushVolume) { +static brush_t *load128x128x32Brush() +{ /* 128x128x32 rectangular brush */ const char *map = R"( { @@ -138,12 +139,40 @@ TEST(qbsp, brushVolume) { )"; mapentity_t worldspawn = LoadMap(map); - ASSERT_EQ(1, worldspawn.nummapbrushes); + Q_assert(1 == worldspawn.nummapbrushes); brush_t *brush = LoadBrush(&worldspawn.mapbrush(0), vec3_origin, 0); - ASSERT_NE(nullptr, brush); + Q_assert(nullptr != brush); + + return brush; +} + +TEST(qbsp, BrushVolume) { + brush_t *brush = load128x128x32Brush(); EXPECT_FLOAT_EQ((128*128*32), BrushVolume(brush)); +} + +TEST(qbsp, BrushMostlyOnSide1) { + brush_t *brush = load128x128x32Brush(); + + plane_t plane1; + VectorSet(plane1.normal, -1, 0, 0); + plane1.dist = -100; + + EXPECT_EQ(SIDE_FRONT, BrushMostlyOnSide(brush, &plane1)); + + FreeMem(brush, BRUSH, 1); +} + +TEST(qbsp, BrushMostlyOnSide2) { + brush_t *brush = load128x128x32Brush(); + + plane_t plane2; + VectorSet(plane2.normal, 1, 0, 0); + plane2.dist = 100; + + EXPECT_EQ(SIDE_BACK, BrushMostlyOnSide(brush, &plane2)); FreeMem(brush, BRUSH, 1); }