1 #include <osgDB/ReadFile>
2 #include <osgDB/FileUtils>
3 #include <osgDB/FileNameUtils>
4 #include <osgDB/WriteFile>
5 #include <osgViewer/Viewer>
6 #include <osg/AnimationPath>
7 
8 #include "UpdateProperty.h"
9 #include "CameraProperty.h"
10 #include "CameraPathProperty.h"
11 #include "EventProperty.h"
12 
13 #include "CaptureSettings.h"
14 
15 #include <osgGA/StateSetManipulator>
16 
17 
18 struct ScreenShot : public osg::Camera::DrawCallback
19 {
ScreenShotScreenShot20     ScreenShot(GLenum pixelFormat, bool flip):
21         _pixelFormat(pixelFormat),
22         _flip(flip) {}
23 
operator ()ScreenShot24     virtual void operator () (osg::RenderInfo& renderInfo) const
25     {
26         if (!_frameCapture)
27         {
28             OSG_NOTICE<<"No FrameCamera assigned"<<std::endl;
29             return;
30         }
31 
32         unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber();
33 
34         CameraNumMap::const_iterator itr = _cameraNumMap.find(renderInfo.getCurrentCamera());
35         std::string outputFileName = (itr!=_cameraNumMap.end()) ?
36                                      _frameCapture->getOutputFileName(itr->second, frameNumber) :
37                                      _frameCapture->getOutputFileName(frameNumber);
38 
39         OSG_NOTICE<<"outputFileName="<<outputFileName<<std::endl;
40 
41         osg::Camera* camera = renderInfo.getCurrentCamera();
42         osg::Viewport* viewport = camera ? camera->getViewport() : 0;
43         if (viewport)
44         {
45             OSG_NOTICE<<"Doing read of ="<<viewport->x()<<", "<<viewport->y()<<", "<<viewport->width()<<", "<<viewport->height()<<" with pixelFormat=0x"<<std::hex<<_pixelFormat<<std::dec<<std::endl;
46 
47             glReadBuffer(camera->getDrawBuffer());
48             osg::ref_ptr<osg::Image> image = new osg::Image;
49 
50             image->readPixels(viewport->x(),viewport->y(),viewport->width(),viewport->height(),
51                               _pixelFormat, GL_UNSIGNED_BYTE, 1);
52 
53             if (_flip) image->flipVertical();
54 
55             osgDB::writeImageFile(*image, outputFileName);
56         }
57 
58     }
59 
60     typedef std::map<const osg::Camera*, unsigned int> CameraNumMap;
61 
62     GLenum                                      _pixelFormat;
63     bool                                        _flip;
64     osg::ref_ptr<gsc::CaptureSettings>          _frameCapture;
65     CameraNumMap                                _cameraNumMap;
66 };
67 
main(int argc,char ** argv)68 int main( int argc, char **argv )
69 {
70     // use an ArgumentParser object to manage the program arguments.
71     osg::ArgumentParser arguments(&argc,argv);
72 
73     arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of 3D textures.");
74     arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options]");
75     arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
76     arguments.getApplicationUsage()->addCommandLineOption("-i <filename>","Input scene (or presentation) filename.");
77     arguments.getApplicationUsage()->addCommandLineOption("-o <filename>","Base output filename of the images, recommended to use something like Images/image.png");
78     arguments.getApplicationUsage()->addCommandLineOption("--cs <filename>","Load pre-generated configuration file for run.");
79     arguments.getApplicationUsage()->addCommandLineOption("--ouput-cs <filename>","Output configuration file with settings provided on commandline.");
80     arguments.getApplicationUsage()->addCommandLineOption("-p <filename>","Use specificied camera path file to control camera position.");
81     arguments.getApplicationUsage()->addCommandLineOption("--offscreen","Use an pbuffer to render the images offscreen.");
82     arguments.getApplicationUsage()->addCommandLineOption("--screen","Use an window to render the images.");
83     arguments.getApplicationUsage()->addCommandLineOption("--width <width>","Window/output image width.");
84     arguments.getApplicationUsage()->addCommandLineOption("--height <height>","Window/output image height.");
85     arguments.getApplicationUsage()->addCommandLineOption("--screen-distance <distance>","Set the distance of the viewer from the physical screen.");
86     arguments.getApplicationUsage()->addCommandLineOption("--screen-width <width>","Set the width of the physical screen.");
87     arguments.getApplicationUsage()->addCommandLineOption("--screen-height <height>","Set the height of the physical screen.");
88     arguments.getApplicationUsage()->addCommandLineOption("--ms <s>","Number of multi-samples to use when rendering, an enable a single sample buffer.");
89     arguments.getApplicationUsage()->addCommandLineOption("--samples <s>","Number of multi-samples to use when rendering.");
90     arguments.getApplicationUsage()->addCommandLineOption("--sampleBuffers <sb>","Number of sample buffers to use when rendering.");
91     arguments.getApplicationUsage()->addCommandLineOption("-f <fps>","Number of frames per second in simulation time.");
92     arguments.getApplicationUsage()->addCommandLineOption("-n <frames>","Number of frames to render/images to create.");
93     arguments.getApplicationUsage()->addCommandLineOption("-d <time>","Duration of rendering run (duration = frames/fps).");
94     arguments.getApplicationUsage()->addCommandLineOption("--center <x> <y> <z>","View center.");
95     arguments.getApplicationUsage()->addCommandLineOption("--eye <x> <y> <z>","Camera eye point.");
96     arguments.getApplicationUsage()->addCommandLineOption("--up <x> <y> <z>","Camera up vector.");
97     arguments.getApplicationUsage()->addCommandLineOption("--rotation-center <x> <y> <z>","Position to rotatate around.");
98     arguments.getApplicationUsage()->addCommandLineOption("--rotation-axis <x> <y> <z>","Axis to rotate around.");
99     arguments.getApplicationUsage()->addCommandLineOption("--rotation-speed <v>","Degrees per second.");
100     arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","OFF | HORIZONTAL_SPLIT | VERTICAL_SPLIT");
101 
102     unsigned int helpType = 0;
103     if ((helpType = arguments.readHelpType()))
104     {
105         arguments.getApplicationUsage()->write(std::cout, helpType);
106         return 1;
107     }
108 
109     osgViewer::Viewer viewer;
110 
111     typedef std::list< osg::ref_ptr<gsc::CaptureSettings> > CaptureSettingsList;
112     CaptureSettingsList frameCaptureList;
113 
114     osg::ref_ptr<gsc::CaptureSettings> fc = new gsc::CaptureSettings;
115 
116     double duration = 0.0;
117     double fps = 0.0f;
118     unsigned int nframes = 0;
119 
120     bool readCaptureSettings = false;
121     std::string filename;
122     if (arguments.read("--cs",filename))
123     {
124         osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(filename);
125         gsc::CaptureSettings* input_cs = dynamic_cast<gsc::CaptureSettings*>(object.get());
126         if (input_cs) { fc = input_cs; readCaptureSettings = true; }
127         else
128         {
129             OSG_NOTICE<<"Unable to read CaptureSettings from file: "<<filename<<std::endl;
130             if (object.valid()) OSG_NOTICE<<"Object read, "<<object.get()<<", className()="<<object->className()<<std::endl;
131             return 1;
132         }
133     }
134 
135     float screenWidth = fc->getScreenWidth()!=0.0 ? fc->getScreenWidth() : osg::DisplaySettings::instance()->getScreenWidth();
136     if (arguments.read("--screen-width",screenWidth)) {}
137 
138     float screenHeight = fc->getScreenHeight()!=0.0 ? fc->getScreenHeight() : osg::DisplaySettings::instance()->getScreenHeight();
139     if (arguments.read("--screen-height",screenHeight)) {}
140 
141     float screenDistance = fc->getScreenDistance()!=0.0 ? fc->getScreenDistance() : osg::DisplaySettings::instance()->getScreenDistance();
142     if (arguments.read("--screen-distance",screenDistance)) {}
143 
144     fc->setScreenWidth(screenWidth);
145     osg::DisplaySettings::instance()->setScreenWidth(screenWidth);
146 
147     fc->setScreenHeight(screenHeight);
148     osg::DisplaySettings::instance()->setScreenHeight(screenHeight);
149 
150     fc->setScreenDistance(screenDistance);
151     osg::DisplaySettings::instance()->setScreenDistance(screenDistance);
152 
153     bool useScreenSizeForProjectionMatrix = true;
154 
155     if (arguments.read("-i",filename)) fc->setInputFileName(filename);
156     if (arguments.read("-o",filename)) fc->setOutputFileName(filename);
157     if (arguments.read("-p",filename))
158     {
159         osg::ref_ptr<gsc::CameraPathProperty> cpp = new gsc::CameraPathProperty;
160         cpp->setAnimationPathFileName(filename);
161 
162         double startTime = 0, endTime = 1.0f;
163         if (cpp->getTimeRange(startTime, endTime))
164         {
165             OSG_NOTICE<<"Camera path time range "<<startTime<<", "<<endTime<<std::endl;
166             if (startTime!=0.0)
167             {
168                 cpp->resetTimeRange(0.0, endTime-startTime);
169                 if (cpp->getTimeRange(startTime, endTime))
170                 {
171                     OSG_NOTICE<<"   new time range "<<startTime<<", "<<endTime<<std::endl;
172                 }
173                 else
174                 {
175                     OSG_NOTICE<<"   failed to set new time range "<<startTime<<", "<<endTime<<std::endl;
176                 }
177             }
178             duration = endTime;
179         }
180         else
181         {
182             OSG_NOTICE<<"Camera path time range "<<startTime<<", "<<endTime<<std::endl;
183         }
184 
185         fc->addUpdateProperty(cpp.get());
186     }
187     else
188     {
189         osg::ref_ptr<gsc::CameraProperty> cp = fc->getPropertyOfType<gsc::CameraProperty>();
190 
191         bool newCameraProperty = false;
192         bool valueSet = false;
193 
194         if (!cp)
195         {
196             newCameraProperty = true;
197             cp = new gsc::CameraProperty;
198 
199             osg::ref_ptr<osg::Node> node;
200             if (!fc->getInputFileName().empty())
201             {
202                 osgDB::readRefNodeFile(fc->getInputFileName());
203             }
204             if (node.valid())
205             {
206                 cp->setToModel(node.get());
207                 valueSet = true;
208             }
209 
210         }
211 
212         osg::Vec3d vec;
213         while (arguments.read("--center",vec.x(), vec.y(), vec.z())) { cp->setCenter(vec); valueSet = true; }
214         while (arguments.read("--eye",vec.x(), vec.y(), vec.z())) { cp->setEyePoint(vec); valueSet = true; }
215         while (arguments.read("--up",vec.x(), vec.y(), vec.z())) { cp->setUpVector(vec); valueSet = true; }
216         while (arguments.read("--rotation-center",vec.x(), vec.y(), vec.z())) { cp->setRotationCenter(vec); valueSet = true; }
217         while (arguments.read("--rotation-axis",vec.x(), vec.y(), vec.z())) { cp->setRotationAxis(vec); valueSet = true; }
218 
219         double speed;
220         while (arguments.read("--rotation-speed",speed)) { cp->setRotationSpeed(speed); valueSet = true; }
221 
222         if (newCameraProperty && valueSet)
223         {
224             fc->addUpdateProperty(cp.get());
225         }
226     }
227 
228     std::string stereoMode;
229     if (arguments.read("--stereo", stereoMode))
230     {
231         if      (stereoMode=="HORIZONTAL_SPLIT") fc->setStereoMode(gsc::CaptureSettings::HORIZONTAL_SPLIT);
232         else if (stereoMode=="VERTICAL_SPLIT") fc->setStereoMode(gsc::CaptureSettings::VERTICAL_SPLIT);
233         else if (stereoMode=="OFF") fc->setStereoMode(gsc::CaptureSettings::OFF);
234     }
235 
236     if (arguments.read("--offscreen")) fc->setOffscreen(true);
237     if (arguments.read("--screen")) fc->setOffscreen(false);
238 
239     if (arguments.read("--flip")) fc->setOutputImageFlip(true);
240     if (arguments.read("--no-flip")) fc->setOutputImageFlip(false);
241 
242     unsigned int width = 1024;
243     if (arguments.read("--width",width)) fc->setWidth(width);
244 
245     unsigned int height = 512;
246     if (arguments.read("--height",height)) fc->setHeight(height);
247 
248     if (arguments.read("--rgb")) fc->setPixelFormat(gsc::CaptureSettings::RGB);
249     if (arguments.read("--rgba")) fc->setPixelFormat(gsc::CaptureSettings::RGBA);
250 
251     osg::Vec4 clearColor(0.0f,0.0f,0.0f,0.0f);
252     while (arguments.read("--clear-color",clearColor[0],clearColor[1],clearColor[2],clearColor[3])) {}
253 
254 
255     unsigned int samples = 0;
256     if (arguments.read("--samples",samples)) fc->setSamples(samples);
257 
258     unsigned int sampleBuffers = 0;
259     if (arguments.read("--sampleBuffers",sampleBuffers)) fc->setSampleBuffers(sampleBuffers);
260 
261     unsigned int ms = 0;
262     if (arguments.read("--ms",ms))
263     {
264         fc->setSamples(ms);
265         fc->setSampleBuffers(1);
266     }
267 
268     if (arguments.read("-f",fps)) fc->setFrameRate(fps);
269 
270     if (arguments.read("-n",nframes)) fc->setNumberOfFrames(nframes);
271 
272     if (arguments.read("-d",duration)) {}
273 
274 
275     std::string key;
276     double time;
277     while(arguments.read("--key-down",time, key) && key.size()>=1)
278     {
279         OSG_NOTICE<<"keydown "<<key<<", "<<time<<std::endl;
280         osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter;
281         event->setTime(time);
282         event->setEventType(osgGA::GUIEventAdapter::KEYDOWN);
283         event->setKey(key[0]);
284         fc->addUpdateProperty(new gsc::EventProperty(event.get()));
285     }
286 
287     while(arguments.read("--key-up",time, key) && key.size()>=1)
288     {
289         OSG_NOTICE<<"keyup "<<key<<", "<<time<<std::endl;
290         osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter;
291         event->setTime(time);
292         event->setEventType(osgGA::GUIEventAdapter::KEYUP);
293         event->setKey(key[0]);
294         fc->addUpdateProperty(new gsc::EventProperty(event.get()));
295     }
296 
297     double mouse_x, mouse_y;
298     while(arguments.read("--mouse-move",time, mouse_x, mouse_y))
299     {
300         OSG_NOTICE<<"mouse move "<<time<<", "<<mouse_x<<", "<<mouse_y<<std::endl;
301         osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter;
302         event->setTime(time);
303         event->setEventType(osgGA::GUIEventAdapter::MOVE);
304         event->setX(mouse_x);
305         event->setY(mouse_y);
306         fc->addUpdateProperty(new gsc::EventProperty(event.get()));
307     }
308 
309     while(arguments.read("--mouse-drag",time, mouse_x, mouse_y))
310     {
311         OSG_NOTICE<<"mouse drag "<<time<<", "<<mouse_x<<", "<<mouse_y<<std::endl;
312         osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter;
313         event->setTime(time);
314         event->setEventType(osgGA::GUIEventAdapter::DRAG);
315         event->setX(mouse_x);
316         event->setY(mouse_y);
317         fc->addUpdateProperty(new gsc::EventProperty(event.get()));
318     }
319 
320 
321     if (!readCaptureSettings)
322     {
323         if (duration!=0.0)
324         {
325             if (fps!=0.0) nframes = static_cast<unsigned int>(ceil(duration*fps));
326             else if (nframes!=0) fps = duration/static_cast<double>(nframes);
327             else
328             {
329                 fps = 60.0;
330                 nframes = static_cast<unsigned int>(ceil(duration/fps));
331             }
332         }
333         else // duration == 0.0
334         {
335             if (fps==0.0) fps=60.0;
336             if (nframes==0) nframes=1;
337 
338             duration = static_cast<double>(nframes)/fps;
339         }
340 
341         fc->setNumberOfFrames(nframes);
342         fc->setFrameRate(fps);
343         OSG_NOTICE<<"Duration="<<duration<<", FPS="<<fps<<", Number of Frames="<<nframes<<std::endl;
344     }
345 
346 
347 
348 
349     if (arguments.read("--output-cs",filename))
350     {
351         osgDB::writeObjectFile(*fc, filename);
352         return 1;
353     }
354 
355 
356 
357     if (fc.valid())
358     {
359         frameCaptureList.push_back(fc);
360     }
361 
362     if (frameCaptureList.empty())
363     {
364         OSG_NOTICE<<"No settings provided"<<std::endl;
365         return 1;
366     }
367 
368 
369     // setup viewer
370     {
371         osg::ref_ptr<osg::DisplaySettings> ds = new osg::DisplaySettings;
372 
373         bool stereo = fc->getStereoMode()!=gsc::CaptureSettings::OFF;
374         osg::DisplaySettings::StereoMode stereoMode = fc->getStereoMode()==gsc::CaptureSettings::VERTICAL_SPLIT ? osg::DisplaySettings::VERTICAL_SPLIT : osg::DisplaySettings::HORIZONTAL_SPLIT;
375         double fovx_multiple = fc->getStereoMode()==gsc::CaptureSettings::HORIZONTAL_SPLIT ? 2.0 : 1;
376         double fovy_multiple = fc->getStereoMode()==gsc::CaptureSettings::VERTICAL_SPLIT ? 2.0 : 1;
377         ds->setStereoMode(stereoMode);
378         ds->setStereo(stereo);
379 
380         if (fc->getScreenWidth()!=0.0) ds->setScreenWidth(fc->getScreenWidth());
381         if (fc->getScreenHeight()!=0.0) ds->setScreenHeight(fc->getScreenHeight());
382         if (fc->getScreenDistance()!=0.0) ds->setScreenDistance(fc->getScreenDistance());
383 
384 
385         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(ds.get());
386 
387         traits->readDISPLAY();
388         if (traits->displayNum<0) traits->displayNum = 0;
389 
390         traits->x = 0;
391         traits->y = 0;
392         traits->width = fc->getWidth();
393         traits->height = fc->getHeight();
394         traits->alpha = (fc->getPixelFormat() == gsc::CaptureSettings::RGBA) ? 8 : 0;
395         traits->samples = fc->getSamples();
396         traits->sampleBuffers = fc->getSampleBuffers();
397         traits->windowDecoration = !(fc->getOffscreen());
398         traits->doubleBuffer = true;
399         traits->sharedContext = 0;
400         traits->pbuffer = fc->getOffscreen();
401 
402         osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
403         if (!gc)
404         {
405             OSG_NOTICE<<"Failed to created requested graphics context"<<std::endl;
406             return 1;
407         }
408 
409         viewer.getCamera()->setClearColor(clearColor);
410         viewer.getCamera()->setGraphicsContext(gc.get());
411         viewer.getCamera()->setDisplaySettings(ds.get());
412 
413         osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
414         if (gw)
415         {
416             OSG_INFO<<"GraphicsWindow has been created successfully."<<std::endl;
417             gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, fc->getWidth(),  fc->getHeight());
418         }
419         else
420         {
421             OSG_NOTICE<<"PixelBuffer has been created succseffully "<<traits->width<<", "<<traits->height<<std::endl;
422         }
423 
424         if (useScreenSizeForProjectionMatrix)
425         {
426             OSG_NOTICE<<"Setting projection matrix"<<std::endl;
427 
428             double vfov = osg::RadiansToDegrees(atan2(screenHeight/2.0f,screenDistance)*2.0);
429             // double hfov = osg::RadiansToDegrees(atan2(width/2.0f,distance)*2.0);
430 
431             viewer.getCamera()->setProjectionMatrixAsPerspective( vfov*fovy_multiple, (screenWidth/screenHeight)*fovx_multiple, 0.1, 1000.0);
432 
433             OSG_NOTICE<<"setProjectionMatrixAsPerspective( "<<vfov*fovy_multiple<<", "<<(screenWidth/screenHeight)*fovx_multiple<<", "<<0.1<<", "<<1000.0<<");"<<std::endl;
434 
435 
436         }
437         else
438         {
439             double fovy, aspectRatio, zNear, zFar;
440             viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
441 
442             double newAspectRatio = double(traits->width) / double(traits->height);
443             double aspectRatioChange = newAspectRatio / aspectRatio;
444             if (aspectRatioChange != 1.0)
445             {
446                 viewer.getCamera()->getProjectionMatrix() *= osg::Matrix::scale(fovx_multiple/aspectRatioChange,fovy_multiple,1.0);
447             }
448         }
449 
450         // set up stereo masks
451         viewer.getCamera()->setCullMask(0xffffffff);
452         viewer.getCamera()->setCullMaskLeft(0x00000001);
453         viewer.getCamera()->setCullMaskRight(0x00000002);
454 
455         viewer.getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
456 
457         GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
458 
459         viewer.getCamera()->setDrawBuffer(buffer);
460         viewer.getCamera()->setReadBuffer(buffer);
461     }
462 
463     std::string outputPath = osgDB::getFilePath(fc->getOutputFileName());
464     if (!outputPath.empty())
465     {
466         osgDB::FileType type = osgDB::fileType(outputPath);
467         switch(type)
468         {
469             case(osgDB::FILE_NOT_FOUND):
470                 if (!osgDB::makeDirectory(outputPath))
471                 {
472                     OSG_NOTICE<<"Error: could not create directory ["<<outputPath<<"]."<<std::endl;
473                     return 1;
474                 }
475                 OSG_NOTICE<<"Created directory ["<<outputPath<<"]."<<std::endl;
476                 break;
477             case(osgDB::REGULAR_FILE):
478                 OSG_NOTICE<<"Error: filepath for output files is regular file, not a directory as required."<<std::endl;
479                 return 1;
480             case(osgDB::DIRECTORY):
481                 OSG_NOTICE<<"Valid path["<<outputPath<<"] provided for output files."<<std::endl;
482                 break;
483         }
484     }
485 
486     GLenum pixelFormat = (fc->getPixelFormat()==gsc::CaptureSettings::RGBA) ? GL_RGBA : GL_RGB;
487 
488 
489     viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
490     viewer.realize();
491 
492     // set up screen shot
493     osg::ref_ptr<ScreenShot> screenShot = new ScreenShot(pixelFormat, fc->getOutputImageFlip());;
494     {
495 
496         osgViewer::Viewer::Cameras cameras;
497         viewer.getCameras(cameras);
498         if (cameras.size()>1)
499         {
500             unsigned int cameraNum = 0;
501             for(osgViewer::Viewer::Cameras::iterator itr = cameras.begin();
502                 itr != cameras.end();
503                 ++itr, ++cameraNum)
504             {
505                 osg::Camera* camera = *itr;
506                 camera->setFinalDrawCallback(screenShot.get());
507                 screenShot->_cameraNumMap[camera] = cameraNum;
508             }
509         }
510         else if (cameras.size()==1)
511         {
512             osg::Camera* camera = cameras.front();
513             camera->setFinalDrawCallback(screenShot.get());
514         }
515         else
516         {
517             OSG_NOTICE<<"No usable Cameras created."<<std::endl;
518             return 1;
519         }
520     }
521 
522     for(CaptureSettingsList::iterator itr = frameCaptureList.begin();
523         itr != frameCaptureList.end();
524         ++itr)
525     {
526         gsc::CaptureSettings* fc = itr->get();
527         screenShot->_frameCapture = fc;
528 
529         osg::ref_ptr<osg::Node> model = osgDB::readRefNodeFile(fc->getInputFileName());
530         if (!model) break;
531 
532         viewer.setSceneData(model.get());
533 
534         double simulationTime = 0.0;
535 
536         for(unsigned int i=0; i<fc->getNumberOfFrames(); ++i)
537         {
538             OSG_NOTICE<<"fc.getOutputFileName("<<i<<")="<<fc->getOutputFileName(i)<<std::endl;
539 
540             viewer.advance(simulationTime);
541 
542             gsc::CaptureSettings::Properties& pl = fc->getProperties();
543             for(gsc::CaptureSettings::Properties::iterator plitr = pl.begin();
544                 plitr != pl.end();
545                 ++plitr)
546             {
547                 (*plitr)->update(&viewer);
548             }
549 
550             viewer.eventTraversal();
551             viewer.updateTraversal();
552             viewer.renderingTraversals();
553 
554             // advance simulationTime and number of frames rendered
555             simulationTime += 1.0/fc->getFrameRate();
556         }
557     }
558 
559     osg::ref_ptr<osg::Object> object = new osgGA::StateSetManipulator;
560     osg::ref_ptr<osgGA::StateSetManipulator> ss = dynamic_cast<osgGA::StateSetManipulator*>(object.get());
561 
562     return 0;
563 }
564