root/OpenSceneGraph/trunk/examples/osgcatch/osgcatch.cpp @ 4025

Revision 4025, 27.4 kB (checked in by robert, 9 years ago)

Fixed bug

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under 
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <osgProducer/Viewer>
15#include <osgDB/ReadFile>
16#include <osgDB/WriteFile>
17#include <osgUtil/Optimizer>
18
19#include <osg/Geode>
20#include <osg/Notify>
21#include <osg/MatrixTransform>
22#include <osg/PositionAttitudeTransform>
23#include <osg/Switch>
24#include <osg/TexMat>
25#include <osg/Texture2D>
26#include <osg/io_utils>
27
28#include <osgParticle/ExplosionEffect>
29#include <osgParticle/ExplosionDebriEffect>
30#include <osgParticle/SmokeEffect>
31#include <osgParticle/FireEffect>
32
33typedef std::vector<std::string> FileList;
34
35class Character : public osg::Referenced
36{
37public:
38    Character();
39   
40    void setCharacter(const std::string& filename, const std::string& name, const osg::Vec3& orgin, const osg::Vec3& width, float positionRatio);
41   
42    void setLives(const std::string& filename, const osg::Vec3& orgin, const osg::Vec3& delta, unsigned int numLives);
43   
44    void setCatches(const std::string& filename, const osg::Vec3& orgin, const osg::Vec3& delta, unsigned int numLives);
45
46    void moveLeft();
47    void moveRight();
48    void moveTo(float positionRatio);
49
50    void reset();
51
52    bool addCatch();
53    bool looseLife();
54
55    osg::Vec3 getCurrentCenterOfBasket() const { return _character->getPosition()+_centerBasket; }
56    float getCurrentRadiusOfBasket() const { return _radiusBasket; }
57
58    osg::Vec3 getLowerLeft() const { return _character->getPosition(); }
59    osg::Vec3 getUpperRight() const { return _character->getPosition(); }
60
61    osg::Vec3 _origin;
62    osg::Vec3 _width;
63
64    float                                        _positionRatio;
65    osg::ref_ptr<osg::PositionAttitudeTransform> _character;
66
67    unsigned int                                 _numLives;
68    osg::ref_ptr<osg::Switch>                    _livesSwitch;
69
70    unsigned int                                 _numCatches;
71    osg::ref_ptr<osg::Switch>                    _catchSwitch;
72   
73    osg::ref_ptr<osg::Group>                     _objectsGroup;
74   
75    osg::Vec3                                    _centerBasket;
76    float                                        _radiusBasket;
77   
78};
79
80Character::Character():
81    _positionRatio(0.5f),
82    _numLives(3),
83    _numCatches(0)
84{
85}
86
87
88void Character::setCharacter(const std::string& filename, const std::string& name, const osg::Vec3& origin, const osg::Vec3& width, float positionRatio)
89{
90    _origin = origin;
91    _width = width;
92    _positionRatio = positionRatio;
93    _numLives = 3;
94    _numCatches = 0;
95
96    float _characterSize = _width.length()*0.2f;
97
98    osg::Image* image = osgDB::readImageFile(filename);
99    if (image)
100    {
101        osg::Vec3 pos(-0.5f*_characterSize,0.0f,0.0f);
102        osg::Vec3 width(_characterSize*((float)image->s())/(float)(image->t()),0.0f,0.0);
103        osg::Vec3 height(0.0f,0.0f,_characterSize);
104
105        osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height);
106        osg::StateSet* stateset = geometry->getOrCreateStateSet();
107        stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON);
108        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
109        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
110
111        osg::Geode* geode = new osg::Geode;
112        geode->addDrawable(geometry);
113
114        _character = new osg::PositionAttitudeTransform;
115        _character->setName(name);
116        _character->addChild(geode);
117       
118        moveTo(positionRatio);
119
120        _centerBasket = width*0.2 + height*0.57 + pos;
121        _radiusBasket = width.length()*0.34;
122
123    }
124   
125}
126
127void Character::setLives(const std::string& filename, const osg::Vec3& origin, const osg::Vec3& delta, unsigned int numLives)
128{
129    float characterSize = delta.length();
130
131    _numLives = numLives;
132    _livesSwitch = new osg::Switch;
133
134    osg::Image* image = osgDB::readImageFile(filename);
135    if (image)
136    {
137        osg::StateSet* stateset = _livesSwitch->getOrCreateStateSet();
138        stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON);
139        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
140        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
141
142        for(unsigned int i=0; i<numLives; ++i)
143        {
144            osg::Vec3 pos = origin + delta*(float)i + osg::Vec3(0.0f,0.0f,0.0f);
145            osg::Vec3 width(characterSize*((float)image->s())/(float)(image->t()),0.0f,0.0);
146            osg::Vec3 height(0.0f,0.0f,characterSize);
147
148            osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height);
149
150            osg::Geode* geode = new osg::Geode;
151            geode->addDrawable(geometry);
152
153            _livesSwitch->addChild(geode,true);
154
155        }
156    }
157
158}
159
160void Character::setCatches(const std::string& filename, const osg::Vec3& origin, const osg::Vec3& delta, unsigned int numCatches)
161{
162    float characterSize = delta.length();
163
164    _numCatches = 0;
165    _catchSwitch = new osg::Switch;
166
167    osg::Image* image = osgDB::readImageFile(filename);
168    if (image)
169    {
170        osg::StateSet* stateset = _catchSwitch->getOrCreateStateSet();
171        stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON);
172        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
173        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
174
175        for(unsigned int i=0; i<numCatches; ++i)
176        {
177            osg::Vec3 pos = origin + delta*(float)i + osg::Vec3(0.0f,0.0f,0.0f);
178            osg::Vec3 width(characterSize,0.0f,0.0);
179            osg::Vec3 height(0.0f,0.0f,characterSize*((float)image->t())/(float)(image->s()));
180
181            osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height);
182
183            osg::Geode* geode = new osg::Geode;
184            geode->addDrawable(geometry);
185
186            _catchSwitch->addChild(geode,false);
187
188        }
189    }
190
191}
192
193void Character::moveLeft()
194{
195    moveTo(_positionRatio - 0.01f);
196}
197
198void Character::moveRight()
199{
200    moveTo(_positionRatio + 0.01f);
201}
202
203void Character::moveTo(float positionRatio)
204{
205    if (positionRatio<0.0f) positionRatio = 0.0f;
206    if (positionRatio>1.0f) positionRatio = 1.0f;
207
208    _positionRatio = positionRatio;
209    _character->setPosition(_origin+_width*+positionRatio);
210}
211
212void Character::reset()
213{
214    _numCatches = 0;
215    _numLives = _livesSwitch->getNumChildren();
216
217    _livesSwitch->setAllChildrenOn();
218    _catchSwitch->setAllChildrenOff();
219}
220
221bool Character::addCatch()
222{
223    if (!_catchSwitch || _numCatches>=_catchSwitch->getNumChildren()) return false;
224   
225    _catchSwitch->setValue(_numCatches,true);
226    ++_numCatches;
227   
228    return true;
229}
230
231bool Character::looseLife()
232{
233    if (!_livesSwitch || _numLives==0) return true;
234   
235    --_numLives;
236    _livesSwitch->setValue(_numLives,false);
237   
238    return (_numLives==0);
239}
240
241
242//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
243//
244class CatchableObject  : public osg::Referenced
245{
246    public:
247        CatchableObject();
248
249        void setObject(const std::string& filename, const std::string& name, const osg::Vec3& center, float size, const osg::Vec3& direction);
250
251        bool anyInside(const osg::Vec3& lower_left, const osg::Vec3& top_right);
252
253        bool centerInside(const osg::Vec3& center, float radius);
254       
255        void explode();
256       
257        bool dangerous() { return _dangerous; }
258
259        void stop() { _stopped = true; }
260       
261        bool stopped() { return _stopped; }
262       
263        void setTimeToRemove(double time) { _timeToRemove=time; }
264       
265        double getTimeToRemove() { return _timeToRemove; }
266       
267        bool needToRemove(double time) { return  _timeToRemove>=0.0 && time>_timeToRemove; }
268       
269        osg::ref_ptr<osg::PositionAttitudeTransform> _object;
270        osg::Vec3                                    _velocity;
271        float                                        _mass;
272        float                                        _radius;
273
274        bool                                         _stopped;
275        bool                                         _dangerous;
276
277        double                                       _timeToRemove;
278
279
280    public:
281   
282        // update position and velocity
283        void update(double dt);
284
285        /// Set the viscosity of the fluid.
286        inline void setFluidViscosity(float v)
287        {
288            _viscosity = v;
289            _viscosityCoefficient = 6 * osg::PI * _viscosity;
290        }
291       
292        /// Get the viscosity of the fluid.
293        inline float getFluidViscosity() const { return _viscosity; }
294
295        /// Set the density of the fluid.
296        inline void setFluidDensity(float d)
297        {
298            _density = d;
299            _densityCoefficeint = 0.2f * osg::PI * _density;
300        }
301
302        /// Get the density of the fluid.
303        inline float getFluidDensity() const { return _density; }
304       
305       
306        /// Set the wind vector.
307        inline void setWind(const osg::Vec3& wind) { _wind = wind; }
308       
309        /// Get the wind vector.
310        inline const osg::Vec3& getWind() const { return _wind; }
311       
312        /// Set the acceleration vector.
313        inline void setAcceleration(const osg::Vec3& v) { _acceleration = v; }
314       
315        /// Get the acceleration vector.
316        inline const osg::Vec3& getAcceleration() const { return _acceleration; }
317
318        /** Set the acceleration vector to the gravity on earth (0, 0, -9.81).
319            The acceleration will be multiplied by the <CODE>scale</CODE> parameter.
320        */
321        inline void setToGravity(float scale = 1.0f) { _acceleration.set(0, 0, -9.81f*scale); }
322
323        /// Set the fluid parameters as for air (20°C temperature).
324        inline void setFluidToAir()
325        {
326            setToGravity(1.0f);
327            setFluidDensity(1.2929f);
328            setFluidViscosity(1.8e-5f);
329        }
330       
331        /// Set the fluid parameters as for pure water (20°C temperature).
332        inline void setFluidToWater()
333        {
334            setToGravity(1.0f);
335            setFluidDensity(1.0f);
336            setFluidViscosity(1.002e-3f);
337        }
338           
339
340    protected:
341
342        osg::Vec3   _acceleration;
343        float       _viscosity;
344        float       _density;
345        osg::Vec3   _wind;
346
347        float       _viscosityCoefficient;
348        float       _densityCoefficeint;
349 
350};
351
352CatchableObject::CatchableObject()
353{
354    _stopped = false;
355    _dangerous = false;
356   
357    _timeToRemove = -1.0; // do not remove.
358    setFluidToAir();
359}
360
361void CatchableObject::setObject(const std::string& filename, const std::string& name, const osg::Vec3& center, float characterSize, const osg::Vec3& velocity)
362{
363    _radius = 0.5f*characterSize;
364    float Area = osg::PI*_radius*_radius;
365    float Volume = Area*_radius*4.0f/3.0f;
366
367    _velocity = velocity;
368    _mass = 1000.0*Volume;
369
370    osg::Image* image = osgDB::readImageFile(filename);
371    if (image)
372    {
373        osg::Vec3 width(characterSize*((float)image->s())/(float)(image->t()),0.0f,0.0);
374        osg::Vec3 height(0.0f,0.0f,characterSize);
375        osg::Vec3 pos = (width+height)*-0.5f;
376
377        osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height);
378        osg::StateSet* stateset = geometry->getOrCreateStateSet();
379        stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON);
380        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
381        stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
382
383        osg::Geode* geode = new osg::Geode;
384        geode->addDrawable(geometry);
385
386        _object = new osg::PositionAttitudeTransform;
387        _object->setName(name);
388        _object->addChild(geode);
389        _object->setPosition(center);
390    }
391
392}
393
394void CatchableObject::update(double dt)
395{
396    if (_stopped) return;
397
398    float Area = osg::PI*_radius*_radius;
399    float Volume = Area*_radius*4.0f/3.0f;
400
401    // compute force due to gravity + boyancy of displacing the fluid that the particle is emersed in.
402    osg::Vec3 force = _acceleration * (_mass - _density*Volume);
403
404    // compute force due to friction
405    osg::Vec3 relative_wind = _velocity-_wind;           
406    force -= relative_wind * Area * (_viscosityCoefficient + _densityCoefficeint*relative_wind.length());           
407
408    // divide force by mass to get acceleration.
409    _velocity += force*(dt/_mass);
410    _object->setPosition(_object->getPosition()+_velocity*dt);
411}
412
413bool CatchableObject::anyInside(const osg::Vec3& lower_left, const osg::Vec3& upper_right)
414{
415    osg::Vec3 pos = _object->getPosition();
416   
417    if (pos.x()+_radius < lower_left.x()) return false;
418    if (pos.x()-_radius > upper_right.x()) return false;
419    if (pos.z()+_radius < lower_left.z()) return false;
420    if (pos.z()-_radius > upper_right.z()) return false;
421
422    return true;
423}
424
425bool CatchableObject::centerInside(const osg::Vec3& center, float radius)
426{
427    osg::Vec3 delta = _object->getPosition() - center;
428    return (delta.length()<radius);
429}
430
431
432void CatchableObject::explode()
433{
434    osg::Vec3 position(0.0f,0.0f,0.0f);
435    osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, _radius);
436    osgParticle::ExplosionDebriEffect* explosionDebri = new osgParticle::ExplosionDebriEffect(position, _radius);
437    osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, _radius);
438    osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, _radius);
439
440    explosion->setWind(_wind);
441    explosionDebri->setWind(_wind);
442    smoke->setWind(_wind);
443    fire->setWind(_wind);
444
445    _object->addChild(explosion);
446    _object->addChild(explosionDebri);
447    _object->addChild(smoke);
448    _object->addChild(fire);
449
450    _dangerous = true;
451
452}
453
454
455
456//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
457//
458class GameEventHandler : public osgGA::GUIEventHandler
459{
460public:
461
462    GameEventHandler();
463   
464    META_Object(osgStereImageApp,GameEventHandler);
465
466    virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); }
467
468    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
469   
470    virtual void getUsage(osg::ApplicationUsage& usage) const;
471   
472    osg::Matrix getCameraPosition();
473   
474    osg::Node* createScene();
475   
476    void setFOVY(float fovy) { _fovy = fovy; }
477    float getFOVY() const { return _fovy; }
478   
479    void setBackground(const std::string& background) { _backgroundImageFile = background; }
480   
481    void createNewCatchable();
482
483protected:
484
485    ~GameEventHandler() {}
486    GameEventHandler(const GameEventHandler&,const osg::CopyOp&) {}
487
488    osg::Vec3 _origin;
489    osg::Vec3 _width;
490    osg::Vec3 _height;
491    osg::Vec3 _originBaseLine;
492    osg::Vec3 _widthBaseLine;
493    float     _characterSize;
494   
495    float _fovy;
496   
497    std::string _backgroundImageFile;
498
499    osg::ref_ptr<osg::Group> _group;
500   
501    Character _player1;
502    Character _player2;
503
504    typedef std::list< osg::ref_ptr<CatchableObject> > CatchableObjectList;
505    CatchableObjectList _catchableObjects;
506
507    bool _leftKeyPressed;
508    bool _rightKeyPressed;   
509       
510};
511
512
513
514
515GameEventHandler::GameEventHandler()
516{
517    _origin.set(0.0f,0.0f,0.0f);
518    _width.set(1280.0f,0.0f,0.0f);
519    _height.set(0.0f,0.0f,1024.0f);
520    _widthBaseLine = _width*0.9f;
521    _originBaseLine = _origin+_width*0.5-_widthBaseLine*0.5f;
522    _characterSize = _width.length()*0.2f;
523
524    _backgroundImageFile = "Catch/sky1.JPG";
525
526    _leftKeyPressed=false;
527    _rightKeyPressed=false;
528}
529
530bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
531{
532    switch(ea.getEventType())
533    {
534        case(osgGA::GUIEventAdapter::FRAME):
535        {
536            // move characters
537            if (_leftKeyPressed)
538            {
539                _player2.moveLeft();
540            }
541           
542            if (_rightKeyPressed)
543            {
544                _player2.moveRight();
545            }
546
547            static double previous_time = ea.time();
548            double dt = ea.time()-previous_time;
549            previous_time = ea.time();
550           
551            // move objects
552            for(CatchableObjectList::iterator itr=_catchableObjects.begin();
553                itr!=_catchableObjects.end();
554                ++itr)
555            {
556                (*itr)->update(dt);
557               
558                bool removeEntry = false;
559
560                if ((*itr)->dangerous())
561                {
562                    if ((*itr)->anyInside(_player1.getLowerLeft(),_player1.getUpperRight()))
563                    {
564                        _player1.looseLife();
565                        removeEntry = true;
566                    }
567
568                    if ((*itr)->anyInside(_player2.getLowerLeft(),_player2.getUpperRight()))
569                    {
570                        _player2.looseLife();
571                        removeEntry = true;
572                    }
573                }
574                else
575                {
576                    if ((*itr)->centerInside(_player1.getCurrentCenterOfBasket(),_player1.getCurrentRadiusOfBasket()))
577                    {
578                        _player1.addCatch();
579                        removeEntry = true;
580                    }
581
582                    if ((*itr)->centerInside(_player2.getCurrentCenterOfBasket(),_player2.getCurrentRadiusOfBasket()))
583                    {
584                        _player2.addCatch();
585                        removeEntry = true;
586                    }
587                }
588
589
590                if (!(*itr)->anyInside(_origin, _origin+_width+_height) ||
591                    (*itr)->needToRemove(ea.time()) ||
592                    removeEntry)
593                {
594                    // need to remove
595                    // remove child from parents.
596                    osg::ref_ptr<osg::PositionAttitudeTransform> child = (*itr)->_object;
597                    osg::Node::ParentList parents = child->getParents();
598                    for(osg::Node::ParentList::iterator pitr=parents.begin();
599                        pitr!=parents.end();
600                        ++pitr)
601                    {
602                        (*pitr)->removeChild(child.get());
603                    }
604
605                    // remove child from catchable list
606                    itr = _catchableObjects.erase(itr);
607
608                    createNewCatchable();
609
610                }
611                else if ((*itr)->anyInside(_origin, _origin+_width) && !(*itr)->stopped())
612                {
613                    // hit base line
614                    (*itr)->explode();
615                    (*itr)->stop();
616                    (*itr)->setTimeToRemove(ea.time()+3.0);
617                }
618               
619            }
620                   
621        }
622        case(osgGA::GUIEventAdapter::KEYDOWN):
623        {
624            if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left)
625            {
626                _leftKeyPressed=true;
627                return true;
628            }
629            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right)
630            {
631                _rightKeyPressed=true;
632                return true;
633            }
634            else if (ea.getKey()=='1')
635            {
636                _player1.looseLife();
637                _player1.addCatch();
638                return true;
639            }
640            else if (ea.getKey()=='2')
641            {
642                _player2.looseLife();
643                _player2.addCatch();
644                return true;
645            }
646            else if (ea.getKey()==' ')
647            {
648                _player1.reset();
649                _player2.reset();
650                return true;
651            }
652        }
653        case(osgGA::GUIEventAdapter::KEYUP):
654        {
655            if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left)
656            {
657                _leftKeyPressed=false;
658                return true;
659            }
660            else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right)
661            {
662                _rightKeyPressed=false;
663                return true;
664            }
665        }
666        case(osgGA::GUIEventAdapter::DRAG):
667        case(osgGA::GUIEventAdapter::MOVE):
668        {
669            float px = (ea.getXnormalized()+1.0f)*0.5f;
670
671            _player1.moveTo(px);
672
673            return true;
674        }
675
676        default:
677            return false;
678    }
679}
680
681void GameEventHandler::getUsage(osg::ApplicationUsage&) const
682{
683}
684
685osg::Matrix GameEventHandler::getCameraPosition()
686{
687    osg::Matrix cameraPosition;
688    osg::Vec3 center = _origin+(_width+_height)*0.5f;
689   
690    float distance = _height.length()/(2.0f*tanf(_fovy*0.5f));
691   
692    cameraPosition.makeLookAt(center-osg::Vec3(0.0f,distance,0.0f),center,osg::Vec3(0.0f,0.0f,1.0f));
693    return cameraPosition;
694}
695
696osg::Node* GameEventHandler::createScene()
697{
698    _group = new osg::Group;
699   
700//    _player1.setCharacter("Catch/girl.png","girl", _originBaseLine, _widthBaseLine, 0.4f);
701    _player1.setCharacter("Catch/gwen.png","girl", _originBaseLine + osg::Vec3(0.0f,-1.0f,0.0f), _widthBaseLine, 0.4f);
702    _player1.setLives("Catch/gwen.png",_originBaseLine+osg::Vec3(0.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),3);
703    _player1.setCatches("Catch/broach.png",_originBaseLine+osg::Vec3(200.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10);
704    _group->addChild(_player1._character.get());
705    _group->addChild(_player1._livesSwitch.get());
706    _group->addChild(_player1._catchSwitch.get());
707
708//    _player2.setCharacter("Catch/boy.png","boy", _originBaseLine, _widthBaseLine, 0.4f);
709//    _player2.setLives("Catch/boy.png",_originBaseLine+osg::Vec3(900.0f,0.0f,000.0f), osg::Vec3(0.0f,0.0f,100.0f),3);
710    _player2.setCharacter("Catch/caitlin.png","boy", _originBaseLine + osg::Vec3(0.0f,-2.0f,0.0f), _widthBaseLine, 0.4f);
711    _player2.setLives("Catch/caitlin.png",_originBaseLine+osg::Vec3(900.0f,-0.5f,000.0f), osg::Vec3(0.0f,0.0f,100.0f),3);
712    _player2.setCatches("Catch/broach.png",_originBaseLine+osg::Vec3(1100.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10);
713    _group->addChild(_player2._character.get());
714    _group->addChild(_player2._livesSwitch.get());
715    _group->addChild(_player2._catchSwitch.get());
716   
717   
718    createNewCatchable();
719    createNewCatchable();
720    createNewCatchable();
721    createNewCatchable();
722
723    // background
724    {
725        osg::Image* image = osgDB::readImageFile(_backgroundImageFile);
726        if (image)
727        {
728            osg::Geometry* geometry = osg::createTexturedQuadGeometry(_origin,_width,_height);
729            osg::StateSet* stateset = geometry->getOrCreateStateSet();
730            stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON);
731           
732            osg::Geode* geode = new osg::Geode;
733            geode->addDrawable(geometry);
734
735            _group->addChild(geode);
736           
737        }
738    }
739
740    return _group.get();
741}
742
743void GameEventHandler::createNewCatchable()
744{
745    float ratio = ((float)rand() / (float)RAND_MAX);
746    float size = 100.0f*((float)rand() / (float)RAND_MAX);
747    float angle = osg::PI*0.25f + 0.5f*osg::PI*((float)rand() / (float)RAND_MAX);
748    float speed = 200.0f*((float)rand() / (float)RAND_MAX);
749
750    CatchableObject* catchableObject = new CatchableObject;
751    osg::Vec3 position = _origin+_height+_width*ratio + osg::Vec3(0.0f,-0.7f,0.0f);
752    osg::Vec3 velocity(-cosf(angle)*speed,0.0f,-sinf(angle)*speed);
753    //std::cout<<"angle = "<<angle<<" velocity="<<velocity<<std::endl;
754    catchableObject->setObject("Catch/a.png","boy",position,size,velocity);
755    _catchableObjects.push_back(catchableObject);
756
757    // catchableObject->explode();
758
759    _group->addChild(catchableObject->_object.get());
760}
761
762int main( int argc, char **argv )
763{
764
765    // use an ArgumentParser object to manage the program arguments.
766    osg::ArgumentParser arguments(&argc,argv);
767   
768    // set up the usage document, in case we need to print out how to use this program.
769    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use node masks to create stereo images.");
770    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
771    arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time delay in sceonds between the display of successive image pairs when in auto advance mode.");
772    arguments.getApplicationUsage()->addCommandLineOption("-a","Enter auto advance of image pairs on start up.");
773    arguments.getApplicationUsage()->addCommandLineOption("-x <float>","Horizontal offset of left and right images.");
774    arguments.getApplicationUsage()->addCommandLineOption("-y <float>","Vertical offset of left and right images.");
775    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
776   
777
778    // construct the viewer.
779    osgProducer::Viewer viewer(arguments);
780
781    // set up the value with sensible default event handlers.
782    viewer.setUpViewer(osgProducer::Viewer::ESCAPE_SETS_DONE);
783
784    // register the handler to add keyboard and mosue handling.
785    GameEventHandler* seh = new GameEventHandler();
786    viewer.getEventHandlerList().push_front(seh);
787
788    std::string filename;
789    if (arguments.read("-b",filename))
790    {
791        seh->setBackground(filename);
792    }
793
794
795    // get details on keyboard and mouse bindings used by the viewer.
796    viewer.getUsage(*arguments.getApplicationUsage());
797
798    // if user request help write it out to cout.
799    if (arguments.read("-h") || arguments.read("--help"))
800    {
801        arguments.getApplicationUsage()->write(std::cout);
802        return 1;
803    }
804
805    // any option left unread are converted into errors to write out later.
806    arguments.reportRemainingOptionsAsUnrecognized();
807
808    // report any errors if they have occured when parsing the program aguments.
809    if (arguments.errors())
810    {
811        arguments.writeErrorMessages(std::cout);
812        return 1;
813    }
814   
815    // now the windows have been realized we switch off the cursor to prevent it
816    // distracting the people seeing the stereo images.
817    float fovy = 1.0f;
818    for( unsigned int i = 0; i < viewer.getCameraConfig()->getNumberOfCameras(); i++ )
819    {
820        Producer::Camera* cam = viewer.getCameraConfig()->getCamera(i);
821        Producer::RenderSurface* rs = cam->getRenderSurface();
822        rs->useCursor(false);
823        fovy = osg::DegreesToRadians(cam->getLensVerticalFov());
824    }
825   
826    seh->setFOVY(fovy);
827   
828    // creat the scene from the file list.
829    osg::ref_ptr<osg::Node> rootNode = seh->createScene();
830
831    osgDB::writeNodeFile(*rootNode,"test.osg");
832
833    // set the scene to render
834    viewer.setSceneData(rootNode.get());
835
836    // create the windows and run the threads.
837    viewer.realize();
838   
839    viewer.requestWarpPointer(0.5f,0.5f);
840       
841
842    while( !viewer.done() )
843    {
844        // wait for all cull and draw threads to complete.
845        viewer.sync();
846
847        // update the scene by traversing it with the the update visitor which will
848        // call all node update callbacks and animations.
849        viewer.update();
850         
851        viewer.setView(seh->getCameraPosition());
852
853        // fire off the cull and draw traversals of the scene.
854        viewer.frame();
855       
856    }
857   
858    // wait for all cull and draw threads to complete before exit.
859    viewer.sync();
860   
861    return 0;
862}
Note: See TracBrowser for help on using the browser.