[util] Loosen affine test epsilon for SEB

Scaling the checks by 1e-6 was a little too tight for very small
triangles, but 1e-5 seems to work well. This fixes SEB getting stuck for
a ridiculously small (for quake) triangle in ad_tears (probably resulted
from some bad math in qfbsp when generating the portal file from the
bsp).
This commit is contained in:
Bill Currie 2021-07-29 15:03:54 +09:00
parent 4f51a3b406
commit 45aa8e6504
6 changed files with 78 additions and 13 deletions

View File

@ -1353,7 +1353,7 @@ test_support_points(const vec_t **points, int *num_points, const vec3_t center)
nn = DotProduct (n, n);
dd = DotProduct (d, d);
vv = DotProduct (v, v);
in_affine = nn < 1e-6 * vv * dd;
in_affine = nn < 1e-5 * vv * dd;
break;
case 3:
VectorSubtract (points[1], points[0], a);
@ -1363,7 +1363,7 @@ test_support_points(const vec_t **points, int *num_points, const vec3_t center)
dn = DotProduct (d, n);
dd = DotProduct (d, d);
nn = DotProduct (n, n);
in_affine = dn * dn < 1e-6 * dd * nn;
in_affine = dn * dn < 1e-5 * dd * nn;
break;
case 4:
in_affine = 1;

View File

@ -197,7 +197,7 @@ test_support_points(const vec4f_t **points, int *num_points, vec4f_t center)
nn = dotf (n, n)[0];
dd = dotf (d, d)[0];
vv = dotf (v, v)[0];
in_affine = nn < 1e-6 * vv * dd;
in_affine = nn < 1e-5 * vv * dd;
break;
case 3:
a = *points[1] - *points[0];
@ -207,7 +207,7 @@ test_support_points(const vec4f_t **points, int *num_points, vec4f_t center)
dn = dotf (d, n)[0];
dd = dotf (d, d)[0];
nn = dotf (n, n)[0];
in_affine = dn * dn < 1e-6 * dd * nn;
in_affine = dn * dn < 1e-5 * dd * nn;
break;
case 4:
in_affine = 1;

View File

@ -18,6 +18,24 @@ const vec3_t points[] = {
{ 0, 0, 0},
};
// This particular triangle from ad_tears caused SEB to hit its iteration
// limit because the center in affine hull test failed due to excessivly tight
// epsilon.
// However, the problem isn't here (but good to have a set of tests for it
// anyway).
const vec3_t tears_triangleA[] = {
{2201.82007, -1262, -713.450012},
{2201.8501, -1262, -713.593994},
};
const vec3_t tears_triangleB[] = {
{2201.82007, -1262, -713.450012},
{2201.84009, -1262, -713.445007},
};
const vec3_t tears_triangleC[] = {
{2201.8501, -1262, -713.593994},
{2201.84009, -1262, -713.445007},
};
struct {
const vec3_t *points;
int num_points;
@ -28,6 +46,9 @@ struct {
{points, 2, {{ 0, 0, 1}, 1.41421356}},
{points, 3, {{-0.333333343, 0.333333343, 0.333333343}, 1.63299322}},
{points, 4, {{0, 0, 0}, 1.73205081}},
{tears_triangleA, 2, {{2201.83496, -1262, -713.521973}, 0.0734853372}},
{tears_triangleB, 2, {{2201.83008, -1262, -713.44751}, 0.0103178304}},
{tears_triangleC, 2, {{2201.84521, -1262, -713.519531}, 0.0746228099}},
};
#define num_tests (sizeof (tests) / sizeof (tests[0]))
@ -61,10 +82,10 @@ main (int argc, const char **argv)
|| fabs (sphere.radius - tests[i].expect.radius) > 1e-4) {
res = 1;
printf ("test %d failed\n", (int) i);
printf ("expect: [%.9g %.9g %.9g],%.9g\n",
printf ("expect: {%.9g, %.9g, %.9g},%.9g\n",
VectorExpand (tests[i].expect.center),
tests[i].expect.radius);
printf ("got : [%.9g %.9g %.9g],%.9g\n",
printf ("got : {%.9g, %.9g, %.9g},%.9g\n",
VectorExpand (sphere.center),
sphere.radius);
}

View File

@ -19,6 +19,24 @@ const vec4f_t points[] = {
{ 0, 0, 0},
};
// This particular triangle from ad_tears caused SEB to hit its iteration
// limit because the center in affine hull test failed due to excessivly tight
// epsilon.
// However, the problem isn't here (but good to have a set of tests for it
// anyway).
const vec4f_t tears_triangleA[] = {
{2201.82007, -1262, -713.450012, 1},
{2201.8501, -1262, -713.593994, 1},
};
const vec4f_t tears_triangleB[] = {
{2201.82007, -1262, -713.450012, 1},
{2201.84009, -1262, -713.445007, 1},
};
const vec4f_t tears_triangleC[] = {
{2201.8501, -1262, -713.593994, 1},
{2201.84009, -1262, -713.445007, 1},
};
struct {
const vec4f_t *points;
int num_points;
@ -29,6 +47,9 @@ struct {
{points, 2, {{ 0, 0, 1}, 1.41421356}},
{points, 3, {{-0.333333343, 0.333333343, 0.333333343}, 1.63299322}},
{points, 4, {{0, 0, 0}, 1.73205081}},
{tears_triangleA, 2, {{2201.83496, -1262, -713.521973}, 0.0734853372}},
{tears_triangleB, 2, {{2201.83008, -1262, -713.44751}, 0.0103178304}},
{tears_triangleC, 2, {{2201.84521, -1262, -713.519531}, 0.0746228099}},
};
#define num_tests (sizeof (tests) / sizeof (tests[0]))
@ -63,10 +84,10 @@ main (int argc, const char **argv)
|| fabs (sphere.radius - tests[i].expect.radius) > 1e-4) {
res = 1;
printf ("test %d failed\n", (int) i);
printf ("expect: [%.9g %.9g %.9g],%.9g\n",
printf ("expect: {%.9g, %.9g, %.9g},%.9g\n",
VectorExpand (tests[i].expect.center),
tests[i].expect.radius);
printf ("got : [%.9g %.9g %.9g],%.9g\n",
printf ("got : {%.9g, %.9g, %.9g},%.9g\n",
VectorExpand (sphere.center),
sphere.radius);
}

View File

@ -18,6 +18,16 @@ const vec3_t points[] = {
{ 0, 0, 0},
};
// This particular triangle from ad_tears caused SEB to hit its iteration
// limit because the center in affine hull test failed due to excessivly tight
// epsilon. Yes, a rather insanely small triangle for a quake map. Probably
// due to qfbsp not culling the portal for being too small.
const vec3_t tears_triangle[] = {
{2201.82007, -1262, -713.450012},
{2201.8501, -1262, -713.593994},
{2201.84009, -1262, -713.445007},
};
struct {
const vec3_t *points;
int num_points;
@ -28,6 +38,7 @@ struct {
{points, 2, {{ 0, 0, 1}, 1.41421356}},
{points, 3, {{-0.333333343, 0.333333343, 0.333333343}, 1.63299322}},
{points, 4, {{0, 0, 0}, 1.73205081}},
{tears_triangle, 3, {{2201.84521, -1262, -713.519531}, 0.0747000724}},
};
#define num_tests (sizeof (tests) / sizeof (tests[0]))
@ -61,10 +72,10 @@ main (int argc, const char **argv)
|| fabs (sphere.radius - tests[i].expect.radius) > 1e-4) {
res = 1;
printf ("test %d failed\n", (int) i);
printf ("expect: [%.9g %.9g %.9g],%.9g\n",
printf ("expect: {%.9g, %.9g, %.9g},%.9g\n",
VectorExpand (tests[i].expect.center),
tests[i].expect.radius);
printf ("got : [%.9g %.9g %.9g],%.9g\n",
printf ("got : {%.9g, %.9g, %.9g},%.9g\n",
VectorExpand (sphere.center),
sphere.radius);
}

View File

@ -19,6 +19,16 @@ const vec4f_t points[] = {
{ 0, 0, 0, 1},
};
// This particular triangle from ad_tears caused SEB to hit its iteration
// limit because the center in affine hull test failed due to excessivly tight
// epsilon. Yes, a rather insanely small triangle for a quake map. Probably
// due to qfbsp not culling the portal for being too small.
const vec4f_t tears_triangle[] = {
{2201.82007, -1262, -713.450012, 1},
{2201.8501, -1262, -713.593994, 1},
{2201.84009, -1262, -713.445007, 1},
};
struct {
const vec4f_t *points;
int num_points;
@ -29,6 +39,7 @@ struct {
{points, 2, {{ 0, 0, 1, 1}, 1.41421356}},
{points, 3, {{-0.333333343, 0.333333343, 0.333333343, 1}, 1.63299322}},
{points, 4, {{0, 0, 0, 1}, 1.73205081}},
{tears_triangle, 3, {{2201.84521, -1262, -713.519531}, 0.0747000724}},
};
#define num_tests (sizeof (tests) / sizeof (tests[0]))
@ -57,15 +68,16 @@ main (int argc, const char **argv)
double start, end;
for (i = 0; i < num_tests; i ++) {
sphere = SmallestEnclosingBall_vf (tests[i].points, tests[i].num_points);
sphere = SmallestEnclosingBall_vf (tests[i].points,
tests[i].num_points);
if (VectorDistance_fast (sphere.center, tests[i].expect.center) > 1e-4
|| fabs (sphere.radius - tests[i].expect.radius) > 1e-4) {
res = 1;
printf ("test %d failed\n", (int) i);
printf ("expect: [%.9g %.9g %.9g],%.9g\n",
printf ("expect: {%.9g, %.9g, %.9g}, %.9g\n",
VectorExpand (tests[i].expect.center),
tests[i].expect.radius);
printf ("got : [%.9g %.9g %.9g],%.9g\n",
printf ("got : {%.9g, %.9g, %.9g}, %.9g\n",
VectorExpand (sphere.center),
sphere.radius);
}