root/branches/Carsten_PtrWork2/Tools/osgBench/Test.cpp

Revision 446, 17.4 kB (checked in by dirk, 2 years ago)

Added RenderAction? RednerTraversal? comparison.
Added Window access

Line 
1 /*---------------------------------------------------------------------------*\
2  *                                OpenSG                                     *
3  *                                                                           *
4  *                                                                           *
5  *             Copyright (C) 2000,2001 by the OpenSG Forum                   *
6  *                                                                           *
7  *                            www.opensg.org                                 *
8  *                                                                           *
9  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
10  *                                                                           *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13  *                                License                                    *
14  *                                                                           *
15  * This library is free software; you can redistribute it and/or modify it   *
16  * under the terms of the GNU Library General Public License as published    *
17  * by the Free Software Foundation, version 2.                               *
18  *                                                                           *
19  * This library is distributed in the hope that it will be useful, but       *
20  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
22  * Library General Public License for more details.                          *
23  *                                                                           *
24  * You should have received a copy of the GNU Library General Public         *
25  * License along with this library; if not, write to the Free Software       *
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
27  *                                                                           *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30  *                                Changes                                    *
31  *                                                                           *
32  *                                                                           *
33  *                                                                           *
34  *                                                                           *
35  *                                                                           *
36  *                                                                           *
37 \*---------------------------------------------------------------------------*/
38
39 //---------------------------------------------------------------------------
40 //  Includes
41 //---------------------------------------------------------------------------
42
43 #include <OpenSG/OSGGLUT.h>
44 #include <OpenSG/OSGMatrixUtility.h>
45 #include <OpenSG/OSGGeoIgnorePumpGroup.h>
46
47 #include "Test.h"
48
49 Test::Test(void) :
50     _win(NULL), _scene(OSG::NullFC), _near(0), _far(0),
51     _froms(), _oris(), _fovs(),
52     _minTime(-1), _nFrames(0), _headlight(true),
53     _statsLevel(0), _time(0), _nRenderedFrames(0), _stats(),
54     _verbose(false), _useRenderTraversal(false)
55 {
56 }
57
58 Test::~Test()
59 {
60 }
61
62 // Set up scene characteristics
63
64 void Test::setScene(NodeBase &scene)
65 {
66     _scene = scene.getNode();
67 }
68
69 void Test::setScene(OSG::NodePtr scene)
70 {
71     _scene = scene;
72 }
73
74 void Test::setWindow(TestWindow &win)
75 {
76     _win = &win;
77 }
78
79 void Test::setHeadlight(bool on)
80 {
81     _headlight = on;
82 }
83      
84 void Test::setNearFar(OSG::Real32 n, OSG::Real32 f)
85 {
86     _near = n;
87     _far = f;
88 }
89
90 // Setup Test Frames
91
92 // clear all the data
93 void Test::clear(void)
94 {
95     _froms.clear();
96     _oris.clear();
97     _fovs.clear();
98 }
99
100 // MinTime takes precedence, the path is repeated fully until the time is
101 // reached
102
103 void Test::setNFrames(OSG::UInt32 nframes)
104 {
105     _nFrames = nframes;
106 }
107    
108 void Test::setMinTime(OSG::Real32 minTime)
109 {
110     _minTime = minTime;
111 }
112
113 void Test::addFromAtUp(OSG::Pnt3f from, OSG::Pnt3f at, OSG::Vec3f up)
114 {
115     OSG::Matrix m;
116    
117     OSG::MatrixLookAt(m, from, at, up);
118                            
119     _froms.push_back(from);
120     _oris.push_back(OSG::Quaternion(m));
121 }
122
123 void Test::addFromAtUp(OSG::Real32 fromx, OSG::Real32 fromy, OSG::Real32 fromz,
124                        OSG::Real32 atx,   OSG::Real32 aty,   OSG::Real32 atz,
125                        OSG::Real32 upx,   OSG::Real32 upy,   OSG::Real32 upz)
126 {
127     addFromAtUp(OSG::Pnt3f(fromx, fromy, fromz),
128                 OSG::Pnt3f(atx, aty, atz),
129                 OSG::Vec3f(upx, upy, upz));
130 }
131
132 // Define Path from VRML-Style Positon/Quaternion Strings
133 void Test::addFromOri(OSG::Char8 *from, OSG::Char8 *ori)
134 {
135     OSG::Char8 *f = from, *o = ori;
136     OSG::UInt32 frames = 0;
137    
138     while(f && *f && o && *o)
139     {
140         OSG::Pnt3f v;
141         OSG::Quaternion q;
142        
143         const OSG::Char8 *grmbl=f;
144 #if defined(OSG_VERSION) && OSG_VERSION >= 020000
145         if (!OSG::FieldTraits<OSG::Pnt3f>::getFromCString(v, grmbl))
146 #elif defined(OSG_VERSION) && OSG_VERSION >= 010300
147         if (!OSG::FieldDataTraits<OSG::Pnt3f>::getFromString(v, grmbl))
148 #else
149         if (OSG::FieldDataTraits<OSG::Pnt3f>::getFromString(v, grmbl))
150 #endif
151         {
152             FWARNING(("Test::addFromOri: error reading from: '%s'!\n",
153                         f));
154             return;
155         }
156        
157         grmbl=o;
158 #if defined(OSG_VERSION) && OSG_VERSION >= 020000
159         if (!OSG::FieldTraits<OSG::Quaternion>::getFromCString(q, grmbl))
160 #elif defined(OSG_VERSION) && OSG_VERSION >= 010300
161         if (!OSG::FieldDataTraits<OSG::Quaternion>::getFromString(q, grmbl))
162 #else
163         if (OSG::FieldDataTraits<OSG::Quaternion>::getFromString(q, grmbl))
164 #endif
165         {
166             FWARNING(("Test::addFromOri: error reading ori: '%s'!\n",
167                         o));
168             return;
169         }
170        
171         _froms.push_back(v);
172         _oris.push_back(q);             
173        
174         f = strchr(f, ',');
175         if(f)
176             ++f;
177        
178         o = strchr(o, ',');
179         if(o)
180             ++o;
181     }
182 }
183
184 // Make a rotational path around the whole model
185 void Test::makeOrbit(OSG::Real32 upx, OSG::Real32 upy, OSG::Real32 upz)
186 {
187     if(_scene == OSG::NullFC)
188     {
189         FWARNING(("Test::makeOrbit: need scene!\n"));
190         return;
191     }
192    
193     OSG::commitChanges();
194     _scene->updateVolume();
195    
196     OSG::DynamicVolume volume;
197     _scene->getWorldVolume(volume);
198    
199     OSG::Pnt3f center;
200     volume.getCenter(center);
201    
202     OSG::Real32 dia = (volume.getMax() - volume.getMin()).length();
203    
204     OSG::Vec3f up(upx,upy,upz);
205     OSG::Vec3f dir, right;
206    
207     up.normalize();
208    
209     dir = up.cross(OSG::Vec3f(1,0,0));
210     if(dir.squareLength() < OSG::Eps)
211     {
212         dir = up.cross(OSG::Vec3f(0,1,0));
213        
214         if(dir.squareLength() < OSG::Eps)
215         {
216             dir = up.cross(OSG::Vec3f(0,0,1));
217             if(dir.squareLength() < OSG::Eps)
218             {
219                 up.setValues(0,1,0);
220                 dir.setValues(0,0,1);
221             }
222         }
223     }
224    
225     dir.normalize();
226     right = dir.cross(up);
227     up = right.cross(dir);
228    
229     dir *= dia;
230     right *= dia;
231    
232     _froms.clear();
233     _oris.clear();
234    
235     // Add a few sensible camera locations
236     // Using 4 gives bad results, a few more are necessary
237     
238     const OSG::Real32 nPoints = 100.f;
239    
240     for(int i = 0; i <= nPoints; ++i)
241     {
242         OSG::Real32 c = OSG::osgcos( M_PI * 2.f / nPoints * i);
243         OSG::Real32 s = OSG::osgsin( M_PI * 2.f / nPoints * i);
244        
245         addFromAtUp(center + dir * c + right * s, center, up);       
246     }
247 }
248
249 // Make a pirouette inside the model
250 void Test::makePirouette(OSG::Real32 upx,   OSG::Real32 upy,   OSG::Real32 upz)
251 {
252     if(_scene == OSG::NullFC)
253     {
254         FWARNING(("Test::makePirouette: need scene!\n"));
255         return;
256     }
257    
258     _scene->updateVolume();
259    
260     OSG::DynamicVolume volume;
261     _scene->getWorldVolume(volume);
262    
263     OSG::Pnt3f center;
264     volume.getCenter(center);
265    
266     OSG::Real32 dia = (volume.getMax() - volume.getMin()).length() * .5;
267    
268     OSG::Vec3f up(upx,upy,upz);
269     OSG::Vec3f dir, right;
270    
271     up.normalize();
272    
273     dir = up.cross(OSG::Vec3f(1,0,0));
274     if(dir.squareLength() < OSG::Eps)
275     {
276         dir = up.cross(OSG::Vec3f(0,1,0));
277        
278         if(dir.squareLength() < OSG::Eps)
279         {
280             dir = up.cross(OSG::Vec3f(0,0,1));
281             if(dir.squareLength() < OSG::Eps)
282             {
283                 up.setValues(0,1,0);
284                 dir.setValues(0,0,1);
285             }
286         }
287     }
288    
289     dir.normalize();
290     right = dir.cross(up);
291     up = right.cross(dir);
292    
293     dir *= dia;
294     right *= dia;
295    
296     _froms.clear();
297     _oris.clear();
298      
299     addFromAtUp(center, center + dir * OSG::Sqrt2                     , up);
300     addFromAtUp(center, center + dir              + right             , up);
301    
302     addFromAtUp(center, center                    + right * OSG::Sqrt2, up);
303     addFromAtUp(center, center - dir              + right             , up);
304    
305     addFromAtUp(center, center - dir * OSG::Sqrt2                     , up);
306     addFromAtUp(center, center - dir              - right             , up);
307    
308     addFromAtUp(center, center                    - right * OSG::Sqrt2, up);
309     addFromAtUp(center, center + dir              - right             , up);
310    
311     addFromAtUp(center, center + dir * OSG::Sqrt2                     , up);
312    
313 }
314
315 // add a FOV to animate
316 void Test::addFov(OSG::Real32 fov)
317 {
318     _fovs.push_back(fov);
319 }
320
321 // Run Test
322 void Test::setStatistics(OSG::UInt16 level)
323 {
324     _statsLevel = level;
325 }
326
327 OSG::UInt16 Test::getStatistics(void)
328 {
329     return _statsLevel;
330 }
331
332 void Test::setVerbose(bool verbose)
333 {
334     _verbose = verbose;
335 }
336
337 void Test::useRenderTraversal(bool val)
338 {
339     _useRenderTraversal = val;
340 }
341
342 void Test::setIgnoreGeometry(bool ignore)
343 {
344     static bool isIgnored = false;
345     static OSG::GeoPumpGroup* igp = new OSG::GeoIgnorePumpGroup;
346    
347     std::vector<OSG::GeoPumpGroup*> &p = OSG::GeoPumpGroup::getActiveGroups();
348    
349     if(ignore && !isIgnored)
350     {
351         p.insert(p.begin(), igp);
352         isIgnored = true;
353     }
354     else if(!ignore && isIgnored)
355     {
356         p.erase(p.begin());
357         isIgnored = false;
358     }
359 }
360
361 // little helper function that runs the test loop. The main reason for this
362 // function is being able to profile it, without the initialisation.
363
364 void Test::runLoop( std::vector<OSG::Matrix> &views,
365                     std::vector<OSG::Real32> &fovs)
366 {
367     OSG::Time start, stop;
368     OSG::SimpleSceneManager *ssm = _win->getSSM();
369
370     start = OSG::getSystemTime();
371    
372     do
373     {       
374         if(_statsLevel)
375         {
376             OSG::UInt32 ss = _stats.size();
377
378             _stats.resize(_stats.size() + views.size());
379
380             if(_statsLevel > 1)
381             {
382                 for(OSG::UInt32 i = ss; i < _stats.size(); ++i)
383                 {
384                     _stats[i].getElem(OSG::Geometry::statNTriangles);
385                 }
386             }
387         }
388        
389         for(OSG::UInt32 i = 0; i < views.size(); ++i, ++_nRenderedFrames)
390         {
391             if(_verbose)
392                 SWARNING << "Test::run: Frame " << i << " ("
393                          << _nRenderedFrames << ") fov "
394                          << fovs[i] << ", view" << std::endl << views[i]
395                          << std::endl;
396             _win->setCamera(views[i]);
397             _win->setFov(fovs[i]);
398            
399             if(_statsLevel)
400             {
401                 if(_useRenderTraversal)
402                     ssm->getRenderTraversalAction()->setStatistics(&_stats[_nRenderedFrames]);
403                 else
404                     ssm->getAction()->setStatistics(&_stats[_nRenderedFrames]);
405             }
406    
407             OSG::Thread::getCurrentChangeList()->commitChanges();
408            
409             _win->redraw();
410         }
411     }
412     while(_minTime > 0 && OSG::getSystemTime() - start < _minTime);
413    
414     _win->finish();
415    
416     stop = OSG::getSystemTime();
417
418     _time = stop - start; 
419
420     if(_statsLevel)
421     {
422         if(_useRenderTraversal)
423             ssm->getRenderTraversalAction()->setStatistics(NULL);
424         else
425             ssm->getAction()->setStatistics(NULL);
426     }
427 }
428
429 void Test::run(void)
430 {
431     if(!_win || !_win->isOpen())
432     {
433         FWARNING(("Test::run: window not ready!\n"));
434         return;
435     }
436     if(!_scene)
437     {
438         FWARNING(("Test::run: no scene!\n"));
439         return;
440     }
441     if(_froms.empty())
442     {
443         FWARNING(("Test::run: no views!\n"));
444         return;
445     }
446     if(_oris.empty())
447     {
448         FWARNING(("Test::run: no views!\n"));
449         return;
450     }
451     if(_froms.size() != _oris.size())
452     {
453         FWARNING(("Test::run: _froms.size() != _oris.size()!\n"));
454         return;       
455     }
456    
457     if(_fovs.empty())
458     {
459         FWARNING(("Test::run: no fovs!\n"));
460         return;
461     }
462    
463     std::vector<OSG::Matrix> views;
464     std::vector<OSG::Real32> fovs;
465    
466     expandData(views, fovs);
467    
468     OSG::Time start, stop;
469     OSG::SimpleSceneManager *ssm = _win->getSSM();
470    
471     _win->setScene(_scene);
472     ssm->setHeadlight(_headlight);
473     ssm->setUseTraversalAction(_useRenderTraversal);
474    
475     _stats.clear();
476  
477     OSG::Thread::getCurrentChangeList()->commitChanges();
478     _win->showAll();
479     _win->redraw();
480    
481     if(_near > 0 && _far > 0)
482     {
483         _win->setNearFar(_near, _far);
484         if(_verbose)
485             FWARNING(("Test::run: near=%f, far=%f\n", _near, _far));
486     }
487      
488     _nRenderedFrames = 0;
489    
490     _win->finish();
491
492     runLoop(views, fovs);
493 }
494
495
496 Image Test::snapshot(OSG::UInt32 frame)
497 {
498     if(!_win || !_win->isOpen())
499     {
500         FWARNING(("Test::snapshot: window not ready!\n"));
501         return Image();
502     }
503     if(!_scene)
504     {
505         FWARNING(("Test::snapshot: no scene!\n"));
506         return Image();
507     }
508     if(_froms.empty())
509     {
510         FWARNING(("Test::snapshot: no views!\n"));
511         return Image();
512     }
513     if(_oris.empty())
514     {
515         FWARNING(("Test::snapshot: no views!\n"));
516         return Image();
517     }
518     if(_froms.size() != _oris.size())
519     {
520         FWARNING(("Test::snapshot: _froms.size() != _oris.size()!\n"));
521         return Image();       
522     }
523    
524     if(_fovs.empty())
525     {
526         FWARNING(("Test::snapshot: no fovs!\n"));
527         return Image();
528     }
529    
530     std::vector<OSG::Matrix> views;
531     std::vector<OSG::Real32> fovs;
532    
533     expandData(views, fovs);
534    
535     if(frame >= views.size())
536     {
537         FWARNING(("Test::snapshot: frame >= views.size()!\n"));
538         return Image();           
539     }
540    
541     OSG::SimpleSceneManager *ssm = _win->getSSM();
542    
543     _win->setScene(_scene);
544     ssm->setHeadlight(_headlight);
545
546     _win->setCamera(views[frame]);
547     _win->setFov(fovs[frame]);
548    
549     if(_useRenderTraversal)
550         ssm->getRenderTraversalAction()->setStatistics(NULL);
551     else
552         ssm->getAction()->setStatistics(NULL);
553    
554     OSG::ImagePtr img;
555    
556     img = _win->snapshot();
557    
558     return Image(img);
559 }
560
561 // Get Results
562
563 OSG::Real32 Test::getFPS(void)
564 {
565     return _nRenderedFrames / _time;
566 }
567
568 OSG::Real32 Test::getTime(void)
569 {
570     return _time;
571 }
572
573 OSG::UInt32 Test::getNRenderedFrames(void)
574 {
575     return _nRenderedFrames;
576 }
577
578 OSG::Real64 Test::getStatValue(OSG::Char8 *name, OSG::UInt32 frame)
579 {
580     if(_stats.size() <= frame)
581     {
582         FWARNING(("Test::getStatValue: no statistics for frame %d!\n", frame));
583         return -1;
584     }
585    
586     OSG::Real64 val;
587     std::string n(name);
588    
589 #if defined(OSG_VERSION) && OSG_VERSION >= 13
590     if(!_stats[frame].getValue(n, val))
591     {
592         FWARNING(("Test::getStatValue: no statistics value '%s'!\n", name));
593         return -1;
594     }
595 #else
596     OSG::StatElemDescBase *desc = OSG::StatElemDescBase::findDescByName(name);
597     if(!desc)
598     {
599         FWARNING(("Test::getStatValue: name not known '%s'!\n", name));
600         return -1;
601     }
602     OSG::StatElem *el = _stats[frame].getElem(*desc, false);
603     if(!el)
604     {
605         FWARNING(("Test::getStatValue: no statistics value '%s'!\n", name));
606         return -1;
607     }
608     val = el->getValue();
609 #endif
610    
611     return val;   
612 }
613
614
615 // expand the animation data to have nFrames elements
616
617 void Test::expandData(std::vector<OSG::Matrix>& views, std::vector<OSG::Real32> &fovs)
618 {
619     views.resize(_nFrames);
620     fovs.resize(_nFrames);
621    
622     // interpolate the values to get _nFrames values
623     
624     OSG::Real32 vscale = (_froms.size() - 1) / (_nFrames - 1.f);
625     OSG::Real32 fscale = (_fovs.size() - 1) / (_nFrames - 1.f);
626    
627     for(OSG::UInt32 i = 0; i < _nFrames; ++i)
628     {
629         OSG::UInt32 vi = static_cast<OSG::UInt32>(OSG::osgfloor(i * vscale));
630         OSG::Real32 v = i * vscale - vi;
631        
632         if(v < OSG::Eps)
633         {
634             views[i].setTransform(_froms[vi].subZero(), _oris[vi]);
635         }
636         else
637         {
638             OSG::Quaternion q;           
639             q.slerpThis(_oris[vi], _oris[vi+1], v);
640
641             OSG::Pnt3f p = _froms[vi] + v * (_froms[vi+1] - _froms[vi]);
642
643             views[i].setTransform(p.subZero(), q);
644         }
645  
646         OSG::UInt32 fi = static_cast<OSG::UInt32>(OSG::osgfloor(i * fscale));
647         OSG::Real32 f = i * fscale - fi;
648        
649         if(f < OSG::Eps)
650         {
651             fovs[i] = _fovs[fi];
652         }
653         else
654         {
655             fovs[i] = _fovs[fi] * (1.f  - f) + _fovs[fi + 1] * f;;
656         }
657     }   
658 }
Note: See TracBrowser for help on using the browser.