root/OpenSceneGraph/trunk/examples/osglauncher/osglauncher.cpp @ 13837

Revision 13376, 13.2 kB (checked in by robert, 12 hours ago)

Changed the osgUI behaviour so that events are set to be handled by Widgets that have focus even if they don't directly use them.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osglauncher.
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 <cstdio>
20//#include <cstdlib>
21#include <iostream>
22#include <list>
23#include <string>
24#include <sstream>
25
26#include <osg/Geode>
27#include <osg/ShapeDrawable>
28#include <osg/Material>
29#include <osg/Texture2D>
30#include <osg/Geometry>
31#include <osg/MatrixTransform>
32#include <osg/PositionAttitudeTransform>
33#include <osg/BlendFunc>
34#include <osg/ClearNode>
35#include <osg/Depth>
36#include <osg/Projection>
37#include <osg/io_utils>
38
39#include <osgUtil/CullVisitor>
40#include <osgUtil/Optimizer>
41
42#include <osgText/Text>
43
44#include <osgGA/TrackballManipulator>
45
46#include <osgViewer/Viewer>
47
48#include <osgDB/ReadFile>
49#include <osgDB/FileUtils>
50#include <osgDB/fstream>
51
52int runApp(std::string xapp);
53
54// class to handle events with a pick
55class PickHandler : public osgGA::GUIEventHandler {
56public:
57
58    PickHandler(osgViewer::Viewer* viewer,osgText::Text* updateText):
59        _viewer(viewer),
60        _updateText(updateText) {}
61       
62    ~PickHandler() {}
63   
64    bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
65
66    std::string pick(const osgGA::GUIEventAdapter& event);
67   
68    void highlight(const std::string& name)
69    {
70        if (_updateText.get()) _updateText->setText(name);
71    }
72   
73protected:
74
75    osgViewer::Viewer* _viewer;
76    osg::ref_ptr<osgText::Text>  _updateText;
77};
78
79bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
80{
81    switch(ea.getEventType())
82    {
83    case(osgGA::GUIEventAdapter::FRAME):
84    case(osgGA::GUIEventAdapter::MOVE):
85    {
86        // osg::notify(osg::NOTICE)<<"MOVE "<<ea.getX()<<", "<<ea.getY()<<std::endl;
87        std::string picked_name = pick(ea);
88        highlight(picked_name);
89        return false;
90    }
91    case(osgGA::GUIEventAdapter::PUSH):
92    {
93        // osg::notify(osg::NOTICE)<<"PUSH "<<ea.getX()<<", "<<ea.getY()<<std::endl;
94        std::string picked_name = pick(ea);
95        if (!picked_name.empty())
96        {
97            runApp(picked_name);
98            return true;
99        }
100        else
101        {
102            return false;
103        }
104    }
105    default:
106        return false;
107    }
108}
109
110
111std::string PickHandler::pick(const osgGA::GUIEventAdapter& event)
112{
113    osgUtil::LineSegmentIntersector::Intersections intersections;
114    if (_viewer->computeIntersections(event, intersections))
115    {
116        for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
117            hitr != intersections.end();
118            ++hitr)
119        {
120            osg::Node* node = hitr->nodePath.empty() ? 0 : hitr->nodePath.back();
121            if (node && !node->getName().empty()) return node->getName();
122        }
123    }
124
125    return "";
126}
127
128osg::Node* createHUD(osgText::Text* updateText)
129{    // create the hud. derived from osgHud.cpp
130    // adds a set of quads, each in a separate Geode - which can be picked individually
131    // eg to be used as a menuing/help system!
132    // Can pick texts too!
133    osg::MatrixTransform* modelview_abs = new osg::MatrixTransform;
134    modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
135    modelview_abs->setMatrix(osg::Matrix::identity());
136   
137    osg::Projection* projection = new osg::Projection;
138    projection->setMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
139    projection->addChild(modelview_abs);
140   
141   
142    std::string timesFont("fonts/times.ttf");
143   
144    // turn lighting off for the text and disable depth test to ensure its always ontop.
145    osg::Vec3 position(50.0f,510.0f,0.0f);
146    osg::Vec3 delta(0.0f,-60.0f,0.0f);
147
148    { // this displays what has been selected
149        osg::Geode* geode = new osg::Geode();
150        osg::StateSet* stateset = geode->getOrCreateStateSet();
151        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
152        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
153        geode->setName("The text label");
154        geode->addDrawable( updateText );
155        modelview_abs->addChild(geode);
156       
157        updateText->setCharacterSize(20.0f);
158        updateText->setFont(timesFont);
159        updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
160        updateText->setText("");
161        updateText->setPosition(position);
162       
163        position += delta;
164    }   
165   
166    return projection;
167
168} // end create HUDf
169
170
171
172
173static osg::Vec3 defaultPos( 0.0f, 0.0f, 0.0f );
174static osg::Vec3 centerScope(0.0f, 0.0f, 0.0f);
175
176class Xample
177{
178    std::string texture;
179    std::string app;
180  public:
181      Xample(std::string image, std::string prog)
182    {
183        texture    = image;
184        app     = prog;
185        osg::notify(osg::INFO) << "New Xample!" << std::endl;
186    };
187    ~Xample() { };
188   
189    std::string getTexture()
190    {
191        return texture;
192    }
193    std::string getApp()
194    {
195        return app;
196    }
197  private:
198      Xample() {}
199}; // end class Xample
200
201
202typedef std::list<Xample>::iterator OP;
203static std::list<Xample> Xamplelist;
204
205
206void printList()
207{
208    osg::notify(osg::INFO) << "start printList()" << std::endl;
209    for (OP i = Xamplelist.begin() ; i != Xamplelist.end() ; ++i)
210    {
211        Xample& x = *i;
212        osg::notify(osg::INFO) << "current x.texture = " << x.getTexture() << std::endl;
213        osg::notify(osg::INFO) << "current x.app = " << x.getApp() << std::endl;
214    }
215    osg::notify(osg::INFO) << "end printList()" << std::endl;
216} // end printList()
217
218
219int runApp(std::string xapp)
220{
221    osg::notify(osg::INFO) << "start runApp()" << std::endl;
222    for (OP i = Xamplelist.begin() ; i != Xamplelist.end() ; ++i)
223    {
224        Xample& x = *i;
225        if(!xapp.compare(x.getApp()))
226        {
227            osg::notify(osg::INFO) << "app found!" << std::endl;
228           
229            const char* cxapp = xapp.c_str();
230           
231            osg::notify(osg::INFO) << "char* = " << cxapp <<std::endl;
232           
233            return system(cxapp);
234        }
235    }
236    osg::notify(osg::INFO) << "app not found!" << std::endl;
237    return 1;
238} // end printList()
239
240
241void readConfFile(const char* confFile)                                                                // read confFile            1
242{
243    osg::notify(osg::INFO) << "Start reading confFile" << std::endl;
244   
245    std::string fileName = osgDB::findDataFile(confFile);
246    if (fileName.empty())
247    {
248        osg::notify(osg::INFO) << "Config file not found"<<confFile << std::endl;
249        return;
250    }
251   
252
253    osgDB::ifstream in(fileName.c_str());
254    if (!in)
255    {
256        osg::notify(osg::INFO) << "File " << fileName << " can not be opened!" << std::endl;
257        exit(1);
258    }
259    std::string imageBuffer;
260    std::string appBuffer;
261   
262    while (!in.eof())
263    {
264        std::getline(in, imageBuffer);
265        std::getline(in, appBuffer);
266        if(imageBuffer == "" || appBuffer == "");
267        else
268        {
269            osg::notify(osg::INFO) << "imageBuffer: " << imageBuffer << std::endl;
270            osg::notify(osg::INFO) << "appBuffer: " << appBuffer << std::endl;
271//            jeweils checken ob image vorhanden ist.
272           
273            Xample tmp(imageBuffer, appBuffer);                                                    // create Xample objects    2
274           
275            Xamplelist.push_back(tmp);                                                            // store objects in list    2
276           
277        }
278    }
279   
280    in.close();
281   
282    osg::notify(osg::INFO) << "End reading confFile" << std::endl;
283   
284    printList();
285} // end readConfFile
286
287
288void SetObjectTextureState(osg::Geode *geodeCurrent, std::string texture)
289{
290    // retrieve or create a StateSet
291    osg::StateSet* stateTexture = geodeCurrent->getOrCreateStateSet();
292
293    // load texture.jpg as an image
294    osg::Image* imgTexture = osgDB::readImageFile( texture );
295   
296    // if the image is successfully loaded
297    if (imgTexture)
298    {
299        // create a new two-dimensional texture object
300        osg::Texture2D* texCube = new osg::Texture2D;
301
302        // set the texture to the loaded image
303        texCube->setImage(imgTexture);
304
305        // set the texture to the state
306        stateTexture->setTextureAttributeAndModes(0,texCube,osg::StateAttribute::ON);
307
308        // set the state of the current geode
309        geodeCurrent->setStateSet(stateTexture);
310    }
311} // end SetObjectTextureState
312
313
314osg::Geode* createTexturedCube(float fRadius,osg::Vec3 vPosition, std::string texture, std::string geodeName)
315{
316    // create a cube shape
317    osg::Box *bCube = new osg::Box(vPosition,fRadius);
318    // osg::Box *bCube = new osg::Box(vPosition,fRadius);
319
320    // create a container that makes the cube drawable
321    osg::ShapeDrawable *sdCube = new osg::ShapeDrawable(bCube);
322
323    // create a geode object to as a container for our drawable cube object
324    osg::Geode* geodeCube = new osg::Geode();
325    geodeCube->setName( geodeName );
326
327    // set the object texture state
328    SetObjectTextureState(geodeCube, texture);
329
330    // add our drawable cube to the geode container
331    geodeCube->addDrawable(sdCube);
332
333    return(geodeCube);
334} // end CreateCube
335
336
337osg::PositionAttitudeTransform* getPATransformation(osg::Node* object, osg::Vec3 position, osg::Vec3 scale, osg::Vec3 pivot)
338{
339    osg::PositionAttitudeTransform* tmpTrans = new osg::PositionAttitudeTransform();
340    tmpTrans->addChild( object );
341   
342    tmpTrans->setPosition( position );
343    tmpTrans->setScale( scale );
344    tmpTrans->setPivotPoint( pivot );
345   
346    return tmpTrans;
347}
348
349void printBoundings(osg::Node* current, std::string name)
350{
351    const osg::BoundingSphere& currentBound = current->getBound();
352    osg::notify(osg::INFO) << name << std::endl;
353    osg::notify(osg::INFO) << "center = " << currentBound.center() << std::endl;
354    osg::notify(osg::INFO) << "radius = " << currentBound.radius() << std::endl;
355   
356//    return currentBound.radius();
357}
358
359
360osg::Group* setupGraph()                                                                        // create Geodes/Nodes from Xamplelist    3
361{
362    osg::Group* xGroup = new osg::Group();
363
364   
365//    positioning and sizes
366    float defaultRadius = 0.8f;
367
368    int itemsInLine    = 4;                                    // name says everything
369    float offset    = 0.05f;
370    float bs        = (defaultRadius / 4) + offset;
371    float xstart    = (3*bs) * (-1);
372    float zstart    = xstart * (-1);
373    float xnext        = xstart;
374    float znext        = zstart;
375    float xjump        = (2*bs);
376    float zjump        = xjump;
377    osg::Vec3 vScale( 0.5f, 0.5f, 0.5f );
378    osg::Vec3 vPivot( 0.0f, 0.0f, 0.0f );   
379
380//  run through Xampleliste
381    int z = 1;
382    for (OP i = Xamplelist.begin() ; i != Xamplelist.end() ; ++i, ++z)
383    {
384        Xample& x = *i;
385       
386        osg::Node* tmpCube = createTexturedCube(defaultRadius, defaultPos, x.getTexture(), x.getApp());
387        printBoundings(tmpCube, x.getApp());
388        osg::Vec3 vPosition( xnext, 0.0f, znext );
389        osg::PositionAttitudeTransform*    transX = getPATransformation(tmpCube, vPosition, vScale, vPivot);
390        xGroup->addChild( transX );
391       
392        // line feed
393        if(z < itemsInLine)
394            xnext += xjump;
395        else
396        {
397            xnext = xstart;
398            znext -= zjump;
399            z = 0;
400        }
401    } // end run through list   
402   
403    return xGroup;
404} // end setupGraph
405
406
407int main( int argc, char **argv )
408{
409    if (argc<=1)
410    {
411        readConfFile("osg.conf");                                                                          // read ConfigFile        1
412    }
413    else
414    {
415        readConfFile(argv[1]);                                                                          // read ConfigFile        1
416    }
417   
418    // construct the viewer.
419    osgViewer::Viewer viewer;
420
421    osg::ref_ptr<osgText::Text> updateText = new osgText::Text;
422    updateText->setDataVariance(osg::Object::DYNAMIC);
423
424    // add the handler for doing the picking
425    viewer.addEventHandler(new PickHandler(&viewer,updateText.get()));
426
427    osg::Group* root = new osg::Group();
428
429    root->addChild( setupGraph() );
430
431    // add the HUD subgraph.   
432    root->addChild(createHUD(updateText.get()));
433   
434    // add model to viewer.
435    viewer.setSceneData( root );
436
437    osg::Matrix lookAt;
438    lookAt.makeLookAt(osg::Vec3(0.0f, -4.0f, 0.0f), centerScope, osg::Vec3(0.0f, 0.0f, 1.0f));
439
440    viewer.getCamera()->setViewMatrix(lookAt);
441       
442    viewer.realize();
443
444    while( !viewer.done() )
445    {
446        // fire off the cull and draw traversals of the scene.
447        viewer.frame();       
448    }
449
450    return 0;
451} // end main
Note: See TracBrowser for help on using the browser.