From Jose Delport, "attached is a version of osgunittests that does not give false alarms

for the case where q1 = -q2. The output of 'osgunittests quat' is now
much cleaner.
"
This commit is contained in:
Robert Osfield
2008-03-13 16:38:05 +00:00
parent 670c7967ae
commit daef0f64f2

View File

@@ -244,69 +244,95 @@ void testGetQuatFromMatrix(const osg::Vec3d& scale)
tstart = osg::Timer::instance()->tick();
int count=0;
for (double rol1 = rol1start; rol1 <= rol1stop; rol1 += rol1step) {
for (double pit1 = pit1start; pit1 <= pit1stop; pit1 += pit1step) {
for (double yaw1 = yaw1start; yaw1 <= yaw1stop; yaw1 += yaw1step) {
for (double rol2 = rol2start; rol2 <= rol2stop; rol2 += rol2step) {
for (double pit2 = pit2start; pit2 <= pit2stop; pit2 += pit2step) {
for (double yaw2 = yaw2start; yaw2 <= yaw2stop; yaw2 += yaw2step) {
count++;
// create two quats based on the roll, pitch and yaw values
osg::Quat rot_quat1 =
osg::Quat(osg::DegreesToRadians(rol1),osg::Vec3d(1,0,0),
osg::DegreesToRadians(pit1),osg::Vec3d(0,1,0),
osg::DegreesToRadians(yaw1),osg::Vec3d(0,0,1));
osg::Quat rot_quat2 =
osg::Quat(osg::DegreesToRadians(rol2),osg::Vec3d(1,0,0),
osg::DegreesToRadians(pit2),osg::Vec3d(0,1,0),
osg::DegreesToRadians(yaw2),osg::Vec3d(0,0,1));
// create an output quat using quaternion math
osg::Quat out_quat1;
out_quat1 = rot_quat2 * rot_quat1;
// create two matrices based on the input quats
osg::Matrixd mat1,mat2;
mat1.makeRotate(rot_quat1);
mat2.makeRotate(rot_quat2);
// create an output quat by matrix multiplication and getRotate
osg::Matrixd out_mat;
out_mat = mat2 * mat1;
// add matrix scale for even more nastiness
out_mat = out_mat * scalemat;
osg::Quat out_quat2;
out_quat2 = out_mat.getRotate();
// If the quaternion W is <0, then we should reflect
// to get it into the positive W
if(out_quat1.w()<0) out_quat1 = out_quat1 * -1.0;
if(out_quat2.w()<0) out_quat2 = out_quat2 * -1.0;
for (double pit1 = pit1start; pit1 <= pit1stop; pit1 += pit1step) {
for (double yaw1 = yaw1start; yaw1 <= yaw1stop; yaw1 += yaw1step) {
for (double rol2 = rol2start; rol2 <= rol2stop; rol2 += rol2step) {
for (double pit2 = pit2start; pit2 <= pit2stop; pit2 += pit2step) {
for (double yaw2 = yaw2start; yaw2 <= yaw2stop; yaw2 += yaw2step)
{
count++;
// create two quats based on the roll, pitch and yaw values
osg::Quat rot_quat1 =
osg::Quat(osg::DegreesToRadians(rol1),osg::Vec3d(1,0,0),
osg::DegreesToRadians(pit1),osg::Vec3d(0,1,0),
osg::DegreesToRadians(yaw1),osg::Vec3d(0,0,1));
osg::Quat rot_quat2 =
osg::Quat(osg::DegreesToRadians(rol2),osg::Vec3d(1,0,0),
osg::DegreesToRadians(pit2),osg::Vec3d(0,1,0),
osg::DegreesToRadians(yaw2),osg::Vec3d(0,0,1));
// if the output quat length is not one
// or if the components do not match,
// something is amiss
if (fabs(1.0-out_quat2.length()) > eps ||
(fabs(out_quat1.x()-out_quat2.x())) > eps ||
(fabs(out_quat1.y()-out_quat2.y())) > eps ||
(fabs(out_quat1.z()-out_quat2.z())) > eps ||
(fabs(out_quat1.w()-out_quat2.w())) > eps) {
std::cout << "testGetQuatFromMatrix problem at: \n"
<< " r1=" << rol1
<< " p1=" << pit1
<< " y1=" << yaw1
<< " r2=" << rol2
<< " p2=" << pit2
<< " y2=" << yaw2 << "\n";
std::cout << "quats: " << out_quat1 << " length: " << out_quat1.length() << "\n";
std::cout << "mats and get: " << out_quat2 << " length: " << out_quat2.length() << "\n\n";
// create an output quat using quaternion math
osg::Quat out_quat1;
out_quat1 = rot_quat2 * rot_quat1;
// create two matrices based on the input quats
osg::Matrixd mat1,mat2;
mat1.makeRotate(rot_quat1);
mat2.makeRotate(rot_quat2);
// create an output quat by matrix multiplication and getRotate
osg::Matrixd out_mat;
out_mat = mat2 * mat1;
// add matrix scale for even more nastiness
out_mat = out_mat * scalemat;
osg::Quat out_quat2;
out_quat2 = out_mat.getRotate();
// If the quaternion W is <0, then we should reflect
// to get it into the positive W.
// Unfortunately, when W is very small (close to 0), the sign
// does not really make sense because of precision problems
// and the reflection might not work.
if(out_quat1.w()<0) out_quat1 = out_quat1 * -1.0;
if(out_quat2.w()<0) out_quat2 = out_quat2 * -1.0;
// if the output quat length is not one
// or if the components do not match,
// something is amiss
bool componentsOK = false;
if ( ((fabs(out_quat1.x()-out_quat2.x())) < eps) &&
((fabs(out_quat1.y()-out_quat2.y())) < eps) &&
((fabs(out_quat1.z()-out_quat2.z())) < eps) &&
((fabs(out_quat1.w()-out_quat2.w())) < eps) )
{
componentsOK = true;
}
// We should also test for q = -q which is valid, so reflect
// one quat.
out_quat2 = out_quat2 * -1.0;
if ( ((fabs(out_quat1.x()-out_quat2.x())) < eps) &&
((fabs(out_quat1.y()-out_quat2.y())) < eps) &&
((fabs(out_quat1.z()-out_quat2.z())) < eps) &&
((fabs(out_quat1.w()-out_quat2.w())) < eps) )
{
componentsOK = true;
}
bool lengthOK = false;
if (fabs(1.0-out_quat2.length()) < eps)
{
lengthOK = true;
}
if (!lengthOK || !componentsOK)
{
std::cout << "testGetQuatFromMatrix problem at: \n"
<< " r1=" << rol1
<< " p1=" << pit1
<< " y1=" << yaw1
<< " r2=" << rol2
<< " p2=" << pit2
<< " y2=" << yaw2 << "\n";
std::cout << "quats: " << out_quat1 << " length: " << out_quat1.length() << "\n";
std::cout << "mats and get: " << out_quat2 << " length: " << out_quat2.length() << "\n\n";
}
}
}
}
}
}
}
}
}
}
tstop = osg::Timer::instance()->tick();
double duration = osg::Timer::instance()->delta_s(tstart,tstop);