root/OpenSceneGraph/trunk/examples/osgpick/osgpick.cpp @ 13788

Revision 13574, 11.8 kB (checked in by robert, 6 hours 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, osgpick.
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/* osgpick sample
20* demonstrate use of osgUtil/PickVisitor for picking in a HUD or
21* in a 3d scene,
22*/
23
24#include <osgUtil/Optimizer>
25#include <osgDB/ReadFile>
26#include <osgViewer/Viewer>
27#include <osgViewer/CompositeViewer>
28
29#include <osgGA/TerrainManipulator>
30#include <osgGA/StateSetManipulator>
31#include <osgGA/AnimationPathManipulator>
32#include <osgGA/TrackballManipulator>
33#include <osgGA/FlightManipulator>
34#include <osgGA/DriveManipulator>
35#include <osgGA/KeySwitchMatrixManipulator>
36#include <osgGA/StateSetManipulator>
37#include <osgGA/AnimationPathManipulator>
38#include <osgGA/TerrainManipulator>
39
40#include <osg/Material>
41#include <osg/Geode>
42#include <osg/BlendFunc>
43#include <osg/Depth>
44#include <osg/Projection>
45#include <osg/MatrixTransform>
46#include <osg/Camera>
47#include <osg/io_utils>
48#include <osg/ShapeDrawable>
49
50#include <osgText/Text>
51
52#include <sstream>
53
54// class to handle events with a pick
55class PickHandler : public osgGA::GUIEventHandler {
56public:
57
58    PickHandler(osgText::Text* updateText):
59        _updateText(updateText) {}
60
61    ~PickHandler() {}
62
63    bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);
64
65    virtual void pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea);
66
67    void setLabel(const std::string& name)
68    {
69        if (_updateText.get()) _updateText->setText(name);
70    }
71
72protected:
73
74    osg::ref_ptr<osgText::Text>  _updateText;
75};
76
77bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
78{
79    switch(ea.getEventType())
80    {
81        case(osgGA::GUIEventAdapter::PUSH):
82        {
83            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
84            if (view) pick(view,ea);
85            return false;
86        }
87        case(osgGA::GUIEventAdapter::KEYDOWN):
88        {
89            if (ea.getKey()=='c')
90            {
91                osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
92                osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter(ea);
93                event->setX((ea.getXmin()+ea.getXmax())*0.5);
94                event->setY((ea.getYmin()+ea.getYmax())*0.5);
95                if (view) pick(view,*event);
96            }
97            return false;
98        }
99        default:
100            return false;
101    }
102}
103
104void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
105{
106    osgUtil::LineSegmentIntersector::Intersections intersections;
107
108    std::string gdlist="";
109
110    if (view->computeIntersections(ea,intersections))
111    {
112        for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
113            hitr != intersections.end();
114            ++hitr)
115        {
116            std::ostringstream os;
117            if (!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty()))
118            {
119                // the geodes are identified by name.
120                os<<"Object \""<<hitr->nodePath.back()->getName()<<"\""<<std::endl;
121            }
122            else if (hitr->drawable.valid())
123            {
124                os<<"Object \""<<hitr->drawable->className()<<"\""<<std::endl;
125            }
126
127            os<<"        local coords vertex("<< hitr->getLocalIntersectPoint()<<")"<<"  normal("<<hitr->getLocalIntersectNormal()<<")"<<std::endl;
128            os<<"        world coords vertex("<< hitr->getWorldIntersectPoint()<<")"<<"  normal("<<hitr->getWorldIntersectNormal()<<")"<<std::endl;
129            const osgUtil::LineSegmentIntersector::Intersection::IndexList& vil = hitr->indexList;
130            for(unsigned int i=0;i<vil.size();++i)
131            {
132                os<<"        vertex indices ["<<i<<"] = "<<vil[i]<<std::endl;
133            }
134
135            gdlist += os.str();
136        }
137    }
138    setLabel(gdlist);
139}
140
141osg::Node* createHUD(osgText::Text* updateText)
142{
143
144    // create the hud. derived from osgHud.cpp
145    // adds a set of quads, each in a separate Geode - which can be picked individually
146    // eg to be used as a menuing/help system!
147    // Can pick texts too!
148
149    osg::Camera* hudCamera = new osg::Camera;
150    hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
151    hudCamera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);
152    hudCamera->setViewMatrix(osg::Matrix::identity());
153    hudCamera->setRenderOrder(osg::Camera::POST_RENDER);
154    hudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
155
156    std::string timesFont("fonts/times.ttf");
157
158    // turn lighting off for the text and disable depth test to ensure its always ontop.
159    osg::Vec3 position(150.0f,800.0f,0.0f);
160    osg::Vec3 delta(0.0f,-60.0f,0.0f);
161
162    {
163        osg::Geode* geode = new osg::Geode();
164        osg::StateSet* stateset = geode->getOrCreateStateSet();
165        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
166        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
167        geode->setName("simple");
168        hudCamera->addChild(geode);
169
170        osgText::Text* text = new  osgText::Text;
171        geode->addDrawable( text );
172
173        text->setFont(timesFont);
174        text->setText("Picking in Head Up Displays is simple!");
175        text->setPosition(position);
176
177        position += delta;
178    }
179
180
181    for (int i=0; i<5; i++) {
182        osg::Vec3 dy(0.0f,-30.0f,0.0f);
183        osg::Vec3 dx(120.0f,0.0f,0.0f);
184        osg::Geode* geode = new osg::Geode();
185        osg::StateSet* stateset = geode->getOrCreateStateSet();
186        const char *opts[]={"One", "Two", "Three", "January", "Feb", "2003"};
187        osg::Geometry *quad=new osg::Geometry;
188        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
189        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
190        std::string name="subOption";
191        name += " ";
192        name += std::string(opts[i]);
193        geode->setName(name);
194        osg::Vec3Array* vertices = new osg::Vec3Array(4); // 1 quad
195        osg::Vec4Array* colors = new osg::Vec4Array;
196        colors = new osg::Vec4Array;
197        colors->push_back(osg::Vec4(0.8-0.1*i,0.1*i,0.2*i, 1.0));
198        quad->setColorArray(colors, osg::Array::BIND_OVERALL);
199        (*vertices)[0]=position;
200        (*vertices)[1]=position+dx;
201        (*vertices)[2]=position+dx+dy;
202        (*vertices)[3]=position+dy;
203        quad->setVertexArray(vertices);
204        quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
205        geode->addDrawable(quad);
206        hudCamera->addChild(geode);
207
208        position += delta;
209    }
210
211
212
213    { // this displays what has been selected
214        osg::Geode* geode = new osg::Geode();
215        osg::StateSet* stateset = geode->getOrCreateStateSet();
216        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
217        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
218        geode->setName("The text label");
219        geode->addDrawable( updateText );
220        hudCamera->addChild(geode);
221
222        updateText->setCharacterSize(20.0f);
223        updateText->setFont(timesFont);
224        updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
225        updateText->setText("");
226        updateText->setPosition(position);
227        updateText->setDataVariance(osg::Object::DYNAMIC);
228
229        position += delta;
230    }
231
232    return hudCamera;
233
234}
235
236int main( int argc, char **argv )
237{
238    // use an ArgumentParser object to manage the program arguments.
239    osg::ArgumentParser arguments(&argc,argv);
240
241    // read the scene from the list of file specified commandline args.
242    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
243
244    if (!scene && arguments.read("--relative-camera-scene"))
245    {
246        // Create a test scene with a camera that has a relative reference frame.
247        osg::Group* group = new osg::Group();
248
249        osg::Geode* sphere = new osg::Geode();
250        sphere->setName("Sphere");
251        sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere()));
252
253        osg::Geode* cube = new osg::Geode();
254        cube->setName("Cube");
255        cube->addDrawable(new osg::ShapeDrawable(new osg::Box()));
256
257        osg::Camera* camera = new osg::Camera();
258        camera->setRenderOrder(osg::Camera::POST_RENDER);
259        camera->setClearMask(GL_DEPTH_BUFFER_BIT);
260        camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
261        camera->setViewMatrix(osg::Matrix::translate(-2, 0, 0));
262
263        osg::MatrixTransform* xform = new osg::MatrixTransform(osg::Matrix::translate(1, 1, 1));
264        xform->addChild(camera);
265
266        group->addChild(sphere);
267        group->addChild(xform);
268        camera->addChild(cube);
269
270        scene = group;
271    }
272
273    // if not loaded assume no arguments passed in, try use default mode instead.
274    if (!scene) scene = osgDB::readNodeFile("fountain.osgt");
275
276    osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(scene.get());
277    if (!group)
278    {
279        group = new osg::Group;
280        group->addChild(scene.get());
281    }
282
283    osg::ref_ptr<osgText::Text> updateText = new osgText::Text;
284
285    // add the HUD subgraph.
286    group->addChild(createHUD(updateText.get()));
287
288    if (arguments.read("--CompositeViewer"))
289    {
290        osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
291        // add the handler for doing the picking
292        view->addEventHandler(new PickHandler(updateText.get()));
293
294        // set the scene to render
295        view->setSceneData(group.get());
296
297        view->setUpViewAcrossAllScreens();
298
299        osgViewer::CompositeViewer viewer;
300        viewer.addView(view.get());
301
302        return viewer.run();
303
304    }
305    else
306    {
307        osgViewer::Viewer viewer;
308
309
310        // add all the camera manipulators
311        {
312            osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
313
314            keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
315            keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
316            keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
317
318            unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
319            keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
320
321            std::string pathfile;
322            char keyForAnimationPath = '5';
323            while (arguments.read("-p",pathfile))
324            {
325                osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
326                if (apm || !apm->valid())
327                {
328                    num = keyswitchManipulator->getNumMatrixManipulators();
329                    keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
330                    ++keyForAnimationPath;
331                }
332            }
333
334            keyswitchManipulator->selectMatrixManipulator(num);
335
336            viewer.setCameraManipulator( keyswitchManipulator.get() );
337        }
338
339        // add the handler for doing the picking
340        viewer.addEventHandler(new PickHandler(updateText.get()));
341
342        // set the scene to render
343        viewer.setSceneData(group.get());
344
345        return viewer.run();
346    }
347
348}
Note: See TracBrowser for help on using the browser.