quat quat_lerp(const quat *q1, const quat *q2, float t) { quat q3, q4; q3 = quat_scale(q1, (1-t)); q4 = quat_scale(q2, t); q3 = quat_add(&q3, &q4); return quat_normalize(&q3); }
quat quat_slerp(const quat *q1, const quat *q2, float t) { float cos_theta = quat_dot(q1, q2); float theta = acos(cos_theta); float sin_theta = sin(theta); if (sin_theta > 0.001f) { float w1 = sin( (1.f-t) * theta) / sin_theta; float w2 = sin(t * theta) / sin_theta; quat q3, q4; q3 = quat_scale(q1, w1); q4 = quat_scale(q2, w2); return quat_add(&q3, &q4); } else { return quat_lerp(q1, q2, t); } }
void quat_scale_self(union quat *q, float f) { quat_scale(q, q, f); }
void quat_normalize(union quat *o, const union quat *q) { /* see: http://www.euclideanspace.com/maths/algebra/ realNormedAlgebra/quaternions/code/index.htm#normalise */ quat_scale(o, q, 1.0f / quat_len(q)); }
int main( int argc, char** argv ) { osg::ArgumentParser arguments(&argc,argv); // set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage()->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."); 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 printQuatTest = false; while (arguments.read("quat")) printQuatTest = true; 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<<arguments.getApplicationUsage()->getCommandLineUsage()<<std::endl; arguments.getApplicationUsage()->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 ******"<<std::endl; testFrustum(-1,1,-1,1,1,1000); testFrustum(0,1,1,2,2.5,100000); testOrtho(0,1,1,2,2.1,1000); testOrtho(-1,10,1,20,2.5,100000); testPerspective(20,1,1,1000); testPerspective(90,2,1,1000); testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(0.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0)); testLookAt(osg::Vec3(10.0,4.0,2.0),osg::Vec3(10.0,4.0,2.0)+osg::Vec3(1.0,1.0,0.0),osg::Vec3(0.0,0.0,1.0)); testMatrixInvert(osg::Matrix(0.999848, -0.002700, 0.017242, -0.1715, 0, 0.987960, 0.154710, 0.207295, -0.017452, -0.154687, 0.987809, -0.98239, 0, 0, 0, 1)); testMatrixInvert(osg::Matrix(0.999848, -0.002700, 0.017242, 0.0, 0.0, 0.987960, 0.154710, 0.0, -0.017452, -0.154687, 0.987809, 0.0, -0.1715, 0.207295, -0.98239, 1.0)); } if (printSizeOfTest) { std::cout<<"**** sizeof() tests ******"<<std::endl; sizeOfTest(); std::cout<<std::endl; } if (performanceTest) { std::cout<<"**** performance tests ******"<<std::endl; runPerformanceTests(); } if (printPolytopeTest) { testPolytope(); } if (printQualifiedTest) { std::cout<<"***** Qualified Tests ******"<<std::endl; osgUtx::QualifiedTestPrinter printer; osgUtx::TestGraph::instance().root()->accept( printer ); std::cout<<std::endl; } if (doTestThreadInitAndExit) { testThreadInitAndExit(); } std::cout<<"****** Running tests ******"<<std::endl; // Global Data or Context osgUtx::TestContext ctx; osgUtx::TestRunner runner( ctx ); runner.specify("root"); osgUtx::TestGraph::instance().root()->accept( runner ); return 0; }