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

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

Added Matrix*::getRotate()/setRotate(Quat), deprecating Matrix*::get(Quat&), Matrix*::set(Quat&)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/UnitTestFramework>
2#include <osg/ArgumentParser>
3#include <osg/ApplicationUsage>
4
5#include <osg/Vec3>
6#include <osg/Matrix>
7#include <osg/io_utils>
8
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(int)=="<<sizeof(int)<<std::endl;
125  std::cout<<"sizeof(long)=="<<sizeof(long)<<std::endl;
126  std::cout<<"sizeof(long int)=="<<sizeof(long int)<<std::endl;
127
128#if defined(_MSC_VER)
129  // long long isn't supported on VS6.0...
130  std::cout<<"sizeof(__int64)=="<<sizeof(__int64)<<std::endl;
131#else
132  std::cout<<"sizeof(long long)=="<<sizeof(long long)<<std::endl;
133#endif
134  std::cout<<"sizeof(float)=="<<sizeof(float)<<std::endl;
135  std::cout<<"sizeof(double)=="<<sizeof(double)<<std::endl;
136
137  std::cout<<"sizeof(std::istream::pos_type)=="<<sizeof(std::istream::pos_type)<<std::endl;
138  std::cout<<"sizeof(std::istream::off_type)=="<<sizeof(std::istream::off_type)<<std::endl;
139  std::cout<<"sizeof(OpenThreads::Mutex)=="<<sizeof(OpenThreads::Mutex)<<std::endl;
140
141  std::cout<<"sizeof(std::string)=="<<sizeof(std::string)<<std::endl;
142
143}
144
145/// Exercises the Matrix.get(Quat&) function, printout is generated on problems only
146void testGetQuatFromMatrix() {
147    // acceptable error range
148    double eps=1e-3;
149
150#if 1
151    // wide range
152    double rol1start = 0.0;
153    double rol1stop = 360.0;
154    double rol1step = 30.0;
155
156    double pit1start = 0.0;
157    double pit1stop = 90.0;
158    double pit1step = 30.0;
159
160    double yaw1start = 0.0;
161    double yaw1stop = 360.0;
162    double yaw1step = 30.0;
163
164    double rol2start = 0.0;
165    double rol2stop = 360.0;
166    double rol2step = 30.0;
167
168    double pit2start = 0.0;
169    double pit2stop = 90.0;
170    double pit2step = 30.0;
171
172    double yaw2start = 0.0;
173    double yaw2stop = 360.0;
174    double yaw2step = 30.0;
175#else
176    // focussed range
177    double rol1start = 0.0;
178    double rol1stop = 0.0;
179    double rol1step = 0.1;
180
181    double pit1start = 0.0;
182    double pit1stop = 5.0;
183    double pit1step = 5.0;
184
185    double yaw1start = 89.0;
186    double yaw1stop = 91.0;
187    double yaw1step = 0.1;
188
189    double rol2start = 0.0;
190    double rol2stop = 0.0;
191    double rol2step = 0.1;
192
193    double pit2start = 0.0;
194    double pit2stop = 0.0;
195    double pit2step = 0.1;
196
197    double yaw2start = 89.0;
198    double yaw2stop = 91.0;
199    double yaw2step = 0.1;
200#endif
201   
202    for (double rol1 = rol1start; rol1 <= rol1stop; rol1 += rol1step) {
203        for (double pit1 = pit1start; pit1 <= pit1stop; pit1 += pit1step) {
204            for (double yaw1 = yaw1start; yaw1 <= yaw1stop; yaw1 += yaw1step) {
205                for (double rol2 = rol2start; rol2 <= rol2stop; rol2 += rol2step) {
206                    for (double pit2 = pit2start; pit2 <= pit2stop; pit2 += pit2step) {
207                        for (double yaw2 = yaw2start; yaw2 <= yaw2stop; yaw2 += yaw2step) {
208                            // create two quats based on the roll, pitch and yaw values
209                            osg::Quat rot_quat1 =
210                                osg::Quat(osg::DegreesToRadians(rol1),osg::Vec3d(1,0,0),
211                                          osg::DegreesToRadians(pit1),osg::Vec3d(0,1,0),
212                                          osg::DegreesToRadians(yaw1),osg::Vec3d(0,0,1));
213                           
214                            osg::Quat rot_quat2 =
215                                osg::Quat(osg::DegreesToRadians(rol2),osg::Vec3d(1,0,0),
216                                          osg::DegreesToRadians(pit2),osg::Vec3d(0,1,0),
217                                          osg::DegreesToRadians(yaw2),osg::Vec3d(0,0,1));
218                           
219                            // create an output quat using quaternion math
220                            osg::Quat out_quat1;
221                            out_quat1 = rot_quat2 * rot_quat1;
222                           
223                            // create two matrices based on the input quats
224                            osg::Matrixd mat1,mat2;
225                            mat1.makeRotate(rot_quat1);
226                            mat2.makeRotate(rot_quat2);
227                           
228                            // create an output quat by matrix multiplication and get
229                            osg::Matrixd out_mat;
230                            out_mat = mat2 * mat1;
231                            osg::Quat out_quat2;
232                            out_quat2 = out_mat.getRotate();
233                           
234                            // if the output quat length is not one
235                            // or if the component magnitudes do not match,
236                            // something is amiss
237                            if (fabs(1.0-out_quat2.length()) > eps ||
238                                (fabs(out_quat1.x())-fabs(out_quat2.x())) > eps ||
239                                (fabs(out_quat1.y())-fabs(out_quat2.y())) > eps ||
240                                (fabs(out_quat1.z())-fabs(out_quat2.z())) > eps ||
241                                (fabs(out_quat1.w())-fabs(out_quat2.w())) > eps) {
242                                std::cout << "problem at: r1=" << rol1
243                                          << " p1=" << pit1
244                                          << " y1=" << yaw1
245                                          << " r2=" << rol2
246                                          << " p2=" << pit2
247                                          << " y2=" << yaw2 << "\n";
248                                std::cout << "quats:        " << out_quat1 << " length: " << out_quat1.length() << "\n";
249                                std::cout << "mats and get: " << out_quat2 << " length: " << out_quat2.length() << "\n\n";
250                            }
251                        }
252                    }
253                }
254            }
255        }
256    }
257}
258
259void testQuatRotate(const osg::Vec3d& from, const osg::Vec3d& to)
260{
261    osg::Quat q_nicolas;
262    q_nicolas.makeRotate(from,to);
263   
264    osg::Quat q_original;
265    q_original.makeRotate_original(from,to);
266   
267    std::cout<<"osg::Quat::makeRotate("<<from<<", "<<to<<")"<<std::endl;
268    std::cout<<"  q_nicolas = "<<q_nicolas<<std::endl;
269    std::cout<<"  q_original = "<<q_original<<std::endl;
270    std::cout<<"  from * M4x4(q_nicolas) = "<<from * osg::Matrixd::rotate(q_nicolas)<<std::endl;
271    std::cout<<"  from * M4x4(q_original) = "<<from * osg::Matrixd::rotate(q_original)<<std::endl;
272}
273
274void testQuat()
275{
276    osg::Quat q1;
277    q1.makeRotate(osg::DegreesToRadians(30.0),0.0f,0.0f,1.0f);
278
279    osg::Quat q2;
280    q2.makeRotate(osg::DegreesToRadians(133.0),0.0f,1.0f,1.0f);
281
282    osg::Quat q1_2 = q1*q2;
283    osg::Quat q2_1 = q2*q1;
284
285    osg::Matrix m1 = osg::Matrix::rotate(q1);
286    osg::Matrix m2 = osg::Matrix::rotate(q2);
287   
288    osg::Matrix m1_2 = m1*m2;
289    osg::Matrix m2_1 = m2*m1;
290   
291    osg::Quat qm1_2;
292    qm1_2.set(m1_2);
293   
294    osg::Quat qm2_1;
295    qm2_1.set(m2_1);
296   
297    std::cout<<"q1*q2 = "<<q1_2<<std::endl;
298    std::cout<<"q2*q1 = "<<q2_1<<std::endl;
299    std::cout<<"m1*m2 = "<<qm1_2<<std::endl;
300    std::cout<<"m2*m1 = "<<qm2_1<<std::endl;
301
302
303    testQuatRotate(osg::Vec3d(1.0,0.0,0.0),osg::Vec3d(0.0,1.0,0.0));
304    testQuatRotate(osg::Vec3d(0.0,1.0,0.0),osg::Vec3d(1.0,0.0,0.0));
305    testQuatRotate(osg::Vec3d(0.0,0.0,1.0),osg::Vec3d(0.0,1.0,0.0));
306    testQuatRotate(osg::Vec3d(1.0,1.0,1.0),osg::Vec3d(1.0,0.0,0.0));
307    testQuatRotate(osg::Vec3d(1.0,0.0,0.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(0.0,1.0,0.0),osg::Vec3d(0.0,-1.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,0.0,1.0),osg::Vec3d(0.0,0.0,-1.0));
313    testQuatRotate(osg::Vec3d(0.0,0.0,-1.0),osg::Vec3d(0.0,0.0,1.0));
314
315    testGetQuatFromMatrix();
316}
317
318int main( int argc, char** argv )
319{
320    osg::ArgumentParser arguments(&argc,argv);
321
322    // set up the usage document, in case we need to print out how to use this program.
323    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which runs units tests.");
324    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
325    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
326    arguments.getApplicationUsage()->addCommandLineOption("qt","Display qualified tests.");
327    arguments.getApplicationUsage()->addCommandLineOption("sizeof","Display sizeof tests.");
328    arguments.getApplicationUsage()->addCommandLineOption("matrix","Display qualified tests.");
329    arguments.getApplicationUsage()->addCommandLineOption("performance","Display qualified tests.");
330 
331
332    if (arguments.argc()<=1)
333    {
334        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
335        return 1;
336    }
337
338    bool printQualifiedTest = false;
339    while (arguments.read("qt")) printQualifiedTest = true;
340
341    bool printMatrixTest = false;
342    while (arguments.read("matrix")) printMatrixTest = true;
343
344    bool printSizeOfTest = false;
345    while (arguments.read("sizeof")) printSizeOfTest = true;
346
347    bool printQuatTest = false;
348    while (arguments.read("quat")) printQuatTest = true;
349
350    bool performanceTest = false;
351    while (arguments.read("p") || arguments.read("performance")) performanceTest = true;
352
353    // if user request help write it out to cout.
354    if (arguments.read("-h") || arguments.read("--help"))
355    {
356        std::cout<<arguments.getApplicationUsage()->getCommandLineUsage()<<std::endl;
357        arguments.getApplicationUsage()->write(std::cout,arguments.getApplicationUsage()->getCommandLineOptions());
358        return 1;
359    }
360
361    // any option left unread are converted into errors to write out later.
362    arguments.reportRemainingOptionsAsUnrecognized();
363
364    // report any errors if they have occured when parsing the program aguments.
365    if (arguments.errors())
366    {
367        arguments.writeErrorMessages(std::cout);
368        return 1;
369    }
370   
371    if (printQuatTest)
372    {
373        testQuat();
374    }
375
376
377    if (printMatrixTest)
378    {
379        std::cout<<"******   Running matrix tests   ******"<<std::endl;
380
381        testFrustum(-1,1,-1,1,1,1000);
382        testFrustum(0,1,1,2,2.5,100000);
383
384        testOrtho(0,1,1,2,2.1,1000);
385        testOrtho(-1,10,1,20,2.5,100000);
386
387        testPerspective(20,1,1,1000);
388        testPerspective(90,2,1,1000);
389
390        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));
391        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));
392       
393        testMatrixInvert(osg::Matrix(0.999848,  -0.002700,  0.017242, -0.1715,
394                                     0,         0.987960,   0.154710,  0.207295,
395                                     -0.017452, -0.154687,  0.987809, -0.98239,
396                                     0,         0,          0,         1));
397
398        testMatrixInvert(osg::Matrix(0.999848,  -0.002700,  0.017242,   0.0,
399                                     0.0,        0.987960,   0.154710,   0.0,
400                                     -0.017452, -0.154687,  0.987809,   0.0,
401                                     -0.1715,    0.207295,  -0.98239,   1.0));
402
403    }
404   
405    if (printSizeOfTest)
406    {
407        std::cout<<"**** sizeof() tests  ******"<<std::endl;
408       
409        sizeOfTest();
410
411        std::cout<<std::endl;
412    }
413
414
415    if (performanceTest)
416    {
417        std::cout<<"**** performance tests  ******"<<std::endl;
418       
419        runPerformanceTests();
420    }
421
422
423    if (printQualifiedTest)
424    {
425         std::cout<<"*****   Qualified Tests  ******"<<std::endl;
426
427         osgUtx::QualifiedTestPrinter printer;
428         osgUtx::TestGraph::instance().root()->accept( printer );   
429         std::cout<<std::endl;
430    }
431
432    std::cout<<"******   Running tests   ******"<<std::endl;
433
434    // Global Data or Context
435    osgUtx::TestContext ctx;
436    osgUtx::TestRunner runner( ctx );
437    runner.specify("root");
438
439    osgUtx::TestGraph::instance().root()->accept( runner );
440
441    return 0;
442}
Note: See TracBrowser for help on using the browser.