mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-12-11 21:31:30 +00:00
132 lines
3.2 KiB
C
132 lines
3.2 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include "QF/mathlib.h"
|
|
|
|
//PITCH YAW ROLL
|
|
static vec3_t test_transforms[][2] = {
|
|
{{ 0, 0, 0}, { 0, 0, 0}},
|
|
{{ 0, 0, 0}, { 1, 2, 3}},
|
|
{{45, 0, 0}, { 0, 0, 0}},
|
|
{{45, 0, 0}, {-1, 2, 3}},
|
|
{{ 0, 45, 0}, { 0, 0, 0}},
|
|
{{ 0, 45, 0}, { 1,-2, 3}},
|
|
{{ 0, 0, 45}, { 0, 0, 0}},
|
|
{{ 0, 0, 45}, { 1, 2,-3}},
|
|
{{45, 45, 0}, { 0, 0, 0}},
|
|
{{45, 45, 0}, {-1,-2, 3}},
|
|
{{ 0, 45, 45}, { 0, 0, 0}},
|
|
{{ 0, 45, 45}, {-1, 2,-3}},
|
|
{{45, 0, 45}, { 0, 0, 0}},
|
|
{{45, 0, 45}, { 1,-2,-3}},
|
|
{{45, 45, 45}, { 0, 0, 0}},
|
|
{{45, 45, 45}, {-1,-2,-3}},
|
|
};
|
|
#define num_transform_tests \
|
|
(sizeof (test_transforms) / sizeof (test_transforms[0]))
|
|
|
|
// return true if a and b are close enough (yay, floats)
|
|
static int
|
|
compare (vec_t a, vec_t b)
|
|
{
|
|
vec_t diff = a - b;
|
|
return diff * diff < 0.001;
|
|
}
|
|
|
|
static int
|
|
test_transform (const vec3_t angles, const vec3_t translation)
|
|
{
|
|
int i;
|
|
const vec3_t v = {4,5,6};
|
|
vec3_t x;
|
|
quat_t rotation;
|
|
DualQuat_t transform, conj;
|
|
DualQuat_t inverse, iconj;
|
|
DualQuat_t vd, xd, ix;
|
|
Dual_t dual;
|
|
|
|
VectorZero (x);
|
|
DualQuatZero (xd);
|
|
DualQuatZero (ix);
|
|
|
|
AngleQuat (angles, rotation);
|
|
DualQuatSetVect (v, vd);
|
|
DualQuatRotTrans (rotation, translation, transform);
|
|
DualQuatConjQE (transform, conj);
|
|
|
|
DualQuatConjQ (transform, inverse);
|
|
DualQuatConjQE (inverse, iconj);
|
|
|
|
DualQuatNorm (vd, dual);
|
|
if (!DualIsUnit (dual)) {
|
|
printf ("dual vector not unit: "
|
|
"[(%g %g %g %g) (%g %g %g %g)] -> [%g %g]\n",
|
|
DualQuatExpand (vd), DualExpand (dual));
|
|
goto fail;
|
|
}
|
|
|
|
DualQuatNorm (transform, dual);
|
|
if (!DualIsUnit (dual)) {
|
|
printf ("dual quat not unit: "
|
|
"[(%g %g %g %g) (%g %g %g %g)] -> [%g %g]\n",
|
|
DualQuatExpand (transform), DualExpand (dual));
|
|
goto fail;
|
|
}
|
|
|
|
QuatMultVec (rotation, v, x);
|
|
VectorAdd (x, translation, x);
|
|
|
|
DualQuatMult (transform, vd, xd);
|
|
DualQuatMult (xd, conj, xd);
|
|
|
|
DualQuatMult (inverse, xd, ix);
|
|
DualQuatMult (ix, iconj, ix);
|
|
|
|
DualQuatNorm (xd, dual);
|
|
if (!DualIsUnit (dual)) {
|
|
printf ("dual result not unit: "
|
|
"[(%g %g %g %g) (%g %g %g %g)] -> [%g %g]\n",
|
|
DualQuatExpand (xd), DualExpand (dual));
|
|
goto fail;
|
|
}
|
|
|
|
DualQuatNorm (ix, dual);
|
|
if (!DualIsUnit (dual)) {
|
|
printf ("dual inverse not unit: "
|
|
"[(%g %g %g %g) (%g %g %g %g)] -> [%g %g]\n",
|
|
DualQuatExpand (ix), DualExpand (dual));
|
|
goto fail;
|
|
}
|
|
|
|
for (i = 0; i < 3; i++)
|
|
if (!compare (xd.qe.sv.v[i], x[i]))
|
|
goto fail;
|
|
for (i = 0; i < 3; i++)
|
|
if (!compare (ix.qe.sv.v[i], v[i]))
|
|
goto fail;
|
|
return 1;
|
|
fail:
|
|
printf ("\n\n(%g %g %g) (%g %g %g)\n",
|
|
VectorExpand (angles), VectorExpand (translation));
|
|
printf (" [(%g %g %g %g) (%g %g %g %g)]\n", DualQuatExpand (transform));
|
|
printf (" [(%g %g %g %g) (%g %g %g %g)]\n", DualQuatExpand (vd));
|
|
printf (" [(%g %g %g %g) (%g %g %g %g)]\n", DualQuatExpand (conj));
|
|
printf (" (%g %g %g)\n", VectorExpand (x));
|
|
printf (" (%g %g %g)\n", VectorExpand (xd.qe.sv.v));
|
|
printf (" (%g %g %g)\n", VectorExpand (ix.qe.sv.v));
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
main (int argc, const char **argv)
|
|
{
|
|
int res = 0;
|
|
size_t i;
|
|
|
|
for (i = 0; i < num_transform_tests; i ++) {
|
|
if (!test_transform (test_transforms[i][0], test_transforms[i][1]))
|
|
res = 1;
|
|
}
|
|
return res;
|
|
}
|