root/OpenSceneGraph/trunk/examples/osgunittests/osgunittests.cpp @ 5828

Revision 5828, 14.3 kB (checked in by robert, 8 years ago)

Moved UnitTestFramework? from core osg lib into osgunittests example

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/ArgumentParser>
2#include <osg/ApplicationUsage>
3
4#include <osg/Vec3>
5#include <osg/Matrix>
6#include <osg/io_utils>
7
8#include "UnitTestFramework.h"
9#include "performance.h"
10
11#include <iostream>
12
13void testFrustum(double left,double right,double bottom,double top,double zNear,double zFar)
14{
15    osg::Matrix f;
16    f.makeFrustum(left,right,bottom,top,zNear,zFar);
17
18    double c_left=0;
19    double c_right=0;
20    double c_top=0;
21    double c_bottom=0;
22    double c_zNear=0;
23    double c_zFar=0;
24   
25   
26    std::cout << "testFrustum"<<f.getFrustum(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar)<<std::endl;
27    std::cout << "  left = "<<left<<" compute "<<c_left<<std::endl;
28    std::cout << "  right = "<<right<<" compute "<<c_right<<std::endl;
29
30    std::cout << "  bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
31    std::cout << "  top = "<<top<<" compute "<<c_top<<std::endl;
32
33    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
34    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
35   
36    std::cout << std::endl;
37}
38
39void testOrtho(double left,double right,double bottom,double top,double zNear,double zFar)
40{
41    osg::Matrix f;
42    f.makeOrtho(left,right,bottom,top,zNear,zFar);
43
44    double c_left=0;
45    double c_right=0;
46    double c_top=0;
47    double c_bottom=0;
48    double c_zNear=0;
49    double c_zFar=0;
50
51    std::cout << "testOrtho "<< f.getOrtho(c_left,c_right,c_bottom,c_top,c_zNear,c_zFar) << std::endl;
52    std::cout << "  left = "<<left<<" compute "<<c_left<<std::endl;
53    std::cout << "  right = "<<right<<" compute "<<c_right<<std::endl;
54
55    std::cout << "  bottom = "<<bottom<<" compute "<<c_bottom<<std::endl;
56    std::cout << "  top = "<<top<<" compute "<<c_top<<std::endl;
57
58    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
59    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
60   
61    std::cout << std::endl;
62}
63
64void testPerspective(double fovy,double aspect,double zNear,double zFar)
65{
66    osg::Matrix f;
67    f.makePerspective(fovy,aspect,zNear,zFar);
68
69    double c_fovy=0;
70    double c_aspect=0;
71    double c_zNear=0;
72    double c_zFar=0;
73
74    std::cout << "testPerspective "<< f.getPerspective(c_fovy,c_aspect,c_zNear,c_zFar) << std::endl;
75    std::cout << "  fovy = "<<fovy<<" compute "<<c_fovy<<std::endl;
76    std::cout << "  aspect = "<<aspect<<" compute "<<c_aspect<<std::endl;
77
78    std::cout << "  zNear = "<<zNear<<" compute "<<c_zNear<<std::endl;
79    std::cout << "  zFar = "<<zFar<<" compute "<<c_zFar<<std::endl;
80   
81    std::cout << std::endl;
82}
83
84void testLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up)
85{
86    osg::Matrix mv;
87    mv.makeLookAt(eye,center,up);
88   
89    osg::Vec3 c_eye,c_center,c_up;
90    mv.getLookAt(c_eye,c_center,c_up);
91   
92    std::cout << "testLookAt"<<std::endl;
93    std::cout << "  eye "<<eye<< " compute "<<c_eye<<std::endl;
94    std::cout << "  center "<<center<< " compute "<<c_center<<std::endl;
95    std::cout << "  up "<<up<< " compute "<<c_up<<std::endl;
96   
97    std::cout << std::endl;
98   
99}
100
101
102void testMatrixInvert(const osg::Matrix& matrix)
103{
104    //Invert it twice using the two inversion functions and view the results
105    osg::notify(osg::NOTICE)<<"testMatrixInvert("<<std::endl;
106    osg::notify(osg::NOTICE)<<matrix<<std::endl;
107    osg::notify(osg::NOTICE)<<")"<<std::endl;
108
109    osg::Matrix invM1_0;
110    invM1_0.invert(matrix);
111    osg::notify(osg::NOTICE)<<"Matrix::invert"<<std::endl;
112    osg::notify(osg::NOTICE)<<invM1_0<<std::endl;
113    osg::Matrix default_result = matrix*invM1_0;
114    osg::notify(osg::NOTICE)<<"matrix * invert="<<std::endl;
115    osg::notify(osg::NOTICE)<<default_result<<std::endl;;
116
117}
118
119void sizeOfTest()
120{
121  std::cout<<"sizeof(bool)=="<<sizeof(bool)<<std::endl;
122  std::cout<<"sizeof(char)=="<<sizeof(char)<<std::endl;
123  std::cout<<"sizeof(short)=="<<sizeof(short)<<std::endl;
124  std::cout<<"sizeof(short int)=="<<sizeof(short int)<<std::endl;
125  std::cout<<"sizeof(int)=="<<sizeof(int)<<std::endl;
126  std::cout<<"sizeof(long)=="<<sizeof(long)<<std::endl;
127  std::cout<<"sizeof(long int)=="<<sizeof(long int)<<std::endl;
128
129#if defined(_MSC_VER)
130  // long long isn't supported on VS6.0...
131  std::cout<<"sizeof(__int64)=="<<sizeof(__int64)<<std::endl;
132#else
133  std::cout<<"sizeof(long long)=="<<sizeof(long long)<<std::endl;
134#endif
135  std::cout<<"sizeof(float)=="<<sizeof(float)<<std::endl;
136  std::cout<<"sizeof(double)=="<<sizeof(double)<<std::endl;
137
138  std::cout<<"sizeof(std::istream::pos_type)=="<<sizeof(std::istream::pos_type)<<std::endl;
139  std::cout<<"sizeof(std::istream::off_type)=="<<sizeof(std::istream::off_type)<<std::endl;
140  std::cout<<"sizeof(OpenThreads::Mutex)=="<<sizeof(OpenThreads::Mutex)<<std::endl;
141
142  std::cout<<"sizeof(std::string)=="<<sizeof(std::string)<<std::endl;
143
144}
145
146/// Exercises the Matrix.get(Quat&) function, printout is generated on problems only
147void testGetQuatFromMatrix() {
148    // acceptable error range
149    double eps=1e-3;
150
151#if 1
152    // wide range
153    double rol1start = 0.0;
154    double rol1stop = 360.0;
155    double rol1step = 30.0;
156
157    double pit1start = 0.0;
158    double pit1stop = 90.0;
159    double pit1step = 30.0;
160
161    double yaw1start = 0.0;
162    double yaw1stop = 360.0;
163    double yaw1step = 30.0;
164
165    double rol2start = 0.0;
166    double rol2stop = 360.0;
167    double rol2step = 30.0;
168
169    double pit2start = 0.0;
170    double pit2stop = 90.0;
171    double pit2step = 30.0;
172
173    double yaw2start = 0.0;
174    double yaw2stop = 360.0;
175    double yaw2step = 30.0;
176#else
177    // focussed range
178    double rol1start = 0.0;
179    double rol1stop = 0.0;
180    double rol1step = 0.1;
181
182    double pit1start = 0.0;
183    double pit1stop = 5.0;
184    double pit1step = 5.0;
185
186    double yaw1start = 89.0;
187    double yaw1stop = 91.0;
188    double yaw1step = 0.1;
189
190    double rol2start = 0.0;
191    double rol2stop = 0.0;
192    double rol2step = 0.1;
193
194    double pit2start = 0.0;
195    double pit2stop = 0.0;
196    double pit2step = 0.1;
197
198    double yaw2start = 89.0;
199    double yaw2stop = 91.0;
200    double yaw2step = 0.1;
201#endif
202   
203    for (double rol1 = rol1start; rol1 <= rol1stop; rol1 += rol1step) {
204        for (double pit1 = pit1start; pit1 <= pit1stop; pit1 += pit1step) {
205            for (double yaw1 = yaw1start; yaw1 <= yaw1stop; yaw1 += yaw1step) {
206                for (double rol2 = rol2start; rol2 <= rol2stop; rol2 += rol2step) {
207                    for (double pit2 = pit2start; pit2 <= pit2stop; pit2 += pit2step) {
208                        for (double yaw2 = yaw2start; yaw2 <= yaw2stop; yaw2 += yaw2step) {
209                            // create two quats based on the roll, pitch and yaw values
210                            osg::Quat rot_quat1 =
211                                osg::Quat(osg::DegreesToRadians(rol1),osg::Vec3d(1,0,0),
212                                          osg::DegreesToRadians(pit1),osg::Vec3d(0,1,0),
213                                          osg::DegreesToRadians(yaw1),osg::Vec3d(0,0,1));
214                           
215                            osg::Quat rot_quat2 =
216                                osg::Quat(osg::DegreesToRadians(rol2),osg::Vec3d(1,0,0),
217                                          osg::DegreesToRadians(pit2),osg::Vec3d(0,1,0),
218                                          osg::DegreesToRadians(yaw2),osg::Vec3d(0,0,1));
219                           
220                            // create an output quat using quaternion math
221                            osg::Quat out_quat1;
222                            out_quat1 = rot_quat2 * rot_quat1;
223                           
224                            // create two matrices based on the input quats
225                            osg::Matrixd mat1,mat2;
226                            mat1.makeRotate(rot_quat1);
227                            mat2.makeRotate(rot_quat2);
228                           
229                            // create an output quat by matrix multiplication and get
230                            osg::Matrixd out_mat;
231                            out_mat = mat2 * mat1;
232                            osg::Quat out_quat2;
233                            out_quat2 = out_mat.getRotate();
234                           
235                            // if the output quat length is not one
236                            // or if the component magnitudes do not match,
237                            // something is amiss
238                            if (fabs(1.0-out_quat2.length()) > eps ||
239                                (fabs(out_quat1.x())-fabs(out_quat2.x())) > eps ||
240                                (fabs(out_quat1.y())-fabs(out_quat2.y())) > eps ||
241                                (fabs(out_quat1.z())-fabs(out_quat2.z())) > eps ||
242                                (fabs(out_quat1.w())-fabs(out_quat2.w())) > eps) {
243                                std::cout << "problem at: r1=" << rol1
244                                          << " p1=" << pit1
245                                          << " y1=" << yaw1
246                                          << " r2=" << rol2
247                                          << " p2=" << pit2
248                                          << " y2=" << yaw2 << "\n";
249                                std::cout << "quats:        " << out_quat1 << " length: " << out_quat1.length() << "\n";
250                                std::cout << "mats and get: " << out_quat2 << " length: " << out_quat2.length() << "\n\n";
251                            }
252                        }
253                    }
254                }
255            }
256        }
257    }
258}
259
260void testQuatRotate(const osg::Vec3d& from, const osg::Vec3d& to)
261{
262    osg::Quat q_nicolas;
263    q_nicolas.makeRotate(from,to);
264   
265    osg::Quat q_original;
266    q_original.makeRotate_original(from,to);
267   
268    std::cout<<"osg::Quat::makeRotate("<<from<<", "<<to<<")"<<std::endl;
269    std::cout<<"  q_nicolas = "<<q_nicolas<<std::endl;
270    std::cout<<"  q_original = "<<q_original<<std::endl;
271    std::cout<<"  from * M4x4(q_nicolas) = "<<from * osg::Matrixd::rotate(q_nicolas)<<std::endl;
272    std::cout<<"  from * M4x4(q_original) = "<<from * osg::Matrixd::rotate(q_original)<<std::endl;
273}
274
275void testQuat()
276{
277    osg::Quat q1;
278    q1.makeRotate(osg::DegreesToRadians(30.0),0.0f,0.0f,1.0f);
279
280    osg::Quat q2;
281    q2.makeRotate(osg::DegreesToRadians(133.0),0.0f,1.0f,1.0f);
282
283    osg::Quat q1_2 = q1*q2;
284    osg::Quat q2_1 = q2*q1;
285
286    osg::Matrix m1 = osg::Matrix::rotate(q1);
287    osg::Matrix m2 = osg::Matrix::rotate(q2);
288   
289    osg::Matrix m1_2 = m1*m2;
290    osg::Matrix m2_1 = m2*m1;
291   
292    osg::Quat qm1_2;
293    qm1_2.set(m1_2);
294   
295    osg::Quat qm2_1;
296    qm2_1.set(m2_1);
297   
298    std::cout<<"q1*q2 = "<<q1_2<<std::endl;
299    std::cout<<"q2*q1 = "<<q2_1<<std::endl;
300    std::cout<<"m1*m2 = "<<qm1_2<<std::endl;
301    std::cout<<"m2*m1 = "<<qm2_1<<std::endl;
302
303
304    testQuatRotate(osg::Vec3d(1.0,0.0,0.0),osg::Vec3d(0.0,1.0,0.0));
305    testQuatRotate(osg::Vec3d(0.0,1.0,0.0),osg::Vec3d(1.0,0.0,0.0));
306    testQuatRotate(osg::Vec3d(0.0,0.0,1.0),osg::Vec3d(0.0,1.0,0.0));
307    testQuatRotate(osg::Vec3d(1.0,1.0,1.0),osg::Vec3d(1.0,0.0,0.0));
308    testQuatRotate(osg::Vec3d(1.0,0.0,0.0),osg::Vec3d(1.0,0.0,0.0));
309    testQuatRotate(osg::Vec3d(1.0,0.0,0.0),osg::Vec3d(-1.0,0.0,0.0));
310    testQuatRotate(osg::Vec3d(-1.0,0.0,0.0),osg::Vec3d(1.0,0.0,0.0));
311    testQuatRotate(osg::Vec3d(0.0,1.0,0.0),osg::Vec3d(0.0,-1.0,0.0));
312    testQuatRotate(osg::Vec3d(0.0,-1.0,0.0),osg::Vec3d(0.0,1.0,0.0));
313    testQuatRotate(osg::Vec3d(0.0,0.0,1.0),osg::Vec3d(0.0,0.0,-1.0));
314    testQuatRotate(osg::Vec3d(0.0,0.0,-1.0),osg::Vec3d(0.0,0.0,1.0));
315
316    testGetQuatFromMatrix();
317}
318
319int main( int argc, char** argv )
320{
321    osg::ArgumentParser arguments(&argc,argv);
322
323    // set up the usage document, in case we need to print out how to use this program.
324    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which runs units tests.");
325    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
326    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
327    arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests.");
328    arguments.getApplicationUsage()->addCommandLineOption("sizeof","Display sizeof tests.");
329    arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");
330    arguments.getApplicationUsage()->addCommandLineOption("performance","Display qualified tests.");
331 
332
333    if (arguments.argc()<=1)
334    {
335        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
336        return 1;
337    }
338
339    bool printQualifiedTest = false;
340    while (arguments.read("qt")) printQualifiedTest = true;
341
342    bool printMatrixTest = false;
343    while (arguments.read("matrix")) printMatrixTest = true;
344
345    bool printSizeOfTest = false;
346    while (arguments.read("sizeof")) printSizeOfTest = true;
347
348    bool printQuatTest = false;
349    while (arguments.read("quat")) printQuatTest = true;
350
351    bool performanceTest = false;
352    while (arguments.read("p") || arguments.read("performance")) performanceTest = true;
353
354    // if user request help write it out to cout.
355    if (arguments.read("-h") || arguments.read("--help"))
356    {
357        std::cout<<arguments.getApplicationUsage()->getCommandLineUsage()<<std::endl;
358        arguments.getApplicationUsage()->write(std::cout,arguments.getApplicationUsage()->getCommandLineOptions());
359        return 1;
360    }
361
362    // any option left unread are converted into errors to write out later.
363    arguments.reportRemainingOptionsAsUnrecognized();
364
365    // report any errors if they have occured when parsing the program aguments.
366    if (arguments.errors())
367    {
368        arguments.writeErrorMessages(std::cout);
369        return 1;
370    }
371   
372    if (printQuatTest)
373    {
374        testQuat();
375    }
376
377
378    if (printMatrixTest)
379    {
380        std::cout<<"******   Running matrix tests   ******"<<std::endl;
381
382        testFrustum(-1,1,-1,1,1,1000);
383        testFrustum(0,1,1,2,2.5,100000);
384
385        testOrtho(0,1,1,2,2.1,1000);
386        testOrtho(-1,10,1,20,2.5,100000);
387
388        testPerspective(20,1,1,1000);
389        testPerspective(90,2,1,1000);
390
391        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));
392        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));
393       
394        testMatrixInvert(osg::Matrix(0.999848,  -0.002700,  0.017242, -0.1715,
395                                     0,         0.987960,   0.154710,  0.207295,
396                                     -0.017452, -0.154687,  0.987809, -0.98239,
397                                     0,         0,          0,         1));
398
399        testMatrixInvert(osg::Matrix(0.999848,  -0.002700,  0.017242,   0.0,
400                                     0.0,        0.987960,   0.154710,   0.0,
401                                     -0.017452, -0.154687,  0.987809,   0.0,
402                                     -0.1715,    0.207295,  -0.98239,   1.0));
403
404    }
405   
406    if (printSizeOfTest)
407    {
408        std::cout<<"**** sizeof() tests  ******"<<std::endl;
409       
410        sizeOfTest();
411
412        std::cout<<std::endl;
413    }
414
415
416    if (performanceTest)
417    {
418        std::cout<<"**** performance tests  ******"<<std::endl;
419       
420        runPerformanceTests();
421    }
422
423
424    if (printQualifiedTest)
425    {
426         std::cout<<"*****   Qualified Tests  ******"<<std::endl;
427
428         osgUtx::QualifiedTestPrinter printer;
429         osgUtx::TestGraph::instance().root()->accept( printer );   
430         std::cout<<std::endl;
431    }
432
433    std::cout<<"******   Running tests   ******"<<std::endl;
434
435    // Global Data or Context
436    osgUtx::TestContext ctx;
437    osgUtx::TestRunner runner( ctx );
438    runner.specify("root");
439
440    osgUtx::TestGraph::instance().root()->accept( runner );
441
442    return 0;
443}
Note: See TracBrowser for help on using the browser.