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

Revision 6627, 14.6 kB (checked in by robert, 8 years ago)

Added signOrZero template method, and to Matrix_implementation.cpp usage of this
method in the get(Quat&) code.

  • 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
319    osg::Matrix matrix(0.5, 0.0, 0.0, 0.0,
320                       0.0, 0.5, 0.0, 0.0,
321                       0.0, 0.0, 0.5, 0.0,
322                       1.0, 1.0, 1.0, 1.0);
323                       
324    osg::Quat quat;
325    matrix.get(quat);
326   
327    osg::notify(osg::NOTICE)<<"Matrix = "<<matrix<<" rotation="<<quat<<std::endl;
328
329}
330
331
332int main( int argc, char** argv )
333{
334    osg::ArgumentParser arguments(&argc,argv);
335
336    // set up the usage document, in case we need to print out how to use this program.
337    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which runs units tests.");
338    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
339    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
340    arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests.");
341    arguments.getApplicationUsage()->addCommandLineOption("sizeof","Display sizeof tests.");
342    arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");
343    arguments.getApplicationUsage()->addCommandLineOption("performance","Display qualified tests.");
344 
345
346    if (arguments.argc()<=1)
347    {
348        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
349        return 1;
350    }
351
352    bool printQualifiedTest = false;
353    while (arguments.read("qt")) printQualifiedTest = true;
354
355    bool printMatrixTest = false;
356    while (arguments.read("matrix")) printMatrixTest = true;
357
358    bool printSizeOfTest = false;
359    while (arguments.read("sizeof")) printSizeOfTest = true;
360
361    bool printQuatTest = false;
362    while (arguments.read("quat")) printQuatTest = true;
363
364    bool performanceTest = false;
365    while (arguments.read("p") || arguments.read("performance")) performanceTest = true;
366
367    // if user request help write it out to cout.
368    if (arguments.read("-h") || arguments.read("--help"))
369    {
370        std::cout<<arguments.getApplicationUsage()->getCommandLineUsage()<<std::endl;
371        arguments.getApplicationUsage()->write(std::cout,arguments.getApplicationUsage()->getCommandLineOptions());
372        return 1;
373    }
374
375    // any option left unread are converted into errors to write out later.
376    arguments.reportRemainingOptionsAsUnrecognized();
377
378    // report any errors if they have occured when parsing the program aguments.
379    if (arguments.errors())
380    {
381        arguments.writeErrorMessages(std::cout);
382        return 1;
383    }
384   
385    if (printQuatTest)
386    {
387        testQuat();
388    }
389
390
391    if (printMatrixTest)
392    {
393        std::cout<<"******   Running matrix tests   ******"<<std::endl;
394
395        testFrustum(-1,1,-1,1,1,1000);
396        testFrustum(0,1,1,2,2.5,100000);
397
398        testOrtho(0,1,1,2,2.1,1000);
399        testOrtho(-1,10,1,20,2.5,100000);
400
401        testPerspective(20,1,1,1000);
402        testPerspective(90,2,1,1000);
403
404        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));
405        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));
406       
407        testMatrixInvert(osg::Matrix(0.999848,  -0.002700,  0.017242, -0.1715,
408                                     0,         0.987960,   0.154710,  0.207295,
409                                     -0.017452, -0.154687,  0.987809, -0.98239,
410                                     0,         0,          0,         1));
411
412        testMatrixInvert(osg::Matrix(0.999848,  -0.002700,  0.017242,   0.0,
413                                     0.0,        0.987960,   0.154710,   0.0,
414                                     -0.017452, -0.154687,  0.987809,   0.0,
415                                     -0.1715,    0.207295,  -0.98239,   1.0));
416
417    }
418   
419    if (printSizeOfTest)
420    {
421        std::cout<<"**** sizeof() tests  ******"<<std::endl;
422       
423        sizeOfTest();
424
425        std::cout<<std::endl;
426    }
427
428
429    if (performanceTest)
430    {
431        std::cout<<"**** performance tests  ******"<<std::endl;
432       
433        runPerformanceTests();
434    }
435
436
437    if (printQualifiedTest)
438    {
439         std::cout<<"*****   Qualified Tests  ******"<<std::endl;
440
441         osgUtx::QualifiedTestPrinter printer;
442         osgUtx::TestGraph::instance().root()->accept( printer );   
443         std::cout<<std::endl;
444    }
445
446    std::cout<<"******   Running tests   ******"<<std::endl;
447
448    // Global Data or Context
449    osgUtx::TestContext ctx;
450    osgUtx::TestRunner runner( ctx );
451    runner.specify("root");
452
453    osgUtx::TestGraph::instance().root()->accept( runner );
454
455    return 0;
456}
Note: See TracBrowser for help on using the browser.