From J.P Delport, "attached find an updated osgunittests.cpp that allows for the testing of
the matrix.getRotate() function when a matrix contains a scale as well as a rotation. The scale can optionally be switched off, see the top of testQuatFromMatrix(). As expected, all the current methods for mat to quat conversion fail these new tests. When the scale is omitted, mk2 of getRotate with sign instead of signOrZero passes, as well as mk1. "
This commit is contained in:
parent
b92ebca928
commit
9a0b39c34b
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <osg/Vec3>
|
#include <osg/Vec3>
|
||||||
#include <osg/Matrix>
|
#include <osg/Matrix>
|
||||||
|
#include <osg/Timer>
|
||||||
#include <osg/io_utils>
|
#include <osg/io_utils>
|
||||||
|
|
||||||
#include "UnitTestFramework.h"
|
#include "UnitTestFramework.h"
|
||||||
@ -143,36 +144,51 @@ void sizeOfTest()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exercises the Matrix.get(Quat&) function, printout is generated on problems only
|
/// Exercise the Matrix.getRotate function.
|
||||||
|
/// Compare the output of:
|
||||||
|
/// q1 * q2
|
||||||
|
/// versus
|
||||||
|
/// (mat(q1)*mat(q2)*scale).getRotate()
|
||||||
|
/// for a range of rotations
|
||||||
void testGetQuatFromMatrix() {
|
void testGetQuatFromMatrix() {
|
||||||
// acceptable error range
|
|
||||||
double eps=1e-3;
|
|
||||||
|
|
||||||
|
// Options
|
||||||
|
|
||||||
|
// acceptable error range
|
||||||
|
double eps=1e-6;
|
||||||
|
|
||||||
|
// scale matrix
|
||||||
|
// To not test with scale, use 1,1,1
|
||||||
|
// Not sure if 0's or negative values are acceptable
|
||||||
|
osg::Matrixd scalemat;
|
||||||
|
scalemat.makeScale(osg::Vec3d(0.9,0.5,0.1));
|
||||||
|
|
||||||
|
// range of rotations
|
||||||
#if 1
|
#if 1
|
||||||
// wide range
|
// wide range
|
||||||
double rol1start = 0.0;
|
double rol1start = 0.0;
|
||||||
double rol1stop = 360.0;
|
double rol1stop = 360.0;
|
||||||
double rol1step = 30.0;
|
double rol1step = 20.0;
|
||||||
|
|
||||||
double pit1start = 0.0;
|
double pit1start = 0.0;
|
||||||
double pit1stop = 90.0;
|
double pit1stop = 90.0;
|
||||||
double pit1step = 30.0;
|
double pit1step = 20.0;
|
||||||
|
|
||||||
double yaw1start = 0.0;
|
double yaw1start = 0.0;
|
||||||
double yaw1stop = 360.0;
|
double yaw1stop = 360.0;
|
||||||
double yaw1step = 30.0;
|
double yaw1step = 20.0;
|
||||||
|
|
||||||
double rol2start = 0.0;
|
double rol2start = 0.0;
|
||||||
double rol2stop = 360.0;
|
double rol2stop = 360.0;
|
||||||
double rol2step = 30.0;
|
double rol2step = 20.0;
|
||||||
|
|
||||||
double pit2start = 0.0;
|
double pit2start = 0.0;
|
||||||
double pit2stop = 90.0;
|
double pit2stop = 90.0;
|
||||||
double pit2step = 30.0;
|
double pit2step = 20.0;
|
||||||
|
|
||||||
double yaw2start = 0.0;
|
double yaw2start = 0.0;
|
||||||
double yaw2stop = 360.0;
|
double yaw2stop = 360.0;
|
||||||
double yaw2step = 30.0;
|
double yaw2step = 20.0;
|
||||||
#else
|
#else
|
||||||
// focussed range
|
// focussed range
|
||||||
double rol1start = 0.0;
|
double rol1start = 0.0;
|
||||||
@ -200,12 +216,18 @@ void testGetQuatFromMatrix() {
|
|||||||
double yaw2step = 0.1;
|
double yaw2step = 0.1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::cout << std::endl << "Starting " << __FUNCTION__ << ", it can take a while ..." << std::endl;
|
||||||
|
|
||||||
|
osg::Timer_t tstart, tstop;
|
||||||
|
tstart = osg::Timer::instance()->tick();
|
||||||
|
int count=0;
|
||||||
for (double rol1 = rol1start; rol1 <= rol1stop; rol1 += rol1step) {
|
for (double rol1 = rol1start; rol1 <= rol1stop; rol1 += rol1step) {
|
||||||
for (double pit1 = pit1start; pit1 <= pit1stop; pit1 += pit1step) {
|
for (double pit1 = pit1start; pit1 <= pit1stop; pit1 += pit1step) {
|
||||||
for (double yaw1 = yaw1start; yaw1 <= yaw1stop; yaw1 += yaw1step) {
|
for (double yaw1 = yaw1start; yaw1 <= yaw1stop; yaw1 += yaw1step) {
|
||||||
for (double rol2 = rol2start; rol2 <= rol2stop; rol2 += rol2step) {
|
for (double rol2 = rol2start; rol2 <= rol2stop; rol2 += rol2step) {
|
||||||
for (double pit2 = pit2start; pit2 <= pit2stop; pit2 += pit2step) {
|
for (double pit2 = pit2start; pit2 <= pit2stop; pit2 += pit2step) {
|
||||||
for (double yaw2 = yaw2start; yaw2 <= yaw2stop; yaw2 += yaw2step) {
|
for (double yaw2 = yaw2start; yaw2 <= yaw2stop; yaw2 += yaw2step) {
|
||||||
|
count++;
|
||||||
// create two quats based on the roll, pitch and yaw values
|
// create two quats based on the roll, pitch and yaw values
|
||||||
osg::Quat rot_quat1 =
|
osg::Quat rot_quat1 =
|
||||||
osg::Quat(osg::DegreesToRadians(rol1),osg::Vec3d(1,0,0),
|
osg::Quat(osg::DegreesToRadians(rol1),osg::Vec3d(1,0,0),
|
||||||
@ -226,9 +248,11 @@ void testGetQuatFromMatrix() {
|
|||||||
mat1.makeRotate(rot_quat1);
|
mat1.makeRotate(rot_quat1);
|
||||||
mat2.makeRotate(rot_quat2);
|
mat2.makeRotate(rot_quat2);
|
||||||
|
|
||||||
// create an output quat by matrix multiplication and get
|
// create an output quat by matrix multiplication and getRotate
|
||||||
osg::Matrixd out_mat;
|
osg::Matrixd out_mat;
|
||||||
out_mat = mat2 * mat1;
|
out_mat = mat2 * mat1;
|
||||||
|
// add matrix scale for even more nastiness
|
||||||
|
out_mat = out_mat * scalemat;
|
||||||
osg::Quat out_quat2;
|
osg::Quat out_quat2;
|
||||||
out_quat2 = out_mat.getRotate();
|
out_quat2 = out_mat.getRotate();
|
||||||
|
|
||||||
@ -240,7 +264,8 @@ void testGetQuatFromMatrix() {
|
|||||||
(fabs(out_quat1.y())-fabs(out_quat2.y())) > eps ||
|
(fabs(out_quat1.y())-fabs(out_quat2.y())) > eps ||
|
||||||
(fabs(out_quat1.z())-fabs(out_quat2.z())) > eps ||
|
(fabs(out_quat1.z())-fabs(out_quat2.z())) > eps ||
|
||||||
(fabs(out_quat1.w())-fabs(out_quat2.w())) > eps) {
|
(fabs(out_quat1.w())-fabs(out_quat2.w())) > eps) {
|
||||||
std::cout << "problem at: r1=" << rol1
|
std::cout << __FUNCTION__ << " problem at: \n"
|
||||||
|
<< " r1=" << rol1
|
||||||
<< " p1=" << pit1
|
<< " p1=" << pit1
|
||||||
<< " y1=" << yaw1
|
<< " y1=" << yaw1
|
||||||
<< " r2=" << rol2
|
<< " r2=" << rol2
|
||||||
@ -255,6 +280,9 @@ void testGetQuatFromMatrix() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tstop = osg::Timer::instance()->tick();
|
||||||
|
double duration = osg::Timer::instance()->delta_s(tstart,tstop);
|
||||||
|
std::cout << "Time for " << __FUNCTION__ << " with " << count << " iterations: " << duration << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testQuatRotate(const osg::Vec3d& from, const osg::Vec3d& to)
|
void testQuatRotate(const osg::Vec3d& from, const osg::Vec3d& to)
|
||||||
@ -313,9 +341,10 @@ void testQuat()
|
|||||||
testQuatRotate(osg::Vec3d(0.0,0.0,1.0),osg::Vec3d(0.0,0.0,-1.0));
|
testQuatRotate(osg::Vec3d(0.0,0.0,1.0),osg::Vec3d(0.0,0.0,-1.0));
|
||||||
testQuatRotate(osg::Vec3d(0.0,0.0,-1.0),osg::Vec3d(0.0,0.0,1.0));
|
testQuatRotate(osg::Vec3d(0.0,0.0,-1.0),osg::Vec3d(0.0,0.0,1.0));
|
||||||
|
|
||||||
|
// Test a range of rotations
|
||||||
testGetQuatFromMatrix();
|
testGetQuatFromMatrix();
|
||||||
|
|
||||||
|
// This is a specific test case for a matrix containing scale and rotation
|
||||||
osg::Matrix matrix(0.5, 0.0, 0.0, 0.0,
|
osg::Matrix matrix(0.5, 0.0, 0.0, 0.0,
|
||||||
0.0, 0.5, 0.0, 0.0,
|
0.0, 0.5, 0.0, 0.0,
|
||||||
0.0, 0.0, 0.5, 0.0,
|
0.0, 0.0, 0.5, 0.0,
|
||||||
@ -324,8 +353,7 @@ void testQuat()
|
|||||||
osg::Quat quat;
|
osg::Quat quat;
|
||||||
matrix.get(quat);
|
matrix.get(quat);
|
||||||
|
|
||||||
osg::notify(osg::NOTICE)<<"Matrix = "<<matrix<<" rotation="<<quat<<std::endl;
|
osg::notify(osg::NOTICE)<<"Matrix = "<<matrix<<"rotation = "<<quat<<", expected quat = (0,0,0,1)"<<std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user