/* OpenSceneGraph example, osgunittests. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include "UnitTestFramework.h" #include "performance.h" #include "MultiThreadRead.h" #include extern void runFileNameUtilsTest(osg::ArgumentParser& arguments); void testFrustum(double left,double right,double bottom,double top,double zNear,double zFar) { osg::Matrix f; f.makeFrustum(left,right,bottom,top,zNear,zFar); double c_left=0; double c_right=0; double c_top=0; double c_bottom=0; double c_zNear=0; double c_zFar=0; std::cout << "testFrustum"<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. // 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); std::cout << "Time for testGetQuatFromMatrix with " << count << " iterations: " << duration << std::endl << std::endl; } void testQuatRotate(const osg::Vec3d& from, const osg::Vec3d& to) { osg::Quat q_nicolas; q_nicolas.makeRotate(from,to); osg::Quat q_original; q_original.makeRotate_original(from,to); std::cout<<"osg::Quat::makeRotate("<setDescription(arguments.getApplicationName()+" is the example which runs units tests."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]"); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests."); arguments.getApplicationUsage()->addCommandLineOption("quat","Display extended quaternion tests."); arguments.getApplicationUsage()->addCommandLineOption("quat_scaled sx sy sz","Display extended quaternion tests of pre scaled matrix."); arguments.getApplicationUsage()->addCommandLineOption("sizeof","Display sizeof tests."); arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests."); arguments.getApplicationUsage()->addCommandLineOption("performance","Display qualified tests."); arguments.getApplicationUsage()->addCommandLineOption("read-threads ","Run multi-thread reading test."); if (arguments.argc()<=1) { arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); return 1; } bool printQualifiedTest = false; while (arguments.read("qt")) printQualifiedTest = true; bool printMatrixTest = false; while (arguments.read("matrix")) printMatrixTest = true; bool printSizeOfTest = false; while (arguments.read("sizeof")) printSizeOfTest = true; bool printFileNameUtilsTests = false; while (arguments.read("filenames")) printFileNameUtilsTests = true; bool printQuatTest = false; while (arguments.read("quat")) printQuatTest = true; int numReadThreads = 0; while (arguments.read("read-threads", numReadThreads)) {} bool printPolytopeTest = false; while (arguments.read("polytope")) printPolytopeTest = true; bool doTestThreadInitAndExit = false; while (arguments.read("thread")) doTestThreadInitAndExit = true; osg::Vec3d quat_scale(1.0,1.0,1.0); while (arguments.read("quat_scaled", quat_scale.x(), quat_scale.y(), quat_scale.z() )) printQuatTest = true; bool performanceTest = false; while (arguments.read("p") || arguments.read("performance")) performanceTest = true; // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) { std::cout<getCommandLineUsage()<write(std::cout,arguments.getApplicationUsage()->getCommandLineOptions()); return 1; } // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); // report any errors if they have occurred when parsing the program arguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); return 1; } if (printQuatTest) { testQuat(quat_scale); } if (printMatrixTest) { std::cout<<"****** Running matrix tests ******"<0) { runMultiThreadReadTests(numReadThreads, arguments); return 0; } if (printPolytopeTest) { testPolytope(); } if (printQualifiedTest) { std::cout<<"***** Qualified Tests ******"<accept( printer ); std::cout<accept( runner ); return 0; }