root/OpenSceneGraph/trunk/examples/osgmanipulator/osgmanipulator.cpp @ 6277

Revision 6277, 12.5 kB (checked in by robert, 10 years ago)

Completed changes to osgManipulator to make it more flexible w.r.t viewer usage, and
ported osgmanipulator example across of osgViewer

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// --c++--
2#include <osgDB/ReadFile>
3#include <osgUtil/Optimizer>
4#include <osgViewer/Viewer>
5#include <osg/CoordinateSystemNode>
6#include <osgText/Text>
7
8#include <osgManipulator/CommandManager>
9#include <osgManipulator/TabBoxDragger>
10#include <osgManipulator/TabPlaneDragger>
11#include <osgManipulator/TabPlaneTrackballDragger>
12#include <osgManipulator/TrackballDragger>
13#include <osgManipulator/Translate1DDragger>
14#include <osgManipulator/Translate2DDragger>
15#include <osgManipulator/TranslateAxisDragger>
16
17#include <iostream>
18
19osgManipulator::Dragger* createDragger(const std::string& name)
20{
21    osgManipulator::Dragger* dragger = 0;
22    if ("TabPlaneDragger" == name)
23    {
24        osgManipulator::TabPlaneDragger* d = new osgManipulator::TabPlaneDragger();
25        d->setupDefaultGeometry();
26        dragger = d;
27    }
28    else if ("TabPlaneTrackballDragger" == name)
29    {
30        osgManipulator::TabPlaneTrackballDragger* d = new osgManipulator::TabPlaneTrackballDragger();
31        d->setupDefaultGeometry();
32        dragger = d;
33    }
34    else if ("TrackballDragger" == name)
35    {
36        osgManipulator::TrackballDragger* d = new osgManipulator::TrackballDragger();
37        d->setupDefaultGeometry();
38        dragger = d;
39    }
40    else if ("Translate1DDragger" == name)
41    {
42        osgManipulator::Translate1DDragger* d = new osgManipulator::Translate1DDragger();
43        d->setupDefaultGeometry();
44        dragger = d;
45    }
46    else if ("Translate2DDragger" == name)
47    {
48        osgManipulator::Translate2DDragger* d = new osgManipulator::Translate2DDragger();
49        d->setupDefaultGeometry();
50        dragger = d;
51    }
52    else if ("TranslateAxisDragger" == name)
53    {
54        osgManipulator::TranslateAxisDragger* d = new osgManipulator::TranslateAxisDragger();
55        d->setupDefaultGeometry();
56        dragger = d;
57    }
58    else
59    {
60        osgManipulator::TabBoxDragger* d = new osgManipulator::TabBoxDragger();
61        d->setupDefaultGeometry();
62        dragger = d;
63    }
64 
65    return dragger;
66}
67
68osg::Node* createHUD()
69{
70    osg::Geode* geode = new osg::Geode();
71   
72    std::string timesFont("fonts/arial.ttf");
73
74    osg::StateSet* stateset = geode->getOrCreateStateSet();
75    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
76
77    osgText::Text* text = new  osgText::Text;
78    geode->addDrawable( text );
79
80    osg::Vec3 position(50.0f,50.0f,0.0f);
81    text->setPosition(position);
82    text->setText("Use the Tab key to switch between the trackball and pick modes.");
83    text->setFont(timesFont);
84
85    osg::Camera* camera = new osg::Camera;
86
87    // set the projection matrix
88    camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024));
89
90    // set the view matrix   
91    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
92    camera->setViewMatrix(osg::Matrix::identity());
93
94    // only clear the depth buffer
95    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
96
97    // draw subgraph after main camera view.
98    camera->setRenderOrder(osg::Camera::POST_RENDER);
99
100    camera->addChild(geode);
101   
102    return camera;
103}
104
105#if 0
106bool computePixelCoords(osgProducer::Viewer* viewer,float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y)
107{
108    Producer::KeyboardMouse* km = viewer->getKeyboardMouse();
109    if (!km) return false;
110           
111    if (cameraNum>=viewer->getNumberOfCameras()) return false;
112
113    Producer::Camera* camera=viewer->getCamera(cameraNum);
114    Producer::RenderSurface* rs = camera->getRenderSurface();
115
116    Producer::InputArea* inputArea = km->getInputArea();
117    if( inputArea != NULL )
118    {
119        // first locate which InputRectange is appropriate for specified RenderSurface.
120        unsigned int i;
121        for(i=0;i<inputArea->getNumRenderSurfaces();++i)
122        {
123            if (inputArea->getRenderSurface(i)==rs) break;
124        }
125       
126        // the RenderSurface isn't in the InputArea list.. therefore cannot make mouse coords to it.
127        if (i==inputArea->getNumRenderSurfaces()) return false;
128
129        // we have a valid InputRectangle
130        Producer::RenderSurface::InputRectangle ir = inputArea->getRenderSurface(i)->getInputRectangle();
131
132        float rx = (x-ir.left())/ir.width();
133        float ry = (y-ir.bottom())/ir.height();
134       
135        int wx, wy;
136        unsigned int w, h;
137        rs->getWindowRectangle( wx, wy, w, h );
138
139        pixel_x = ((float)w)* rx;
140        pixel_y = ((float)h)* ry;
141    }
142    else
143    {
144        float rx = (x+1.0f)*0.5f;
145        float ry = (y+1.0f)*0.5f;
146
147        int wx, wy;
148        unsigned int w, h;
149        rs->getWindowRectangle( wx, wy, w, h );
150
151        pixel_x = ((float)w)* rx;
152        pixel_y = ((float)h)* ry;
153    }
154    return true;
155}
156#endif
157
158osg::Node* addDraggerToScene(osg::Node* scene, osgManipulator::CommandManager* cmdMgr, const std::string& name)
159{
160    scene->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
161
162    osgManipulator::Selection* selection = new osgManipulator::Selection;
163    selection->addChild(scene);
164
165    osgManipulator::Dragger* dragger = createDragger(name);
166
167    osg::Group* root = new osg::Group;
168    root->addChild(dragger);
169    root->addChild(selection);
170    root->addChild(createHUD());
171
172    float scale = scene->getBound().radius() * 1.6;
173    dragger->setMatrix(osg::Matrix::scale(scale, scale, scale) *
174                       osg::Matrix::translate(scene->getBound().center()));
175    cmdMgr->connect(*dragger, *selection);
176
177    return root;
178}
179
180class PickModeHandler : public osgGA::GUIEventHandler
181{
182    public:
183        enum Modes
184        {
185            VIEW = 0,
186            PICK
187        };
188
189        PickModeHandler():
190            _mode(VIEW),
191            _activeDragger(0)
192        {
193        }       
194       
195        bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa,
196                    osg::Object*, osg::NodeVisitor*)
197        {
198            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
199            if (!view) return false;
200
201            if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Tab &&
202                ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN &&
203                _activeDragger == 0)
204            {
205                _mode = ! _mode;
206            }
207           
208            if (VIEW == _mode) return false;
209
210            switch (ea.getEventType())
211            {
212                case osgGA::GUIEventAdapter::PUSH:
213                {
214                    osgUtil::LineSegmentIntersector::Intersections intersections;
215
216                    _pointer.reset();
217
218                    if (view->computeIntersections(ea.getX(),ea.getY(),intersections))
219                    {
220                        _pointer.setCamera(view->getCamera());
221                        _pointer.setMousePosition(ea.getX(), ea.getY());
222
223                        for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
224                            hitr != intersections.end();
225                            ++hitr)
226                        {
227                            _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
228                        }
229                        for (osg::NodePath::iterator itr = _pointer._hitList.front().first.begin();
230                             itr != _pointer._hitList.front().first.end();
231                             ++itr)
232                        {
233                            osgManipulator::Dragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*itr);
234                            if (dragger)
235                            {
236
237                                dragger->handle(_pointer, ea, aa);
238                                _activeDragger = dragger;
239                                break;
240                            }                   
241                        }
242                    }
243                }
244                case osgGA::GUIEventAdapter::DRAG:
245                case osgGA::GUIEventAdapter::RELEASE:
246                {
247                    if (_activeDragger)
248                    {
249                        _pointer._hitIter = _pointer._hitList.begin();
250                        _pointer.setCamera(view->getCamera());
251                        _pointer.setMousePosition(ea.getX(), ea.getY());
252
253                        _activeDragger->handle(_pointer, ea, aa);
254                    }
255                    break;
256                }
257                default:
258                    break;
259            }
260
261            if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
262            {
263                _activeDragger = 0;
264                _pointer.reset();
265            }
266
267            return true;
268        }
269       
270    private:
271        unsigned int _mode;
272        osgManipulator::Dragger* _activeDragger;
273        osgManipulator::PointerInfo _pointer;
274};
275
276int main( int argc, char **argv )
277{
278
279    // use an ArgumentParser object to manage the program arguments.
280    osg::ArgumentParser arguments(&argc,argv);
281   
282    // set up the usage document, in case we need to print out how to use this program.
283    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
284    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
285    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
286    arguments.getApplicationUsage()->addCommandLineOption("--image <filename>","Load an image and render it on a quad");
287    arguments.getApplicationUsage()->addCommandLineOption("--dem <filename>","Load an image/DEM and render it on a HeightField");
288    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
289    arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available");
290    arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available");
291    arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindings.");
292
293    arguments.getApplicationUsage()->addCommandLineOption("--dragger <draggername>","Use the specified dragger for manipulation");
294   
295
296    // construct the viewer.
297    osgViewer::Viewer viewer;
298
299    // get details on keyboard and mouse bindings used by the viewer.
300    viewer.getUsage(*arguments.getApplicationUsage());
301
302    // if user request help write it out to cout.
303    bool helpAll = arguments.read("--help-all");
304    unsigned int helpType = ((helpAll || arguments.read("-h") || arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) |
305                            ((helpAll ||  arguments.read("--help-env"))? osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) |
306                            ((helpAll ||  arguments.read("--help-keys"))? osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 );
307    if (helpType)
308    {
309        arguments.getApplicationUsage()->write(std::cout, helpType);
310        return 1;
311    }
312
313    // report any errors if they have occurred when parsing the program arguments.
314    if (arguments.errors())
315    {
316        arguments.writeErrorMessages(std::cout);
317        return 1;
318    }
319   
320    if (arguments.argc()<=1)
321    {
322        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
323        return 1;
324    }
325
326    std::string dragger_name = "TabBoxDragger";
327    arguments.read("--dragger", dragger_name);
328
329    osg::Timer_t start_tick = osg::Timer::instance()->tick();
330
331    // read the scene from the list of file specified command line args.
332    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
333
334    // if no model has been successfully loaded report failure.
335    if (!loadedModel)
336    {
337        std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
338        return 1;
339    }
340
341    // any option left unread are converted into errors to write out later.
342    arguments.reportRemainingOptionsAsUnrecognized();
343
344    // report any errors if they have occurred when parsing the program arguments.
345    if (arguments.errors())
346    {
347        arguments.writeErrorMessages(std::cout);
348    }
349
350    osg::Timer_t end_tick = osg::Timer::instance()->tick();
351
352    std::cout << "Time to load = "<<osg::Timer::instance()->delta_s(start_tick,end_tick)<<std::endl;
353
354
355    // optimize the scene graph, remove redundant nodes and state etc.
356    osgUtil::Optimizer optimizer;
357    optimizer.optimize(loadedModel.get());
358
359    osg::ref_ptr<osgManipulator::CommandManager> cmdMgr = new osgManipulator::CommandManager;
360   
361    // pass the loaded scene graph to the viewer.
362    viewer.setSceneData(addDraggerToScene(loadedModel.get(), cmdMgr.get(), dragger_name));
363
364    viewer.addEventHandler(new PickModeHandler());
365
366    return viewer.run();
367}
Note: See TracBrowser for help on using the browser.