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

Revision 13376, 12.0 kB (checked in by robert, 4 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);
199        quad->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
200        (*vertices)[0]=position;
201        (*vertices)[1]=position+dx;
202        (*vertices)[2]=position+dx+dy;
203        (*vertices)[3]=position+dy;
204        quad->setVertexArray(vertices);
205        quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
206        geode->addDrawable(quad);
207        hudCamera->addChild(geode);
208       
209        position += delta;
210    }   
211   
212   
213   
214    { // this displays what has been selected
215        osg::Geode* geode = new osg::Geode();
216        osg::StateSet* stateset = geode->getOrCreateStateSet();
217        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
218        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
219        geode->setName("The text label");
220        geode->addDrawable( updateText );
221        hudCamera->addChild(geode);
222       
223        updateText->setCharacterSize(20.0f);
224        updateText->setFont(timesFont);
225        updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
226        updateText->setText("");
227        updateText->setPosition(position);
228        updateText->setDataVariance(osg::Object::DYNAMIC);
229       
230        position += delta;
231    }   
232   
233    return hudCamera;
234
235}
236
237int main( int argc, char **argv )
238{
239    // use an ArgumentParser object to manage the program arguments.
240    osg::ArgumentParser arguments(&argc,argv);
241
242    // read the scene from the list of file specified commandline args.
243    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
244
245    if (!scene && arguments.read("--relative-camera-scene"))
246    {
247        // Create a test scene with a camera that has a relative reference frame.
248        osg::Group* group = new osg::Group();
249
250        osg::Geode* sphere = new osg::Geode();
251        sphere->setName("Sphere");
252        sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere()));
253
254        osg::Geode* cube = new osg::Geode();
255        cube->setName("Cube");
256        cube->addDrawable(new osg::ShapeDrawable(new osg::Box()));
257
258        osg::Camera* camera = new osg::Camera();
259        camera->setRenderOrder(osg::Camera::POST_RENDER);
260        camera->setClearMask(GL_DEPTH_BUFFER_BIT);
261        camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
262        camera->setViewMatrix(osg::Matrix::translate(-2, 0, 0));
263
264        osg::MatrixTransform* xform = new osg::MatrixTransform(osg::Matrix::translate(1, 1, 1));
265        xform->addChild(camera);
266
267        group->addChild(sphere);
268        group->addChild(xform);
269        camera->addChild(cube);
270
271        scene = group;
272    }
273
274    // if not loaded assume no arguments passed in, try use default mode instead.
275    if (!scene) scene = osgDB::readNodeFile("fountain.osgt");
276
277    osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(scene.get());
278    if (!group)
279    {
280        group = new osg::Group;
281        group->addChild(scene.get());
282    }
283
284    osg::ref_ptr<osgText::Text> updateText = new osgText::Text;
285
286    // add the HUD subgraph.   
287    group->addChild(createHUD(updateText.get()));
288
289    if (arguments.read("--CompositeViewer"))
290    {
291        osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
292        // add the handler for doing the picking
293        view->addEventHandler(new PickHandler(updateText.get()));
294
295        // set the scene to render
296        view->setSceneData(group.get());
297
298        view->setUpViewAcrossAllScreens();
299
300        osgViewer::CompositeViewer viewer;
301        viewer.addView(view.get());
302
303        return viewer.run();
304
305    }
306    else
307    {
308        osgViewer::Viewer viewer;
309
310
311        // add all the camera manipulators
312        {
313            osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
314
315            keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
316            keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
317            keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
318
319            unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
320            keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
321
322            std::string pathfile;
323            char keyForAnimationPath = '5';
324            while (arguments.read("-p",pathfile))
325            {
326                osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
327                if (apm || !apm->valid())
328                {
329                    num = keyswitchManipulator->getNumMatrixManipulators();
330                    keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
331                    ++keyForAnimationPath;
332                }
333            }
334
335            keyswitchManipulator->selectMatrixManipulator(num);
336
337            viewer.setCameraManipulator( keyswitchManipulator.get() );
338        }
339
340        // add the handler for doing the picking
341        viewer.addEventHandler(new PickHandler(updateText.get()));
342
343        // set the scene to render
344        viewer.setSceneData(group.get());
345   
346        return viewer.run();
347    }
348
349}
Note: See TracBrowser for help on using the browser.