mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-12-12 21:52:32 +00:00
3193ffd9cc
Now the distribution should be more even as the rng doesn't affect the exponent.
118 lines
2.9 KiB
C
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.333333284, 0.333333333, 0.333333333}},//rounding :P
|
|
{tri, 3, points[8], {0.333333284, 0.333333333, 0.333333333}},//rounding :P
|
|
{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;
|
|
}
|