/* OpenSceneGraph example, osgpick. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* osgpick sample - Mouse picking in a 3d scene, */ #include #include "../SoEOsgPragma.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // class to handle events with a pick class PickHandler : public osgGA::GUIEventHandler { public: PickHandler(osgText::Text* updateText): _updateText(updateText) {} ~PickHandler() {} bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa); virtual void pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea); void setLabel(const std::string& name) { if (_updateText.get()) _updateText->setText(name); } protected: osg::ref_ptr _updateText; }; bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) { switch(ea.getEventType()) { case(osgGA::GUIEventAdapter::PUSH): { osgViewer::View* view = dynamic_cast(&aa); if (view) pick(view,ea); return false; } case(osgGA::GUIEventAdapter::KEYDOWN): { if (ea.getKey()=='c') { osgViewer::View* view = dynamic_cast(&aa); osg::ref_ptr event = new osgGA::GUIEventAdapter(ea); event->setX((ea.getXmin()+ea.getXmax())*0.5); event->setY((ea.getYmin()+ea.getYmax())*0.5); if (view) pick(view,*event); } return false; } default: return false; } } void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea) { osgUtil::LineSegmentIntersector::Intersections intersections; std::string gdlist=""; if (view->computeIntersections(ea,intersections)) { for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr != intersections.end(); ++hitr) { std::ostringstream os; if (!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty())) { // the geodes are identified by name. os<<"Object \""<nodePath.back()->getName()<<"\""<drawable.valid()) { os<<"Object \""<drawable->className()<<"\""<getLocalIntersectPoint()<<")"<<" normal("<getLocalIntersectNormal()<<")"<getWorldIntersectPoint()<<")"<<" normal("<getWorldIntersectNormal()<<")"<indexList; for(unsigned int i=0;igetOrCreateStateSet(); stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); geode->setName("simple"); hudCamera->addChild(geode); osgText::Text* text = new osgText::Text; geode->addDrawable( text ); text->setFont(timesFont); text->setText("Picking in Head Up Displays is simple!"); text->setPosition(position); position += delta; } for (int i=0; i<5; i++) { osg::Vec3 dy(0.0f,-30.0f,0.0f); osg::Vec3 dx(120.0f,0.0f,0.0f); osg::Geode* geode = new osg::Geode(); osg::StateSet* stateset = geode->getOrCreateStateSet(); const char *opts[]={"One", "Two", "Three", "January", "Feb", "2003"}; osg::Geometry *quad=new osg::Geometry; stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); std::string name="subOption"; name += " "; name += std::string(opts[i]); geode->setName(name); osg::Vec3Array* vertices = new osg::Vec3Array(4); // 1 quad osg::Vec4Array* colors = new osg::Vec4Array; colors = new osg::Vec4Array; colors->push_back(osg::Vec4(0.8-0.1*i,0.1*i,0.2*i, 1.0)); quad->setColorArray(colors, osg::Array::BIND_OVERALL); (*vertices)[0]=position; (*vertices)[1]=position+dx; (*vertices)[2]=position+dx+dy; (*vertices)[3]=position+dy; quad->setVertexArray(vertices); quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); geode->addDrawable(quad); hudCamera->addChild(geode); position += delta; } { // this displays what has been selected osg::Geode* geode = new osg::Geode(); osg::StateSet* stateset = geode->getOrCreateStateSet(); stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); geode->setName("The text label"); geode->addDrawable( updateText ); hudCamera->addChild(geode); updateText->setCharacterSize(20.0f); updateText->setFont(timesFont); updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); updateText->setText(""); updateText->setPosition(position); updateText->setDataVariance(osg::Object::DYNAMIC); position += delta; } return hudCamera; } osg::Node* createUnit() { osg::ref_ptr simpleModel = osgDB::readRefNodeFile("cessna.osg.10.scale"); osg::ref_ptr detailModel = osgDB::readRefNodeFile("cow.osg"); osg::ref_ptr mtNode = new osg::MatrixTransform; osg::Matrix posM; posM.makeTranslate(osg::Vec3d(0.0, 0.0, 20.0)); mtNode->setMatrix(posM); osg::ref_ptr patNode = new osg::PositionAttitudeTransform; osg::ref_ptr olNode = new osgFX::Outline; olNode->setColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)); olNode->setWidth(2.0f); olNode->setEnabled(true); osg::ref_ptr atNode = new osg::AutoTransform; atNode->setAutoScaleToScreen(true); osg::ref_ptr lodNode = new osg::LOD; lodNode->insertChild(0, atNode); lodNode->insertChild(1, detailModel); lodNode->setRange(0, 10, 1e10); lodNode->setRange(1, 0, 10); mtNode->addChild(patNode); patNode->addChild(olNode); olNode->addChild(lodNode); atNode->addChild(simpleModel); return mtNode.release(); } int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // read the scene from the list of file specified commandline args. osg::ref_ptr scene = osgDB::readRefNodeFiles(arguments); if (!scene && arguments.read("--relative-camera-scene")) { // Create a test scene with a camera that has a relative reference frame. osg::Group* group = new osg::Group(); osg::Geode* sphere = new osg::Geode(); sphere->setName("Sphere"); sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere())); osg::Geode* cube = new osg::Geode(); cube->setName("Cube"); cube->addDrawable(new osg::ShapeDrawable(new osg::Box())); osg::Camera* camera = new osg::Camera(); camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setClearMask(GL_DEPTH_BUFFER_BIT); camera->setReferenceFrame(osg::Transform::RELATIVE_RF); camera->setViewMatrix(osg::Matrix::translate(-2, 0, 0)); osg::MatrixTransform* xform = new osg::MatrixTransform(osg::Matrix::translate(1, 1, 1)); xform->addChild(camera); group->addChild(sphere); group->addChild(xform); camera->addChild(cube); scene = group; } // if not loaded assume no arguments passed in, try use default mode instead. if (!scene) scene = new osg::Group;//osgDB::readRefNodeFile("fountain.osgt"); osg::ref_ptr group = dynamic_cast(scene.get()); if (!group) { group = new osg::Group; group->addChild(scene.get()); } group->addChild(createUnit()); group->addChild(osgDB::readNodeFile("cessna.osg")); osg::ref_ptr updateText = new osgText::Text; // add the HUD subgraph. group->addChild(createHUD(updateText.get())); if (arguments.read("--CompositeViewer")) { osg::ref_ptr view = new osgViewer::View; // add the handler for doing the picking view->addEventHandler(new PickHandler(updateText.get())); // set the scene to render view->setSceneData(group.get()); view->setUpViewAcrossAllScreens(); osgViewer::CompositeViewer viewer; viewer.addView(view.get()); return viewer.run(); } else { osgViewer::Viewer viewer; // add all the camera manipulators { osg::ref_ptr keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() ); keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() ); keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() ); unsigned int num = keyswitchManipulator->getNumMatrixManipulators(); keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() ); std::string pathfile; char keyForAnimationPath = '5'; while (arguments.read("-p",pathfile)) { osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile); if (apm || !apm->valid()) { num = keyswitchManipulator->getNumMatrixManipulators(); keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm ); ++keyForAnimationPath; } } keyswitchManipulator->selectMatrixManipulator(num); viewer.setCameraManipulator( keyswitchManipulator.get() ); } // add the handler for doing the picking viewer.addEventHandler(new PickHandler(updateText.get())); // set the scene to render viewer.setSceneData(group.get()); return viewer.run(); } }