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

Revision 7909, 8.8 kB (checked in by robert, 7 years ago)

From Jean-Sebastien Guay and Robert Osfield, added optional --CompositeViewer? path into osgpick to illustrate how to do picking in both viewers and as unit test for picking.

  • 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 <osg/Material>
30#include <osg/Geode>
31#include <osg/BlendFunc>
32#include <osg/Depth>
33#include <osg/Projection>
34#include <osg/MatrixTransform>
35#include <osg/Camera>
36#include <osg/io_utils>
37
38#include <osgText/Text>
39
40#include <sstream>
41
42// class to handle events with a pick
43class PickHandler : public osgGA::GUIEventHandler {
44public:
45
46    PickHandler(osgText::Text* updateText):
47        _updateText(updateText) {}
48       
49    ~PickHandler() {}
50   
51    bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);
52
53    virtual void pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea);
54
55    void setLabel(const std::string& name)
56    {
57        if (_updateText.get()) _updateText->setText(name);
58    }
59   
60protected:
61
62    osg::ref_ptr<osgText::Text>  _updateText;
63};
64
65bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
66{
67    switch(ea.getEventType())
68    {
69        case(osgGA::GUIEventAdapter::PUSH):
70        {
71            osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
72            if (view) pick(view,ea);
73            return false;
74        }   
75        default:
76            return false;
77    }
78}
79
80void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea)
81{
82    osgUtil::LineSegmentIntersector::Intersections intersections;
83
84    std::string gdlist="";
85    float x = ea.getX();
86    float y = ea.getY();
87    if (view->computeIntersections(x,y,intersections))
88    {
89        for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
90            hitr != intersections.end();
91            ++hitr)
92        {
93            std::ostringstream os;
94            if (!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty()))
95            {
96                // the geodes are identified by name.
97                os<<"Object \""<<hitr->nodePath.back()->getName()<<"\""<<std::endl;
98            }
99            else if (hitr->drawable.valid())
100            {
101                os<<"Object \""<<hitr->drawable->className()<<"\""<<std::endl;
102            }
103
104            os<<"        local coords vertex("<< hitr->getLocalIntersectPoint()<<")"<<"  normal("<<hitr->getLocalIntersectNormal()<<")"<<std::endl;
105            os<<"        world coords vertex("<< hitr->getWorldIntersectPoint()<<")"<<"  normal("<<hitr->getWorldIntersectNormal()<<")"<<std::endl;
106            const osgUtil::LineSegmentIntersector::Intersection::IndexList& vil = hitr->indexList;
107            for(unsigned int i=0;i<vil.size();++i)
108            {
109                os<<"        vertex indices ["<<i<<"] = "<<vil[i]<<std::endl;
110            }
111           
112            gdlist += os.str();
113        }
114    }
115    setLabel(gdlist);
116}
117
118osg::Node* createHUD(osgText::Text* updateText)
119{
120
121    // create the hud. derived from osgHud.cpp
122    // adds a set of quads, each in a separate Geode - which can be picked individually
123    // eg to be used as a menuing/help system!
124    // Can pick texts too!
125
126    osg::Camera* hudCamera = new osg::Camera;
127    hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
128    hudCamera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);
129    hudCamera->setViewMatrix(osg::Matrix::identity());
130    hudCamera->setRenderOrder(osg::Camera::POST_RENDER);
131    hudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
132   
133    std::string timesFont("fonts/times.ttf");
134   
135    // turn lighting off for the text and disable depth test to ensure its always ontop.
136    osg::Vec3 position(150.0f,800.0f,0.0f);
137    osg::Vec3 delta(0.0f,-60.0f,0.0f);
138   
139    {
140        osg::Geode* geode = new osg::Geode();
141        osg::StateSet* stateset = geode->getOrCreateStateSet();
142        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
143        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
144        geode->setName("simple");
145        hudCamera->addChild(geode);
146       
147        osgText::Text* text = new  osgText::Text;
148        geode->addDrawable( text );
149       
150        text->setFont(timesFont);
151        text->setText("Picking in Head Up Displays is simple!");
152        text->setPosition(position);
153       
154        position += delta;
155    }   
156   
157   
158    for (int i=0; i<5; i++) {
159        osg::Vec3 dy(0.0f,-30.0f,0.0f);
160        osg::Vec3 dx(120.0f,0.0f,0.0f);
161        osg::Geode* geode = new osg::Geode();
162        osg::StateSet* stateset = geode->getOrCreateStateSet();
163        const char *opts[]={"One", "Two", "Three", "January", "Feb", "2003"};
164        osg::Geometry *quad=new osg::Geometry;
165        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
166        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
167        std::string name="subOption";
168        name += " ";
169        name += std::string(opts[i]);
170        geode->setName(name);
171        osg::Vec3Array* vertices = new osg::Vec3Array(4); // 1 quad
172        osg::Vec4Array* colors = new osg::Vec4Array;
173        colors = new osg::Vec4Array;
174        colors->push_back(osg::Vec4(0.8-0.1*i,0.1*i,0.2*i, 1.0));
175        quad->setColorArray(colors);
176        quad->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
177        (*vertices)[0]=position;
178        (*vertices)[1]=position+dx;
179        (*vertices)[2]=position+dx+dy;
180        (*vertices)[3]=position+dy;
181        quad->setVertexArray(vertices);
182        quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
183        geode->addDrawable(quad);
184        hudCamera->addChild(geode);
185       
186        position += delta;
187    }   
188   
189   
190   
191    { // this displays what has been selected
192        osg::Geode* geode = new osg::Geode();
193        osg::StateSet* stateset = geode->getOrCreateStateSet();
194        stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
195        stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
196        geode->setName("The text label");
197        geode->addDrawable( updateText );
198        hudCamera->addChild(geode);
199       
200        updateText->setCharacterSize(20.0f);
201        updateText->setFont(timesFont);
202        updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
203        updateText->setText("");
204        updateText->setPosition(position);
205        updateText->setDataVariance(osg::Object::DYNAMIC);
206       
207        position += delta;
208    }   
209   
210    return hudCamera;
211
212}
213
214int main( int argc, char **argv )
215{
216    // use an ArgumentParser object to manage the program arguments.
217    osg::ArgumentParser arguments(&argc,argv);
218
219    // read the scene from the list of file specified commandline args.
220    osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
221     
222    // if not loaded assume no arguments passed in, try use default mode instead.
223    if (!scene) scene = osgDB::readNodeFile("fountain.osg");
224
225    osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(scene.get());
226    if (!group)
227    {
228        group = new osg::Group;
229        group->addChild(scene.get());
230    }
231
232    osg::ref_ptr<osgText::Text> updateText = new osgText::Text;
233
234    // add the HUD subgraph.   
235    group->addChild(createHUD(updateText.get()));
236
237    if (arguments.read("--CompositeViewer"))
238    {
239        osg::ref_ptr<osgViewer::View> view = new osgViewer::View;
240        // add the handler for doing the picking
241        view->addEventHandler(new PickHandler(updateText.get()));
242
243        // set the scene to render
244        view->setSceneData(group.get());
245
246        view->setUpViewAcrossAllScreens();
247
248        osgViewer::CompositeViewer viewer;
249        viewer.addView(view.get());
250
251        return viewer.run();
252
253    }
254    else
255    {
256        osgViewer::Viewer viewer;
257
258        // add the handler for doing the picking
259        viewer.addEventHandler(new PickHandler(updateText.get()));
260
261        // set the scene to render
262        viewer.setSceneData(group.get());
263
264        return viewer.run();
265    }
266
267}
Note: See TracBrowser for help on using the browser.