Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
This tutorial demonstrates how to use the vl::RayIntersector class to interactively pick and select objects in the scene.
In this tutorial we will populate the scene with a few random objects. Then when the mouse is pressed we compute the ray projected from the mouse click position towards the scene and use it to compute the intersections point. If any intersection is found we highlight the intersection point by moving there a green sphere.
[From App_Picking.cpp
]
class App_Picking: public BaseDemo { public: void mouseDownEvent(EMouseButton, int x, int y) { Camera* camera = rendering()->as<Rendering>()->camera(); // convert Y coordinates to the OpenGL conventions y = openglContext()->height() - y; // compute the ray passing through the selected pixel Ray ray = camera->computeRay(x,y); // instance our ray-intersector RayIntersector intersector; // compute a frustum along the ray to accelerate the intersection test intersector.setFrustum( camera->computeRayFrustum( x,y ) ); // compute the intersections! // (1) short way intersector.intersect(ray, sceneManager()); // (2) long way /* // specify the Actor[s] to be tested intersector.actors()->clear(); sceneManager()->extractActors( *intersector.actors() ); // set the intersecting ray intersector.setRay(ray); // run intersection test intersector.intersect(); */ // inspect our intersections, the intersections returned are sorted according to their distance, the first one is the closest. if (intersector.intersections().size()) { // highlight the intersection point by moving the green sphere there mIntersectionPoint->setLocalMatrix( mat4() ); mIntersectionPoint->translate( intersector.intersections()[0]->intersectionPoint() ); mIntersectionPoint->computeWorldMatrix(); // print the name of the picked object Log::print( Say("Intersections detected = %n (%s).\n") << intersector.intersections().size() << intersector.intersections()[0]->actor()->objectName() ); } else Log::print("No intersections detected.\n"); } virtual void initEvent() { Log::notify(appletInfo()); srand((int)time(NULL)); // populate our scene with some random objects int count = 1; float displace = 2.0f; for(int z=-count; z<=count; ++z) for(int y=-count; y<=count; ++y) for(int x=-count; x<=count; ++x) { // random color ref<Effect> fx = new Effect; fx->shader()->enable(EN_DEPTH_TEST); fx->shader()->enable(EN_LIGHTING); fx->shader()->gocLight(0)->setLinearAttenuation(0.025f); fx->shader()->gocMaterial()->setDiffuse( fvec4((float)random(0,1), (float)random(0,1), (float)random(0,1),1.0f) ); ref<Geometry> geom = randomObject(); Actor* act = sceneManager()->tree()->addActor( geom.get(), fx.get(), new Transform ); act->setObjectName(geom->objectName().c_str()); act->transform()->translate(x*displace, y*displace, z*displace); act->transform()->computeWorldMatrix(); } // create a uv-sphere used to highlight the intersection point // random color ref<Effect> fx = new Effect; fx->shader()->enable(EN_DEPTH_TEST); fx->shader()->enable(EN_LIGHTING); fx->shader()->gocLight(0)->setLinearAttenuation(0.025f); fx->shader()->gocMaterial()->setDiffuse( green ); ref<Geometry> intersection_point_geom = makeUVSphere(vec3(0,0,0), 0.1f); intersection_point_geom->computeNormals(); Actor* intersection_point_act = sceneManager()->tree()->addActor( intersection_point_geom.get(), fx.get(), new Transform ); mIntersectionPoint = intersection_point_act->transform(); } // generate random objects ref<Geometry> randomObject() { ref<Geometry> geom; // random shape switch(rand() % 7) { case 0: geom = makeIcosphere(vec3(0,0,0), 1, 2, false); break; case 1: geom = makeBox(vec3(0,0,0), 1, 1, 1); break; case 2: geom = makeCone(vec3(0,0,0),1,1); break; case 3: geom = makeUVSphere(vec3(0,0,0),1); break; case 4: geom = makeCylinder(vec3(0,0,0),1,1); break; case 5: geom = makeTorus(vec3(0,0,0),2,0.5f,20,20); break; case 6: geom = makeTeapot(vec3(0,0,0),2); break; } // normals are needed for lighting if (!geom->normalArray()) geom->computeNormals(); return geom; } protected: Transform* mIntersectionPoint; }; // Have fun!