qbsp: fix some issues with SplitBrush
This commit is contained in:
parent
3bb22ef22b
commit
9629134612
|
|
@ -122,6 +122,16 @@ void AddPointToBounds(const vec3_t v, vec3_t mins, vec3_t maxs)
|
|||
}
|
||||
}
|
||||
|
||||
plane_t FlipPlane(plane_t input)
|
||||
{
|
||||
plane_t result;
|
||||
|
||||
VectorScale(input.normal, -1, result.normal);
|
||||
result.dist = -input.dist;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// from http://mathworld.wolfram.com/SpherePointPicking.html
|
||||
// eqns 6,7,8
|
||||
void
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ VectorCopyFromGLM(const qvec3f &in, vec3_t out)
|
|||
void ClearBounds(vec3_t mins, vec3_t maxs);
|
||||
void AddPointToBounds(const vec3_t v, vec3_t mins, vec3_t maxs);
|
||||
|
||||
plane_t FlipPlane(plane_t input);
|
||||
|
||||
static inline qvec3f
|
||||
VectorToGLM(const vec3_t in)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1429,16 +1429,6 @@ qboolean WindingIsHuge (winding_t *w)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
Brush_FaceCount (const brush_t *brush)
|
||||
{
|
||||
int i=0;
|
||||
for (const face_t *face = brush->faces; face; face = face->next) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SplitBrush
|
||||
|
|
@ -1457,7 +1447,19 @@ void SplitBrush (const brush_t *brush,
|
|||
*front = nullptr;
|
||||
*back = nullptr;
|
||||
|
||||
const qbsp_plane_t *plane = &map.planes.at(planenum);
|
||||
qbsp_plane_t plane;
|
||||
{
|
||||
const qbsp_plane_t *globalplane = &map.planes.at(planenum);
|
||||
VectorCopy(globalplane->normal, plane.normal);
|
||||
plane.dist = globalplane->dist;
|
||||
if (planeside) {
|
||||
VectorScale(plane.normal, -1, plane.normal);
|
||||
plane.dist = -plane.dist;
|
||||
}
|
||||
// FIXME: dangerous..
|
||||
plane.type = -1000;
|
||||
plane.outputplanenum = -1;
|
||||
}
|
||||
|
||||
// check all points
|
||||
vec_t d_front = 0;
|
||||
|
|
@ -1468,7 +1470,7 @@ void SplitBrush (const brush_t *brush,
|
|||
continue;
|
||||
|
||||
for (int j=0 ; j<w->numpoints ; j++) {
|
||||
const vec_t d = DotProduct (w->points[j], plane->normal) - plane->dist;
|
||||
const vec_t d = DotProduct (w->points[j], plane.normal) - plane.dist;
|
||||
if (d > 0 && d > d_front)
|
||||
d_front = d;
|
||||
if (d < 0 && d < d_back)
|
||||
|
|
@ -1488,9 +1490,11 @@ void SplitBrush (const brush_t *brush,
|
|||
}
|
||||
|
||||
// create a new winding from the split plane
|
||||
winding_t *w = BaseWindingForPlane (plane);
|
||||
winding_t *w = BaseWindingForPlane (&plane);
|
||||
for (const face_t *face = brush->faces; face; face = face->next) {
|
||||
plane_t plane2 = Face_Plane(face);
|
||||
if (!w)
|
||||
break;
|
||||
const plane_t plane2 = FlipPlane(Face_Plane(face));
|
||||
ChopWindingInPlace (&w, plane2.normal, plane2.dist, 0); // PLANESIDE_EPSILON);
|
||||
}
|
||||
|
||||
|
|
@ -1501,7 +1505,7 @@ void SplitBrush (const brush_t *brush,
|
|||
if (w)
|
||||
FreeMem(w, WINDING, 1);
|
||||
|
||||
side = BrushMostlyOnSide (brush, plane->normal, plane->dist);
|
||||
side = BrushMostlyOnSide (brush, plane.normal, plane.dist);
|
||||
if (side == SIDE_FRONT)
|
||||
*front = CopyBrush (brush);
|
||||
if (side == SIDE_BACK)
|
||||
|
|
@ -1545,7 +1549,7 @@ void SplitBrush (const brush_t *brush,
|
|||
continue;
|
||||
|
||||
winding_t *cw[2];
|
||||
DivideWinding(w, plane, &cw[0], &cw[1]);
|
||||
DivideWinding(w, &plane, &cw[0], &cw[1]);
|
||||
|
||||
for (int j=0 ; j<2 ; j++)
|
||||
{
|
||||
|
|
@ -1586,7 +1590,7 @@ void SplitBrush (const brush_t *brush,
|
|||
}
|
||||
}
|
||||
|
||||
if (Brush_FaceCount(b[i]) < 4 /* was 3 */ || j < 3)
|
||||
if (Brush_NumFaces(b[i]) < 4 /* was 3 */ || j < 3)
|
||||
{
|
||||
FreeBrush (b[i]);
|
||||
b[i] = nullptr;
|
||||
|
|
|
|||
|
|
@ -193,6 +193,94 @@ TEST(qbsp, BoundBrush) {
|
|||
FreeMem(brush, BRUSH, 1);
|
||||
}
|
||||
|
||||
static void checkForAllCubeNormals(const brush_t *brush)
|
||||
{
|
||||
const vec3_t wanted[6] = {
|
||||
{ -1, 0, 0 },{ 1, 0, 0 },
|
||||
{ 0,-1, 0 },{ 0, 1, 0 },
|
||||
{ 0, 0,-1 },{ 0, 0, 1 }
|
||||
};
|
||||
|
||||
bool found[6];
|
||||
for (int i=0; i<6; i++) {
|
||||
found[i] = false;
|
||||
}
|
||||
|
||||
for (const face_t *face = brush->faces; face; face = face->next) {
|
||||
const plane_t faceplane = Face_Plane(face);
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
if (VectorCompare(wanted[i], faceplane.normal, NORMAL_EPSILON)) {
|
||||
EXPECT_FALSE(found[i]);
|
||||
found[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
EXPECT_TRUE(found[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(qbsp, SplitBrush) {
|
||||
brush_t *brush = load128x128x32Brush();
|
||||
|
||||
const vec3_t planenormal = { -1, 0, 0 };
|
||||
int planeside;
|
||||
const int planenum = FindPlane(planenormal, 0.0, &planeside);
|
||||
|
||||
brush_t *front, *back;
|
||||
SplitBrush(brush, planenum, planeside, &front, &back);
|
||||
|
||||
ASSERT_NE(nullptr, front);
|
||||
ASSERT_NE(nullptr, back);
|
||||
|
||||
// front
|
||||
EXPECT_FLOAT_EQ(-64, front->mins[0]);
|
||||
EXPECT_FLOAT_EQ(-64, front->mins[1]);
|
||||
EXPECT_FLOAT_EQ(-16, front->mins[2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(0, front->maxs[0]);
|
||||
EXPECT_FLOAT_EQ(64, front->maxs[1]);
|
||||
EXPECT_FLOAT_EQ(16, front->maxs[2]);
|
||||
|
||||
EXPECT_EQ(6, Brush_NumFaces(front));
|
||||
checkForAllCubeNormals(front);
|
||||
|
||||
// back
|
||||
EXPECT_FLOAT_EQ(0, back->mins[0]);
|
||||
EXPECT_FLOAT_EQ(-64, back->mins[1]);
|
||||
EXPECT_FLOAT_EQ(-16, back->mins[2]);
|
||||
|
||||
EXPECT_FLOAT_EQ(64, back->maxs[0]);
|
||||
EXPECT_FLOAT_EQ(64, back->maxs[1]);
|
||||
EXPECT_FLOAT_EQ(16, back->maxs[2]);
|
||||
|
||||
EXPECT_EQ(6, Brush_NumFaces(back));
|
||||
checkForAllCubeNormals(back);
|
||||
|
||||
FreeMem(brush, BRUSH, 1);
|
||||
FreeMem(front, BRUSH, 1);
|
||||
FreeMem(back, BRUSH, 1);
|
||||
}
|
||||
|
||||
TEST(qbsp, SplitBrushOnSide) {
|
||||
brush_t *brush = load128x128x32Brush();
|
||||
|
||||
const vec3_t planenormal = { -1, 0, 0 };
|
||||
int planeside;
|
||||
const int planenum = FindPlane(planenormal, -64.0, &planeside);
|
||||
|
||||
brush_t *front, *back;
|
||||
SplitBrush(brush, planenum, planeside, &front, &back);
|
||||
|
||||
EXPECT_NE(nullptr, front);
|
||||
EXPECT_EQ(6, Brush_NumFaces(front));
|
||||
checkForAllCubeNormals(front);
|
||||
|
||||
EXPECT_EQ(nullptr, back);
|
||||
}
|
||||
|
||||
TEST(mathlib, WindingArea) {
|
||||
winding_t w;
|
||||
w.numpoints = 5;
|
||||
|
|
|
|||
Loading…
Reference in New Issue