quakeforge/libs/util/test/test-bary.c
Bill Currie ef9b04ba83 [util] Get tests working with sse2
It seems that i686 code generation is all over the place reguarding sse2
vs fp, with the resulting differences in carried precision. I'm not sure
I'm happy with the situation, but at least it's being tested to a
certain extent. Not sure if this broke basic (no sse) i686 tests.
2021-06-01 18:53:53 +09:00

118 lines
2.9 KiB
C

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "QF/mathlib.h"
#include "QF/mersenne.h"
#include "QF/sys.h"
vec3_t points[] = {
{-1, -1, 1},
{ 1, 1, 1},
{-1, 1, -1},
{ 1, -1, -1},
{-1, -1, -1},
{ 1, 1, -1},
{-1, 1, 1},
{ 1, -1, 1},
{ 0, 0, 0},
};
const vec_t *line[] = {points[0], points[1]};
const vec_t *tri[] = {points[0], points[1], points[2]};
const vec_t *tetra[] = {points[0], points[1], points[2], points[3]};
struct {
const vec_t **points;
int num_points;
vec_t *x;
vec_t expect[4];
} tests[] = {
{line, 2, points[0], {1, 0}},
{line, 2, points[1], {0, 1}},
{line, 2, points[2], {0.5, 0.5}},
{line, 2, points[3], {0.5, 0.5}},
{line, 2, points[8], {0.5, 0.5}},
{tri, 3, points[0], {1, 0, 0}},
{tri, 3, points[1], {0, 1, 0}},
{tri, 3, points[2], {0, 0, 1}},
{tri, 3, points[3], {0.333333333, 0.333333333, 0.333333333}},
{tri, 3, points[8], {0.333333333, 0.333333333, 0.333333333}},
{tetra, 4, points[0], {1, 0, 0, 0}},
{tetra, 4, points[1], {0, 1, 0, 0}},
{tetra, 4, points[2], {0, 0, 1, 0}},
{tetra, 4, points[3], {0, 0, 0, 1}},
{tetra, 4, points[4], { 0.5, -0.5, 0.5, 0.5}},
{tetra, 4, points[5], {-0.5, 0.5, 0.5, 0.5}},
{tetra, 4, points[6], { 0.5, 0.5, 0.5, -0.5}},
{tetra, 4, points[7], { 0.5, 0.5, -0.5, 0.5}},
{tetra, 4, points[8], {0.25, 0.25, 0.25, 0.25}},
};
#define num_tests (sizeof (tests) / sizeof (tests[0]))
static inline float
rnd (mtstate_t *mt)
{
union {
uint32_t u;
float f;
} uf;
do {
uf.u = mtwist_rand (mt) & 0x007fffff;
} while (!uf.u);
uf.u |= 0x40000000;
return uf.f - 3.0;
}
int
main (int argc, const char **argv)
{
int res = 0;
size_t i;
int j;
vec_t lambda[4];
mtstate_t mt;
double start, end;
for (i = 0; i < num_tests; i ++) {
BarycentricCoords (tests[i].points, tests[i].num_points, tests[i].x,
lambda);
for (j = 0; j < tests[i].num_points; j++) {
if (tests[i].expect[j] != lambda[j])
break;
}
if (j != tests[i].num_points) {
res = 1;
printf ("test %d failed\n", (int) i);
printf ("expect:");
for (j = 0; j < tests[i].num_points; j++)
printf (" %.9g", tests[i].expect[j]);
printf ("\ngot :");
for (j = 0; j < tests[i].num_points; j++)
printf (" %.9g", lambda[j]);
printf ("\n");
}
}
mtwist_seed (&mt, 0);
start = Sys_DoubleTime ();
for (i = 0; i < 1000000; i++) {
vec3_t p, x;
VectorSet (rnd (&mt), rnd (&mt), rnd (&mt), p);
BarycentricCoords (tetra, 4, p, lambda);
VectorZero (x);
for (j = 0; j < 4; j++)
VectorMultAdd (x, lambda[j], tetra[j], x);
if (VectorDistance_fast (x, p) > 1e-4) {
res = 1;
printf ("[%.9g %.9g %.9g] != [%.9g %.9g %.9g]: [%g %g %g %g]\n",
VectorExpand (x), VectorExpand (p), QuatExpand (lambda));
break;
}
}
end = Sys_DoubleTime ();
printf ("%d itterations in %gs: %g itters/second\n", (int) i, end - start,
i / (end - start));
return res;
}