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
|
// from http://mathworld.wolfram.com/SpherePointPicking.html
|
||||||
// eqns 6,7,8
|
// eqns 6,7,8
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,8 @@ VectorCopyFromGLM(const qvec3f &in, vec3_t out)
|
||||||
void ClearBounds(vec3_t mins, vec3_t maxs);
|
void ClearBounds(vec3_t mins, vec3_t maxs);
|
||||||
void AddPointToBounds(const vec3_t v, 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
|
static inline qvec3f
|
||||||
VectorToGLM(const vec3_t in)
|
VectorToGLM(const vec3_t in)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1429,16 +1429,6 @@ qboolean WindingIsHuge (winding_t *w)
|
||||||
return false;
|
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
|
SplitBrush
|
||||||
|
|
@ -1457,7 +1447,19 @@ void SplitBrush (const brush_t *brush,
|
||||||
*front = nullptr;
|
*front = nullptr;
|
||||||
*back = 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
|
// check all points
|
||||||
vec_t d_front = 0;
|
vec_t d_front = 0;
|
||||||
|
|
@ -1468,7 +1470,7 @@ void SplitBrush (const brush_t *brush,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int j=0 ; j<w->numpoints ; j++) {
|
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)
|
if (d > 0 && d > d_front)
|
||||||
d_front = d;
|
d_front = d;
|
||||||
if (d < 0 && d < d_back)
|
if (d < 0 && d < d_back)
|
||||||
|
|
@ -1488,9 +1490,11 @@ void SplitBrush (const brush_t *brush,
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new winding from the split plane
|
// 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) {
|
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);
|
ChopWindingInPlace (&w, plane2.normal, plane2.dist, 0); // PLANESIDE_EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1501,7 +1505,7 @@ void SplitBrush (const brush_t *brush,
|
||||||
if (w)
|
if (w)
|
||||||
FreeMem(w, WINDING, 1);
|
FreeMem(w, WINDING, 1);
|
||||||
|
|
||||||
side = BrushMostlyOnSide (brush, plane->normal, plane->dist);
|
side = BrushMostlyOnSide (brush, plane.normal, plane.dist);
|
||||||
if (side == SIDE_FRONT)
|
if (side == SIDE_FRONT)
|
||||||
*front = CopyBrush (brush);
|
*front = CopyBrush (brush);
|
||||||
if (side == SIDE_BACK)
|
if (side == SIDE_BACK)
|
||||||
|
|
@ -1545,7 +1549,7 @@ void SplitBrush (const brush_t *brush,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
winding_t *cw[2];
|
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++)
|
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]);
|
FreeBrush (b[i]);
|
||||||
b[i] = nullptr;
|
b[i] = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,94 @@ TEST(qbsp, BoundBrush) {
|
||||||
FreeMem(brush, BRUSH, 1);
|
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) {
|
TEST(mathlib, WindingArea) {
|
||||||
winding_t w;
|
winding_t w;
|
||||||
w.numpoints = 5;
|
w.numpoints = 5;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue