root/OpenSceneGraph/trunk/examples/osgstereoimage/osgstereoimage.cpp @ 13662

Revision 13574, 22.8 kB (checked in by robert, 92 minutes ago)

From Mattias Helsing, "Seems I was only half right given what you asked for. CMP0017 only
says that modules that are found and ran from cmake modules dir should
prefer cmake-provided modules. find_package() and include() still look
in CMAKE_MODULE_PATH first.

After some investigating I've come up with a proposal examplified in
the attached FindGDAL.cmake script. It simply calls the cmake provided
FindGDAL.cmake if it exists and returns if it succeeds in finding GDAL
using that, otherwise continue with our local cmake code.
Pro: Wont clutter our root CMakeLists.txt
Con: If we begin to write more advanced Findxxx modules (using
COMPONENTS, REQUIRED etc.) we may have to revise this scheme.
"

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgstereoimage.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19#include <osgViewer/Viewer>
20#include <osgDB/fstream>
21#include <osgDB/ReadFile>
22#include <osgDB/WriteFile>
23#include <osgUtil/Optimizer>
24
25#include <osg/ImageStream>
26#include <osg/Geode>
27#include <osg/Notify>
28#include <osg/MatrixTransform>
29#include <osg/Switch>
30#include <osg/TexMat>
31#include <osg/Texture2D>
32
33#include <iostream>
34
35typedef std::vector<std::string> FileList;
36
37#include <osg/Program>
38#include <osg/Shader>
39
40osg::StateSet* createColorToGreyscaleStateSet()
41{
42    osg::StateSet* stateset = new osg::StateSet;
43
44    osg::Program* program = new osg::Program;
45    stateset->setAttribute(program);
46
47    const char* fragSource =
48    {
49        "uniform sampler2D baseTexture;\n"
50        "uniform mat4 colorMatrix;\n"
51        "void main(void)\n"
52        "{\n"
53        "    vec4 color = texture2D( baseTexture, gl_TexCoord[0].st );\n"
54        "    gl_FragColor = colorMatrix * color;\n"
55        "}\n"
56    };
57    program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSource));
58
59    stateset->addUniform(new osg::Uniform("baseTexture",0));
60
61    osg::Matrixf colorMatrix(
62        0.3f, 0.3f, 0.3f, 0.0f,
63        0.59f, 0.59f, 0.59f, 0.0f,
64        0.11f, 0.11f, 0.11f, 0.0f,
65        0.0f, 0.0f, 0.0f, 1.0f
66    );
67
68    stateset->addUniform(new osg::Uniform("colorMatrix",colorMatrix));
69
70    return stateset;
71}
72
73
74osg::Geode* createSectorForImage(osg::Image* image, osg::TexMat* texmat, float s,float t, float radius, float height, float length)
75{
76    bool flip = image->getOrigin()==osg::Image::TOP_LEFT;
77
78    int numSegments = 20;
79    float Theta = length/radius;
80    float dTheta = Theta/(float)(numSegments-1);
81
82    float ThetaZero = height*s/(t*radius);
83
84    // set up the texture.
85    osg::Texture2D* texture = new osg::Texture2D;
86    texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
87    texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
88    texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
89    texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
90    texture->setResizeNonPowerOfTwoHint(false);
91    texture->setImage(image);
92
93    // set up the drawstate.
94    osg::StateSet* dstate = new osg::StateSet;
95    dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
96    dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
97    dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);
98    dstate->setTextureAttribute(0, texmat);
99
100    // set up the geoset.
101    osg::Geometry* geom = new osg::Geometry;
102    geom->setStateSet(dstate);
103
104    osg::Vec3Array* coords = new osg::Vec3Array();
105    osg::Vec2Array* tcoords = new osg::Vec2Array();
106
107    int i;
108    float angle = -Theta/2.0f;
109    for(i=0;
110        i<numSegments;
111        ++i, angle+=dTheta)
112    {
113        coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,height*0.5f)); // top
114        coords->push_back(osg::Vec3(sinf(angle)*radius,cosf(angle)*radius,-height*0.5f)); // bottom.
115
116        tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f, flip ? 0.0f : 1.0f)); // top
117        tcoords->push_back(osg::Vec2(angle/ThetaZero+0.5f, flip ? 1.0f : 0.0f)); // bottom.
118
119    }
120
121    osg::Vec4Array* colors = new osg::Vec4Array();
122    colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
123
124    osg::DrawArrays* elements = new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP,0,coords->size());
125
126
127
128    geom->setVertexArray(coords);
129    geom->setTexCoordArray(0,tcoords);
130    geom->setColorArray(colors, osg::Array::BIND_OVERALL);
131
132    geom->addPrimitiveSet(elements);
133
134    // set up the geode.
135    osg::Geode* geode = new osg::Geode;
136    geode->addDrawable(geom);
137
138    return geode;
139
140}
141
142osg::Group * loadImages(std::string image1, std::string image2, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length)
143{
144    osg::ref_ptr<osg::Image> imageLeft = osgDB::readImageFile(image1);
145    osg::ref_ptr<osg::Image> imageRight = osgDB::readImageFile(image2);
146    if (imageLeft.valid() && imageRight.valid())
147    {
148        osg::ImageStream* streamLeft = dynamic_cast<osg::ImageStream*>(imageLeft.get());
149        if (streamLeft) streamLeft->play();
150
151        osg::ImageStream* streamRight = dynamic_cast<osg::ImageStream*>(imageRight.get());
152        if (streamRight) streamRight->play();
153
154
155        float average_s = (imageLeft->s()+imageRight->s())*0.5f;
156        float average_t = (imageLeft->t()+imageRight->t())*0.5f;
157        osg::Geode* geodeLeft = createSectorForImage(imageLeft.get(),texmatLeft,average_s,average_t, radius, height, length);
158        geodeLeft->setNodeMask(0x01);
159
160        osg::Geode* geodeRight = createSectorForImage(imageRight.get(),texmatRight,average_s,average_t, radius, height, length);
161        geodeRight->setNodeMask(0x02);
162
163        osg::Group * imageGroup = new osg::Group;
164
165        imageGroup->addChild(geodeLeft);
166        imageGroup->addChild(geodeRight);
167        return imageGroup;
168    }
169    else
170    {
171        std::cout << "Warning: Unable to load both image files, '"<<image1<<"' & '"<<image2<<"', required for stereo imaging."<<std::endl;
172        return 0;
173    }
174}
175
176// create a switch containing a set of child each containing a
177// stereo image pair.
178osg::Switch* createScene(FileList fileList, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length)
179{
180    osg::Switch* sw = new osg::Switch;
181
182    // load the images.
183    for(unsigned int i=0;i+1<fileList.size();i+=2)
184    {
185        osg::Group * imageGroup = loadImages(fileList[i],fileList[i+1],texmatLeft,texmatRight, radius,  height, length);
186        if (imageGroup) sw->addChild(imageGroup);
187    }
188
189
190    if (sw->getNumChildren()>0)
191    {
192        // select first child.
193        sw->setSingleChildOn(0);
194    }
195
196    return sw;
197}
198
199class SlideEventHandler : public osgGA::GUIEventHandler
200{
201public:
202
203    SlideEventHandler();
204
205    META_Object(osgStereImageApp,SlideEventHandler);
206
207
208    void set(osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float timePerSlide, bool autoSteppingActive);
209
210    void set(FileList fileList, osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length, float timePerSlide, bool autoSteppingActive);
211
212
213    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
214
215    virtual void getUsage(osg::ApplicationUsage& usage) const;
216
217    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
218
219    void nextSlide();
220
221    void previousSlide();
222
223    void scaleImage(float s);
224
225    void offsetImage(float ds,float dt);
226
227    void rotateImage(float rx,float ry);
228
229    void initTexMatrices();
230
231protected:
232
233    ~SlideEventHandler() {}
234    SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {}
235
236    osg::ref_ptr<osg::Switch>   _switch;
237    osg::ref_ptr<osg::TexMat>   _texmatLeft;
238    osg::ref_ptr<osg::TexMat>   _texmatRight;
239    float                        _radius;
240    float                        _height;
241    float                        _length;
242    bool                        _firstTraversal;
243    unsigned int                _activeSlide;
244    double                      _previousTime;
245    double                      _timePerSlide;
246    bool                        _autoSteppingActive;
247    float                       _initSeperationX;
248    float                       _currentSeperationX;
249    float                       _initSeperationY;
250    float                       _currentSeperationY;
251    FileList                     _fileList;
252
253};
254
255SlideEventHandler::SlideEventHandler():
256    _switch(0),
257    _texmatLeft(0),
258    _texmatRight(0),
259    _firstTraversal(true),
260    _activeSlide(0),
261    _previousTime(-1.0f),
262    _timePerSlide(5.0),
263    _autoSteppingActive(false)
264{
265}
266
267void SlideEventHandler::set(osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float timePerSlide, bool autoSteppingActive)
268{
269    _switch = sw;
270    _switch->setUpdateCallback(this);
271
272    _texmatLeft = texmatLeft;
273    _texmatRight = texmatRight;
274
275    _timePerSlide = timePerSlide;
276    _autoSteppingActive = autoSteppingActive;
277
278    _initSeperationX = offsetX;
279    _currentSeperationX = _initSeperationX;
280
281    _initSeperationY = offsetY;
282    _currentSeperationY = _initSeperationY;
283
284    initTexMatrices();
285
286}
287
288void SlideEventHandler::set(FileList fileList, osg::Switch* sw, float offsetX, float offsetY, osg::TexMat* texmatLeft, osg::TexMat* texmatRight, float radius, float height, float length, float timePerSlide, bool autoSteppingActive)
289{
290    _switch = sw;
291    _switch->setUpdateCallback(this);
292    _fileList=FileList(fileList);
293
294    osg::ref_ptr<osg::Group> imageGroup = loadImages(fileList[0],fileList[1],texmatLeft,texmatRight, radius,  height, length);
295    if (imageGroup.get())_switch->addChild(imageGroup.get());
296
297    _texmatLeft = texmatLeft;
298    _texmatRight = texmatRight;
299
300    _radius=radius;
301    _height=height;
302    _length=length;
303
304    _timePerSlide = timePerSlide;
305    _autoSteppingActive = autoSteppingActive;
306
307    _initSeperationX = offsetX;
308    _currentSeperationX = _initSeperationX;
309
310    _initSeperationY = offsetY;
311    _currentSeperationY = _initSeperationY;
312
313    initTexMatrices();
314}
315
316
317bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
318{
319    switch(ea.getEventType())
320    {
321        case(osgGA::GUIEventAdapter::KEYDOWN):
322        {
323            if (ea.getKey()=='a')
324            {
325                _autoSteppingActive = !_autoSteppingActive;
326                _previousTime = ea.getTime();
327                return true;
328            }
329            else if ((ea.getKey()=='n') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right))
330            {
331                nextSlide();
332                return true;
333            }
334            else if ((ea.getKey()=='p') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left))
335            {
336                previousSlide();
337                return true;
338            }
339            else if ((ea.getKey()=='w') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Add))
340            {
341                scaleImage(0.99f);
342                return true;
343            }
344            else if ((ea.getKey()=='s') || (ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Subtract))
345            {
346                scaleImage(1.01f);
347                return true;
348            }
349            else if (ea.getKey()=='j')
350            {
351                offsetImage(-0.001f,0.0f);
352                return true;
353            }
354            else if (ea.getKey()=='k')
355            {
356                offsetImage(0.001f,0.0f);
357                return true;
358            }
359            else if (ea.getKey()=='i')
360            {
361                offsetImage(0.0f,-0.001f);
362                return true;
363            }
364            else if (ea.getKey()=='m')
365            {
366                offsetImage(0.0f,0.001f);
367                return true;
368            }
369            else if (ea.getKey()==' ')
370            {
371                initTexMatrices();
372                return true;
373            }
374            return false;
375        }
376        case(osgGA::GUIEventAdapter::DRAG):
377        case(osgGA::GUIEventAdapter::MOVE):
378        {
379            static float px = ea.getXnormalized();
380            static float py = ea.getYnormalized();
381
382            float dx = ea.getXnormalized()-px;
383            float dy = ea.getYnormalized()-py;
384
385            px = ea.getXnormalized();
386            py = ea.getYnormalized();
387
388            rotateImage(dx,dy);
389
390            return true;
391        }
392
393        default:
394            return false;
395    }
396}
397
398void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
399{
400    usage.addKeyboardMouseBinding("Space","Reset the image position to center");
401    usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
402    usage.addKeyboardMouseBinding("n","Advance to next image");
403    usage.addKeyboardMouseBinding("p","Move to previous image");
404    usage.addKeyboardMouseBinding("q","Zoom into the image");
405    usage.addKeyboardMouseBinding("a","Zoom out of the image");
406    usage.addKeyboardMouseBinding("j","Reduce horizontal offset");
407    usage.addKeyboardMouseBinding("k","Increase horizontal offset");
408    usage.addKeyboardMouseBinding("m","Reduce vertical offset");
409    usage.addKeyboardMouseBinding("i","Increase vertical offset");
410}
411
412void SlideEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv)
413{
414    if (_autoSteppingActive && nv->getFrameStamp())
415    {
416        double time = nv->getFrameStamp()->getSimulationTime();
417
418        if (_firstTraversal)
419        {
420            _firstTraversal = false;
421            _previousTime = time;
422        }
423        else if (time-_previousTime>_timePerSlide)
424        {
425            _previousTime = time;
426
427            nextSlide();
428        }
429
430    }
431
432    traverse(node,nv);
433}
434
435void SlideEventHandler::nextSlide()
436{
437
438    if (_switch->getNumChildren()==0) return;
439
440    ++_activeSlide;
441
442    if (_fileList.size()>0) {
443        if (_activeSlide>= _fileList.size()/2 ) _activeSlide = 0;
444        osg::ref_ptr<osg::Group> images = loadImages(_fileList[2*_activeSlide],_fileList[2*_activeSlide+1],_texmatLeft.get(),_texmatRight.get(),_radius,_height,_length);
445        if (images.valid()) _switch->replaceChild(_switch->getChild(0),images.get());
446
447    } else {
448        if (_activeSlide>=_switch->getNumChildren()) _activeSlide = 0;
449
450        _switch->setSingleChildOn(_activeSlide);
451    }
452}
453
454void SlideEventHandler::previousSlide()
455{
456    if (_switch->getNumChildren()==0) return;
457
458    if (_fileList.size()>0) {
459        if (_activeSlide==0) _activeSlide = _fileList.size()/2-1;
460        else --_activeSlide;
461        osg::ref_ptr<osg::Group> images = loadImages(_fileList[2*_activeSlide],_fileList[2*_activeSlide+1],_texmatLeft.get(),_texmatRight.get(),_radius,_height,_length);
462        if (images.valid()) _switch->replaceChild(_switch->getChild(0),images.get());
463    } else {
464        if (_activeSlide==0) _activeSlide = _switch->getNumChildren()-1;
465        else --_activeSlide;
466
467        _switch->setSingleChildOn(_activeSlide);
468    }
469}
470
471void SlideEventHandler::scaleImage(float s)
472{
473    _texmatLeft->setMatrix(_texmatLeft->getMatrix()*osg::Matrix::translate(-0.5f,-0.5f,0.0f)*osg::Matrix::scale(s,s,1.0f)*osg::Matrix::translate(0.5f,0.5f,0.0f));
474    _texmatRight->setMatrix(_texmatRight->getMatrix()*osg::Matrix::translate(-0.5f,-0.5f,0.0f)*osg::Matrix::scale(s,s,1.0f)*osg::Matrix::translate(0.5f,0.5f,0.0f));
475}
476
477void SlideEventHandler::offsetImage(float ds,float dt)
478{
479    _currentSeperationX+=ds;
480    _currentSeperationY+=dt;
481    osg::notify(osg::NOTICE)<<"image offset x = "<<_currentSeperationX<<"  y ="<<_currentSeperationY<<std::endl;
482    _texmatLeft->setMatrix(_texmatLeft->getMatrix()*osg::Matrix::translate(ds,dt,0.0f));
483    _texmatRight->setMatrix(_texmatRight->getMatrix()*osg::Matrix::translate(-ds,-dt,0.0f));
484}
485
486void SlideEventHandler::rotateImage(float rx,float ry)
487{
488    const float scale = 0.5f;
489    _texmatLeft->setMatrix(_texmatLeft->getMatrix()*osg::Matrix::translate(-rx*scale,-ry*scale,0.0f));
490    _texmatRight->setMatrix(_texmatRight->getMatrix()*osg::Matrix::translate(-rx*scale,-ry*scale,0.0f));
491}
492
493void SlideEventHandler::initTexMatrices()
494{
495    _texmatLeft->setMatrix(osg::Matrix::translate(_initSeperationX,_initSeperationY,0.0f));
496    _texmatRight->setMatrix(osg::Matrix::translate(-_initSeperationX,-_initSeperationY,0.0f));
497}
498
499
500
501int main( int argc, char **argv )
502{
503    // use an ArgumentParser object to manage the program arguments.
504    osg::ArgumentParser arguments(&argc,argv);
505
506    // set up the usage document, in case we need to print out how to use this program.
507    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use node masks to create stereo images.");
508    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
509    arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time delay in seconds between the display of successive image pairs when in auto advance mode.");
510    arguments.getApplicationUsage()->addCommandLineOption("-a","Enter auto advance of image pairs on start up.");
511    arguments.getApplicationUsage()->addCommandLineOption("-x <float>","Horizontal offset of left and right images.");
512    arguments.getApplicationUsage()->addCommandLineOption("-y <float>","Vertical offset of left and right images.");
513    arguments.getApplicationUsage()->addCommandLineOption("--disk","Keep images on disk");
514    arguments.getApplicationUsage()->addCommandLineOption("-files <filename>","Load filenames from a file");
515    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
516    arguments.getApplicationUsage()->addCommandLineOption("--SingleThreaded","Select SingleThreaded threading model for viewer.");
517    arguments.getApplicationUsage()->addCommandLineOption("--CullDrawThreadPerContext","Select CullDrawThreadPerContext threading model for viewer.");
518    arguments.getApplicationUsage()->addCommandLineOption("--DrawThreadPerContext","Select DrawThreadPerContext threading model for viewer.");
519    arguments.getApplicationUsage()->addCommandLineOption("--CullThreadPerCameraDrawThreadPerContext","Select CullThreadPerCameraDrawThreadPerContext threading model for viewer.");
520
521
522    // construct the viewer.
523    osgViewer::Viewer viewer(arguments);
524
525    // register the handler to add keyboard and mouse handling.
526    SlideEventHandler* seh = new SlideEventHandler();
527    viewer.addEventHandler(seh);
528
529    // read any time delay argument.
530    float timeDelayBetweenSlides = 5.0f;
531    while (arguments.read("-d",timeDelayBetweenSlides)) {}
532
533    bool autoSteppingActive = false;
534    while (arguments.read("-a")) autoSteppingActive = true;
535
536    float offsetX=0.0f;
537    while (arguments.read("-x",offsetX)) {}
538
539    float offsetY=0.0f;
540    while (arguments.read("-y",offsetY)) {}
541
542    bool onDisk=false;
543    while (arguments.read("--disk")) { onDisk=true;}
544
545    std::string filename="";
546    FileList fileList;
547    // extract the filenames from the a file, one filename per line.
548    while (arguments.read("-files",filename)) {
549        osgDB::ifstream is(filename.c_str());
550        if (is) {
551                std::string line;
552                while (std::getline(is,line,'\n')) fileList.push_back(line);
553                is.close();
554            }
555
556    }
557
558    // if user request help write it out to cout.
559    if (arguments.read("-h") || arguments.read("--help"))
560    {
561        arguments.getApplicationUsage()->write(std::cout);
562        return 1;
563    }
564
565    osgViewer::Viewer::ThreadingModel threading = osgViewer::Viewer::SingleThreaded;
566    while (arguments.read("--SingleThreaded")) threading = osgViewer::Viewer::SingleThreaded;
567    while (arguments.read("--CullDrawThreadPerContext")) threading = osgViewer::Viewer::CullDrawThreadPerContext;
568    while (arguments.read("--DrawThreadPerContext")) threading = osgViewer::Viewer::DrawThreadPerContext;
569    while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) threading = osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext;
570
571    viewer.setThreadingModel(threading);
572
573    // any option left unread are converted into errors to write out later.
574    arguments.reportRemainingOptionsAsUnrecognized();
575
576    // report any errors if they have occurred when parsing the program arguments.
577    if (arguments.errors())
578    {
579        arguments.writeErrorMessages(std::cout);
580        return 1;
581    }
582
583    // extract the filenames from the arguments list.
584    for(int pos=1;pos<arguments.argc();++pos)
585    {
586        if (arguments.isString(pos)) fileList.push_back(arguments[pos]);
587    }
588
589    if (fileList.empty())
590    {
591        fileList.push_back("Images/dog_left_eye.jpg");
592         fileList.push_back("Images/dog_right_eye.jpg");
593    }
594    else if (fileList.size()<2)
595    {
596        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
597        return 1;
598    }
599
600    // now the windows have been realized we switch off the cursor to prevent it
601    // distracting the people seeing the stereo images.
602    double fovy, aspectRatio, zNear, zFar;
603    viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);
604
605    float radius = 1.0f;
606    float height = 2*radius*tan(osg::DegreesToRadians(fovy)*0.5f);
607    float length = osg::PI*radius;  // half a cylinder.
608
609    // use a texture matrix to control the placement of the image.
610    osg::TexMat* texmatLeft = new osg::TexMat;
611    osg::TexMat* texmatRight = new osg::TexMat;
612
613    // creat the scene from the file list.
614    osg::ref_ptr<osg::Switch> rootNode;
615    if (!onDisk)  rootNode = createScene(fileList,texmatLeft,texmatRight,radius,height,length);
616    else rootNode=new osg::Switch();
617
618    //osgDB::writeNodeFile(*rootNode,"test.osgt");
619
620
621
622    viewer.getCamera()->setCullMask(0xffffffff);
623    viewer.getCamera()->setCullMaskLeft(0x00000001);
624    viewer.getCamera()->setCullMaskRight(0x00000002);
625
626    // set up the use of stereo by default.
627    osg::DisplaySettings::instance()->setStereo(true);
628
629    if (osg::DisplaySettings::instance()->getStereoMode()==osg::DisplaySettings::ANAGLYPHIC)
630    {
631        rootNode->setStateSet(createColorToGreyscaleStateSet());
632    }
633
634
635    // set the scene to render
636    viewer.setSceneData(rootNode.get());
637
638
639    // create the windows and run the threads.
640    viewer.realize();
641
642
643    // switch off the cursor
644    osgViewer::Viewer::Windows windows;
645    viewer.getWindows(windows);
646    for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
647        itr != windows.end();
648        ++itr)
649    {
650        (*itr)->useCursor(false);
651    }
652
653    viewer.setFusionDistance(osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE,radius);
654
655    // set up the SlideEventHandler.
656    if (onDisk) seh->set(fileList,rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,radius,height,length,timeDelayBetweenSlides,autoSteppingActive);
657    else seh->set(rootNode.get(),offsetX,offsetY,texmatLeft,texmatRight,timeDelayBetweenSlides,autoSteppingActive);
658
659    osg::Matrix homePosition;
660    homePosition.makeLookAt(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(0.0f,1.0f,0.0f),osg::Vec3(0.0f,0.0f,1.0f));
661
662    while( !viewer.done() )
663    {
664        viewer.getCamera()->setViewMatrix(homePosition);
665
666        // fire off the cull and draw traversals of the scene.
667        viewer.frame();
668
669    }
670
671    return 0;
672}
Note: See TracBrowser for help on using the browser.