fixed: compile issue
[opensg.git] / Examples / Simple / 11picking.cpp
blob45fa8d69ad2b0be122ec6f1f6f8e8af99297d7ab
1 // OpenSG Tutorial Example: Picking
2 //
3 // In addition to the loading example this one shows how to pick an object.
4 //
5 // To do that the IntersectAction is introduced, which tests rays against
6 // geometry.
7 //
8 // Use Space to send a ray into the scene. If it hits something the hit
9 // triangle will be highlighted.
12 #ifdef OSG_BUILD_ACTIVE
13 // Headers
14 #include <OSGGLUT.h>
15 #include <OSGConfig.h>
16 #include <OSGSimpleGeometry.h>
17 #include <OSGGeoProperties.h>
18 #include <OSGGLUTWindow.h>
19 #include <OSGSimpleSceneManager.h>
20 #include <OSGAction.h>
21 #include <OSGGroup.h>
22 #include <OSGSceneFileHandler.h>
23 #include <OSGTriangleIterator.h>
25 // New Headers
27 // the ray intersect traversal
28 #include <OSGIntersectAction.h>
29 #else
30 // Headers
31 #include <OpenSG/OSGGLUT.h>
32 #include <OpenSG/OSGConfig.h>
33 #include <OpenSG/OSGSimpleGeometry.h>
34 #include <OpenSG/OSGGeoProperties.h>
35 #include <OpenSG/OSGGLUTWindow.h>
36 #include <OpenSG/OSGSimpleSceneManager.h>
37 #include <OpenSG/OSGAction.h>
38 #include <OpenSG/OSGGroup.h>
39 #include <OpenSG/OSGSceneFileHandler.h>
40 #include <OpenSG/OSGTriangleIterator.h>
42 // New Headers
44 // the ray intersect traversal
45 #include <OpenSG/OSGIntersectAction.h>
46 #endif
49 // The SimpleSceneManager to manage simple applications
50 OSG::SimpleSceneManagerRefPtr mgr;
52 // The file root node, needed for intersection
53 OSG::NodeRefPtr fileroot;
55 // The points used for visualising the ray and hit object
56 OSG::GeoPnt3fPropertyRefPtr isectPoints;
58 // The visualisation geometry, needed for update.
59 OSG::GeometryRefPtr testgeocore;
61 // forward declaration so we can have the interesting stuff upfront
62 int setupGLUT( int *argc, char *argv[] );
64 // react to keys
65 void keyboard(unsigned char k, int x, int y)
67 switch(k)
69 case 27:
71 // clean up global variables
72 fileroot = NULL;
73 isectPoints = NULL;
74 testgeocore = NULL;
75 mgr = NULL;
77 OSG::osgExit();
78 exit(0);
80 break;
82 case ' ': // send a ray through the clicked pixel
84 Intersection testing for rays is done using an
85 IntersectAction. The ray itself is calculated by the
86 SimpleSceneManager, given the clicked pixel.
88 It needs to be set up with the line that is to be
89 intersected. A line is a semi-infinite ray which has a
90 starting point and a direction, and extends in the
91 direction to infinity.
93 To do the actual test the Action's apply() method is used.
95 The results can be received from the Action. The main
96 difference is if something was hit or not, which is
97 returned in didHit().
99 If an intersection did occur, the other data elements are
100 valid, otherwise they are undefined.
102 The information that is stored in the action is the object
103 which was hit, the triangle of the object that was hit (in
104 the form of its index) and the actual hit position.
107 OSG::Line l;
109 l = mgr->calcViewRay(x, y);
111 std::cerr << "From " << l.getPosition ()
112 << ", dir " << l.getDirection() << std::endl;
114 OSG::IntersectActionRefPtr act = OSG::IntersectAction::create();
116 act->setLine(l);
117 act->apply(fileroot);
119 isectPoints->setValue(l.getPosition(), 0);
120 isectPoints->setValue(l.getPosition() + l.getDirection(), 1);
122 // did we hit something?
123 if (act->didHit())
125 // yes!! print and highlight it
126 std::cerr << " object " << act->getHitObject ()
127 << " tri " << act->getHitTriangle()
128 << " at " << act->getHitPoint ();
130 mgr->setHighlight(act->getHitObject());
132 // stop the ray on the hit surface
133 isectPoints->setValue(l.getPosition() +
134 l.getDirection() * act->getHitT(), 1);
136 // find the triangle that was hit
137 OSG::TriangleIterator it(act->getHitObject());
138 it.seek(act->getHitTriangle());
140 // calculate its vertex positions in world space
141 OSG::Matrix m;
142 act->getHitObject()->getToWorld(m);
144 // and turn them into a triangle
145 OSG::Pnt3f p = it.getPosition(0);
146 m.mult(p, p);
147 isectPoints->setValue(p, 2);
148 p = it.getPosition(1);
149 m.mult(p, p);
150 isectPoints->setValue(p, 3);
151 p = it.getPosition(2);
152 m.mult(p, p);
153 isectPoints->setValue(p, 4);
155 else
157 // no, get rid of the triangle and highlight.
158 isectPoints->setValue(OSG::Pnt3f(0,0,0), 2);
159 isectPoints->setValue(OSG::Pnt3f(0,0,0), 3);
160 isectPoints->setValue(OSG::Pnt3f(0,0,0), 4);
162 mgr->setHighlight(NULL);
165 OSG::commitChanges();
167 // free the action
168 act = NULL;
170 std::cerr << std::endl;
172 glutPostRedisplay();
174 break;
176 case 's':
178 mgr->setStatistics(!mgr->getStatistics());
180 break;
184 // Initialize GLUT & OpenSG and set up the scene
185 int main(int argc, char **argv)
187 // OSG init
188 OSG::osgInit(argc,argv);
190 // GLUT init
191 int winid = setupGLUT(&argc, argv);
193 // open a new scope, because the pointers below should go out of scope
194 // before entering glutMainLoop.
195 // Otherwise OpenSG will complain about objects being alive after shutdown.
197 // the connection between GLUT and OpenSG
198 OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create();
199 gwin->setGlutId(winid);
200 gwin->init();
202 // The scene group
204 OSG::NodeRefPtr scene = OSG::Node::create();
205 OSG::GroupRefPtr g = OSG::Group::create();
207 scene->setCore(g);
209 if(argc < 2)
211 FWARNING(("No file given!\n"));
212 FWARNING(("Supported file formats:\n"));
214 std::list<const char*> suffixes;
215 OSG::SceneFileHandler::the()->getSuffixList(suffixes);
217 for(std::list<const char*>::iterator it = suffixes.begin();
218 it != suffixes.end();
219 ++it)
221 FWARNING(("%s\n", *it));
224 fileroot = OSG::makeTorus(.5, 2, 16, 16);
226 else
229 All scene file loading is handled via the SceneFileHandler.
231 fileroot = OSG::SceneFileHandler::the()->read(argv[1]);
234 scene->addChild(fileroot);
236 // Create a small geometry to show the ray and what was hit
237 // Contains a line and a single triangle.
238 // The line shows the ray, the triangle whatever was hit.
240 OSG::SimpleMaterialRefPtr red = OSG::SimpleMaterial::create();
242 red->setDiffuse (OSG::Color3f( 1,0,0 ));
243 red->setTransparency(0.5);
244 red->setLit (false);
246 isectPoints = OSG::GeoPnt3fProperty::create();
247 isectPoints->addValue(OSG::Pnt3f(0,0,0));
248 isectPoints->addValue(OSG::Pnt3f(0,0,0));
249 isectPoints->addValue(OSG::Pnt3f(0,0,0));
250 isectPoints->addValue(OSG::Pnt3f(0,0,0));
251 isectPoints->addValue(OSG::Pnt3f(0,0,0));
253 OSG::GeoUInt32PropertyRefPtr index = OSG::GeoUInt32Property::create();
254 index->addValue(0);
255 index->addValue(1);
256 index->addValue(2);
257 index->addValue(3);
258 index->addValue(4);
260 OSG::GeoUInt32PropertyRefPtr lens = OSG::GeoUInt32Property::create();
261 lens->addValue(2);
262 lens->addValue(3);
264 OSG::GeoUInt8PropertyRefPtr type = OSG::GeoUInt8Property::create();
265 type->addValue(GL_LINES);
266 type->addValue(GL_TRIANGLES);
268 testgeocore = OSG::Geometry::create();
269 testgeocore->setPositions(isectPoints);
270 testgeocore->setIndices(index);
271 testgeocore->setLengths(lens);
272 testgeocore->setTypes(type);
273 testgeocore->setMaterial(red);
275 OSG::NodeRefPtr testgeo = OSG::Node::create();
276 testgeo->setCore(testgeocore);
278 scene->addChild(testgeo);
280 OSG::commitChanges();
282 // create the SimpleSceneManager helper
283 mgr = OSG::SimpleSceneManager::create();
285 // tell the manager what to manage
286 mgr->setWindow(gwin );
287 mgr->setRoot (scene);
289 // show the whole scene
290 mgr->showAll();
293 // GLUT main loop
294 glutMainLoop();
296 return 0;
300 // GLUT callback functions
303 // redraw the window
304 void display(void)
306 mgr->redraw();
309 // react to size changes
310 void reshape(int w, int h)
312 mgr->resize(w, h);
313 glutPostRedisplay();
316 // react to mouse button presses
317 void mouse(int button, int state, int x, int y)
319 if (state)
320 mgr->mouseButtonRelease(button, x, y);
321 else
322 mgr->mouseButtonPress(button, x, y);
324 glutPostRedisplay();
327 // react to mouse motions with pressed buttons
328 void motion(int x, int y)
330 mgr->mouseMove(x, y);
331 glutPostRedisplay();
334 // setup the GLUT library which handles the windows for us
335 int setupGLUT(int *argc, char *argv[])
337 glutInit(argc, argv);
338 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
340 int winid = glutCreateWindow("OpenSG");
342 glutReshapeFunc(reshape);
343 glutDisplayFunc(display);
344 glutMouseFunc(mouse);
345 glutMotionFunc(motion);
346 glutKeyboardFunc(keyboard);
348 return winid;