Add VectorShear and really test Mat4Decompose.

And the tests really exercised VectorShear (first attempt had things
messed up when more than one shear value was non-zero). Also,
Mat4Decompose wasn't orthogonalizing the z axis row. Oops. Anyway,
Mat4Decompose is now known to work well, and the usage of its output is
understood :)
This commit is contained in:
Bill Currie 2012-05-09 22:28:22 +09:00
parent 8cea6b0a1e
commit de131c18ad
3 changed files with 70 additions and 2 deletions

View file

@ -104,6 +104,22 @@ extern const vec_t *const quat_origin;
(c)[1] = (a)[1] * (b); \
(c)[2] = (a)[2] * (b); \
} while (0)
/** Shear vector \a b by vector \a a.
Vector a represents the shear factors XY, XZ, YZ, ie in matrix form:
[ 1 0 0 ] [ b0 ]
[ a0 1 0 ] [ b1 ]
[ a1 a2 1 ] [ b2 ]
The reason for this particular scheme is that is how Mat4Decompose
calculates the shear from a matrix.
*/
#define VectorShear(a,b,c) \
do { \
(c)[2] = (b)[0] * (a)[1] + (b)[1] * (a)[2] + (b)[2]; \
(c)[1] = (b)[0] * (a)[0] + (b)[1]; \
(c)[0] = (b)[0]; \
} while (0)
#define VectorCompMult(a,b,c) \
do { \
(c)[0] = (a)[0] * (b)[0]; \

View file

@ -861,11 +861,10 @@ Mat4Decompose (const mat4_t m, quat_t rot, vec3_t scale, vec3_t shear,
vec_t l, t;
int i, j;
if (trans)
VectorCopy (m + 12, trans);
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
row[j][i] = m[i * 4 + j];
l = DotProduct (row[0], row[0]);
if (l < 1e-5)
return 0;
@ -884,6 +883,7 @@ Mat4Decompose (const mat4_t m, quat_t rot, vec3_t scale, vec3_t shear,
VectorMultSub (row[2], shr[1], row[0], row[2]);
shr[2] = DotProduct (row[1], row[2]);
VectorMultSub (row[2], shr[2], row[1], row[2]);
l = DotProduct (row[2], row[2]);
if (l < 1e-5)
return 0;
@ -895,6 +895,8 @@ Mat4Decompose (const mat4_t m, quat_t rot, vec3_t scale, vec3_t shear,
VectorCopy (scl, scale);
if (shear)
VectorCopy (shr, shear);
if (trans)
VectorCopy (m + 12, trans);
if (!rot)
return 1;

View file

@ -117,6 +117,7 @@ test_transform (const vec3_t angles, const vec3_t scale,
for (i = 0; i < 3; i++)
if (!compare (x[i], y[i]))
goto fail;
return 1;
fail:
printf ("\n\n(%g %g %g) (%g %g %g) (%g %g %g)\n", VectorExpand (angles),
@ -126,6 +127,46 @@ fail:
return 0;
}
static int
test_transform2 (const vec3_t angles, const vec3_t scale,
const vec3_t translation)
{
int i;
const vec3_t v = {4,5,6};
vec3_t x, y;
quat_t rotation;
mat4_t mat;
vec3_t rot, sc, sh, tr;
VectorCopy (v, x);
AngleQuat (angles, rotation);
VectorCompMult (scale, x, x);
QuatMultVec (rotation, x, x);
VectorAdd (translation, x, x);
Mat4Init (rotation, scale, translation, mat);
Mat4Decompose (mat, rot, sc, sh, tr);
VectorCopy (v, y);
QuatMultVec (rot, y, y);
VectorShear (sh, y, y);
VectorCompMult (sc, y, y);//scale
VectorAdd (tr, y, y);
for (i = 0; i < 3; i++)
if (!compare (x[i], y[i]))
goto fail;
return 1;
fail:
printf ("\n\n(%g %g %g) (%g %g %g) (%g %g %g) (%g %g %g)\n",
VectorExpand (angles), VectorExpand (scale),
VectorExpand (translation), VectorExpand (v));
printf (" (%g %g %g)\n", VectorExpand (x));
printf (" (%g %g %g)\n", VectorExpand (y));
return 0;
}
int
main (int argc, const char **argv)
{
@ -145,5 +186,14 @@ main (int argc, const char **argv)
}
}
}
for (i = 0; i < num_angle_tests; i ++) {
for (j = 0; j < num_translation_tests; j ++) {
for (k = 0; k < num_translation_tests; k ++) {
if (!test_transform2 (test_angles[i], test_scales[j],
test_translations[k]))
res = 1;
}
}
}
return res;
}