UWSimUtils.cpp
Go to the documentation of this file.
00001 /* 
00002  * Copyright (c) 2013 University of Jaume-I.
00003  * All rights reserved. This program and the accompanying materials
00004  * are made available under the terms of the GNU Public License v3.0
00005  * which accompanies this distribution, and is available at
00006  * http://www.gnu.org/licenses/gpl.html
00007  * 
00008  * Contributors:
00009  *     Mario Prats
00010  *     Javier Perez
00011  */
00012 
00013 #include <ros/ros.h>
00014 #include <uwsim/SimulatorConfig.h>
00015 #include <uwsim/UWSimUtils.h>
00016 #include <osg/Material>
00017 #include <osg/ShapeDrawable>
00018 #include <osg/Shape>
00019 #include <osg/Geode>
00020 #include <osg/Switch>
00021 #include <osg/MatrixTransform>
00022 #include <osgDB/ReadFile>
00023 
00024 #if OSG_VERSION_MAJOR>=3
00025 #include <osgDB/Options>
00026 #endif
00027 
00028 //#include <osgOcean/OceanScene>
00029 #include <osgOcean/ShaderManager>
00030 
00031 // Default constructor - initialize searchForName to "" and 
00032 // set the traversal mode to TRAVERSE_ALL_CHILDREN
00033 findNodeVisitor::findNodeVisitor() :
00034     osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), searchForName()
00035 {
00036 }
00037 
00038 // Constructor that accepts string argument
00039 // Initializes searchForName to user string
00040 // set the traversal mode to TRAVERSE_ALL_CHILDREN
00041 findNodeVisitor::findNodeVisitor(const std::string &searchName) :
00042     osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), searchForName(searchName)
00043 {
00044 }
00045 
00046 //The 'apply' method for 'node' type instances.
00047 //Compare the 'searchForName' data member against the node's name.
00048 //If the strings match, add this node to our list
00049 void findNodeVisitor::apply(osg::Node &searchNode)
00050 {
00051   //std::cerr << "Compare " << searchForName << " to "  << searchNode.getName() << std::endl;
00052   if (searchNode.getName() == searchForName)
00053   {
00054     foundNodeList.push_back(&searchNode);
00055   }
00056   traverse(searchNode);
00057 }
00058 
00059 // Set the searchForName to user-defined string
00060 void findNodeVisitor::setNameToFind(const std::string &searchName)
00061 {
00062   searchForName = searchName;
00063   foundNodeList.clear();
00064 }
00065 
00066 osg::Node* findNodeVisitor::getFirst()
00067 {
00068   if (foundNodeList.size() == 0)
00069     return NULL;
00070   else
00071     return foundNodeList[0];
00072 }
00073 
00074 findRoutedNode::findRoutedNode() :
00075     nodeVisitor()
00076 {
00077 }
00078 
00079 findRoutedNode::findRoutedNode(const std::string &searchName) :
00080     nodeVisitor(), searchRoute(searchName)
00081 {
00082 }
00083 
00084 void findRoutedNode::setNameToFind(const std::string &searchName)
00085 {
00086   searchRoute = searchName;
00087   rootList.clear();
00088 }
00089 
00090 void findRoutedNode::find(osg::ref_ptr<osg::Node> searchNode)
00091 {
00092   unsigned int pos = 0;
00093   rootList.clear();
00094   rootList.push_back(searchNode);
00095   nodeListType auxList, auxList2;
00096 
00097   while ((pos = searchRoute.find("/")) < searchRoute.size())
00098   {
00099     for (unsigned int i = 0; i < rootList.size(); i++)
00100     {
00101       nodeVisitor.setNameToFind(searchRoute.substr(0, pos));
00102       rootList[i]->accept(nodeVisitor);
00103       auxList2 = nodeVisitor.getNodeList();
00104       auxList.insert(auxList.end(), auxList2.begin(), auxList2.end());
00105     }
00106     searchRoute.erase(0, pos + 1);
00107     rootList = auxList;
00108     auxList.clear();
00109   }
00110   for (unsigned int i = 0; i < rootList.size(); i++)
00111   {
00112     nodeVisitor.setNameToFind(searchRoute);
00113     rootList[i]->accept(nodeVisitor);
00114     auxList2 = nodeVisitor.getNodeList();
00115     auxList.insert(auxList.end(), auxList2.begin(), auxList2.end());
00116   }
00117   rootList = auxList;
00118 }
00119 
00120 osg::Node* findRoutedNode::getFirst()
00121 {
00122   if (rootList.size() == 0)
00123     return NULL;
00124   else
00125     return rootList[0];
00126 }
00127 
00128 osg::Node * findRN(std::string target, osg::Group * root)
00129 {
00130   findRoutedNode findRN(target);
00131   findRN.find(root);
00132   return findRN.getFirst();
00133 }
00134 
00135 osg::Node* UWSimGeometry::createSwitchableFrame(double radius, double length)
00136 {
00137   osg::Switch *axis = new osg::Switch();
00138   axis->setNewChildDefaultValue(false);
00139   axis->setName("switch_frames");
00140   axis->addChild(UWSimGeometry::createFrame());
00141   return axis;
00142 }
00143 
00144 osg::Node* UWSimGeometry::createFrame(double radius, double length)
00145 {
00146   osg::MatrixTransform *linkBaseTransform = new osg::MatrixTransform(osg::Matrix());
00147 
00148   //create XBase to rotate
00149   osg::Matrix XBase;
00150   XBase.preMultRotate(osg::Quat(M_PI_2, osg::Vec3d(1, 0, 0)));
00151   XBase.preMultTranslate(osg::Vec3d(0, 0, length / 2));
00152   osg::MatrixTransform *XBaseTransform = new osg::MatrixTransform(XBase);
00153   linkBaseTransform->addChild(XBaseTransform);
00154 
00155   //create X cylinder, set color, and add to XBase
00156   osg::Node *Xcylinder = UWSimGeometry::createOSGCylinder(radius, length);
00157   osg::StateSet * Xstateset = new osg::StateSet();
00158   osg::Material * Xmaterial = new osg::Material();
00159   Xmaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(1, 0, 0, 0));
00160   Xstateset->setAttribute(Xmaterial);
00161   Xcylinder->setStateSet(Xstateset);
00162   XBaseTransform->addChild(Xcylinder);
00163 
00164   //Properties on X cylinder
00165   static const char model_vertex[] = "default_scene.vert";
00166   static const char model_fragment[] = "default_scene.frag";
00167 
00168   osgDB::Registry::instance()->getDataFilePathList().push_back(
00169       std::string(UWSIM_ROOT_PATH) + std::string("/data/shaders"));
00170   osg::ref_ptr < osg::Program > program = osgOcean::ShaderManager::instance().createProgram("robot_shader",
00171                                                                                             model_vertex,
00172                                                                                             model_fragment, "", "");
00173   program->addBindAttribLocation("aTangent", 6);
00174 
00175   Xstateset->setAttributeAndModes(program, osg::StateAttribute::ON);
00176   Xstateset->addUniform(new osg::Uniform("uOverlayMap", 1));
00177   Xstateset->addUniform(new osg::Uniform("uNormalMap", 2));
00178 
00179   //create YBase to rotate
00180   osg::Matrix YBase;
00181   YBase.makeIdentity();
00182   YBase.preMultRotate(osg::Quat(M_PI_2, osg::Vec3d(0, 1, 0)));
00183   YBase.preMultTranslate(osg::Vec3d(0, 0, length / 2));
00184   osg::MatrixTransform *YBaseTransform = new osg::MatrixTransform(YBase);
00185   linkBaseTransform->addChild(YBaseTransform);
00186 
00187   //create Y cylinder, set color, and add to YBase
00188   osg::Node * Ycylinder = UWSimGeometry::createOSGCylinder(radius, length);
00189   osg::StateSet * Ystateset = new osg::StateSet();
00190   osg::Material * Ymaterial = new osg::Material();
00191   Ymaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 1, 0, 0));
00192   Ystateset->setAttribute(Ymaterial);
00193   Ycylinder->setStateSet(Ystateset);
00194   YBaseTransform->addChild(Ycylinder);
00195 
00196   //Properties on Ycylinder
00197   Ystateset->setAttributeAndModes(program, osg::StateAttribute::ON);
00198   Ystateset->addUniform(new osg::Uniform("uOverlayMap", 1));
00199   Ystateset->addUniform(new osg::Uniform("uNormalMap", 2));
00200 
00201   //create ZBase to rotate
00202   osg::Matrix ZBase;
00203   ZBase.makeIdentity();
00204   ZBase.preMultRotate(osg::Quat(M_PI_2, osg::Vec3d(0, 0, 1)));
00205   ZBase.preMultTranslate(osg::Vec3d(0, 0, length / 2));
00206   osg::MatrixTransform *ZBaseTransform = new osg::MatrixTransform(ZBase);
00207   linkBaseTransform->addChild(ZBaseTransform);
00208 
00209   //create Z cylinder, set color, and add to ZBase
00210   osg::Node * Zcylinder = UWSimGeometry::createOSGCylinder(radius, length);
00211   osg::StateSet * Zstateset = new osg::StateSet();
00212   osg::Material * Zmaterial = new osg::Material();
00213   Zmaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0, 0, 1, 0));
00214   Zstateset->setAttribute(Zmaterial);
00215   Zcylinder->setStateSet(Zstateset);
00216   ZBaseTransform->addChild(Zcylinder);
00217 
00218   //Properties on Zcylinder
00219   Zstateset->setAttributeAndModes(program, osg::StateAttribute::ON);
00220   Zstateset->addUniform(new osg::Uniform("uOverlayMap", 1));
00221   Zstateset->addUniform(new osg::Uniform("uNormalMap", 2));
00222 
00223   return linkBaseTransform;
00224 }
00225 
00226 osg::Node * UWSimGeometry::createOSGBox(osg::Vec3 size)
00227 {
00228   osg::Box *box = new osg::Box();
00229 
00230   box->setHalfLengths(size / 2);
00231 
00232   osg::ShapeDrawable *shape = new osg::ShapeDrawable(box);
00233   osg::Geode *geode = new osg::Geode();
00234   geode->addDrawable(shape);
00235 
00236   osg::Node* node = new osg::Group();
00237   node->asGroup()->addChild(geode);
00238 
00239   return node;
00240 }
00241 
00242 osg::Node* UWSimGeometry::createOSGCylinder(double radius, double height)
00243 {
00244   osg::Cylinder *cylinder = new osg::Cylinder();
00245 
00246   cylinder->setRadius(radius);
00247   cylinder->setHeight(height);
00248 
00249   osg::ShapeDrawable *shape = new osg::ShapeDrawable(cylinder);
00250   osg::Geode *geode = new osg::Geode();
00251   geode->addDrawable(shape);
00252 
00253   osg::Node *node = new osg::Group();
00254   node->asGroup()->addChild(geode);
00255 
00256   return node;
00257 }
00258 
00259 osg::Node * UWSimGeometry::createOSGSphere(double radius)
00260 {
00261   osg::Sphere *sphere = new osg::Sphere();
00262 
00263   sphere->setRadius(radius);
00264 
00265   osg::ShapeDrawable *shape = new osg::ShapeDrawable(sphere);
00266   osg::Geode *geode = new osg::Geode();
00267   geode->addDrawable(shape);
00268 
00269   osg::Node *node = new osg::Group();
00270   node->asGroup()->addChild(geode);
00271 
00272   return node;
00273 }
00274 
00275 void UWSimGeometry::applyStateSets(osg::Node *node)
00276 {
00277   const std::string SIMULATOR_DATA_PATH = std::string(getenv("HOME")) + "/.uwsim/data";
00278 
00279   osgDB::Registry::instance()->getDataFilePathList().push_back(
00280       std::string(UWSIM_ROOT_PATH) + std::string("/data/shaders"));
00281   static const char model_vertex[] = "default_scene.vert";
00282   static const char model_fragment[] = "default_scene.frag";
00283 
00284   osg::ref_ptr < osg::Program > program = osgOcean::ShaderManager::instance().createProgram("robot_shader",
00285                                                                                             model_vertex,
00286                                                                                             model_fragment, "", "");
00287   program->addBindAttribLocation("aTangent", 6);
00288 
00289   node->getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON);
00290   node->getStateSet()->addUniform(new osg::Uniform("uOverlayMap", 1));
00291   node->getStateSet()->addUniform(new osg::Uniform("uNormalMap", 2));
00292 }
00293 
00294 osg::Node * UWSimGeometry::retrieveResource(std::string name)
00295 {
00296   //Load file in memory
00297   resource_retriever::Retriever r;
00298   resource_retriever::MemoryResource resource;
00299 
00300   try
00301   {
00302     resource = r.get(name);
00303   }
00304   catch (resource_retriever::Exception& e)
00305   {
00306     return NULL;
00307   }
00308 
00309   //Create stream with memory resource
00310   std::stringstream buffer;
00311   buffer.write((char *)resource.data.get(), resource.size);
00312 
00313   //Get file extension and create options
00314   std::string file_ext = osgDB::getFileExtension(name);
00315 #if OSG_VERSION_MAJOR>=3
00316   osg::ref_ptr<osgDB::Options> local_opt = new osgDB::Options;
00317 #endif
00318 
00319   //Check if file format is supported, get readerwriter
00320   osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(file_ext);
00321   if (!rw)
00322   {
00323     std::cout << "Data file format " << file_ext << " not supported" << std::endl;
00324     return NULL;
00325   }
00326 
00327   //Try loading the resource,
00328 #if OSG_VERSION_MAJOR>=3
00329   osgDB::ReaderWriter::ReadResult readResult = rw->readNode( buffer,local_opt.get());
00330 #else
00331   osgDB::ReaderWriter::ReadResult readResult = rw->readNode(buffer);
00332 #endif
00333   if (readResult.validNode())
00334     return readResult.takeNode();
00335   else
00336     std::cout << "Can't load file " << name << std::endl;
00337   return NULL;
00338 
00339 }
00340 
00341 osg::Node * UWSimGeometry::loadGeometry(boost::shared_ptr<Geometry> geom)
00342 {
00343   if (geom->type == 0)
00344   {
00345     osg::Node * node = retrieveResource(geom->file);
00346     if (node == NULL)
00347     {
00348       //retrieve resource didn't succeed, let's search in the DATA PATH
00349       const std::string SIMULATOR_DATA_PATH = std::string(getenv("HOME")) + "/.uwsim/data";
00350 
00351       osgDB::Registry::instance()->getDataFilePathList().push_back(std::string(SIMULATOR_DATA_PATH));
00352       osgDB::Registry::instance()->getDataFilePathList().push_back(
00353           std::string(SIMULATOR_DATA_PATH) + std::string("/objects"));
00354       osgDB::Registry::instance()->getDataFilePathList().push_back(
00355           std::string(SIMULATOR_DATA_PATH) + std::string("/terrain"));
00356       osgDB::Registry::instance()->getDataFilePathList().push_back(
00357           std::string(UWSIM_ROOT_PATH) + std::string("/data/shaders"));
00358       node = osgDB::readNodeFile(geom->file);
00359 
00360       if (node == NULL)
00361       {
00362         std::cerr << "Error retrieving file " << geom->file
00363             << " Check URDF file or set your data path with the --dataPath option." << std::endl;
00364         exit(0);
00365       }
00366     }
00367     //If node isn't a group create a group with it.
00368     if (node->asGroup() == NULL)
00369     {
00370       osg::Node * aux = node;
00371       node = new osg::Group();
00372       node->asGroup()->addChild(aux);
00373     }
00374     return node;
00375   }
00376   else if (geom->type == 1)
00377   {
00378     return UWSimGeometry::createOSGBox(osg::Vec3(geom->boxSize[0], geom->boxSize[1], geom->boxSize[2]));
00379   }
00380   else if (geom->type == 2)
00381     return UWSimGeometry::createOSGCylinder(geom->radius, geom->length);
00382   else if (geom->type == 3)
00383     return UWSimGeometry::createOSGSphere(geom->radius);
00384   else if (geom->type == 4)
00385     return new osg::Group();
00386   std::cerr << "Unknown geometry type. " << std::endl;
00387   exit(0);
00388   return NULL;
00389 }
00390 
00391 getWorldCoordOfNodeVisitor::getWorldCoordOfNodeVisitor() :
00392     osg::NodeVisitor(NodeVisitor::TRAVERSE_PARENTS), done(false)
00393 {
00394   wcMatrix.reset(new osg::Matrixd());
00395 }
00396 
00397 void getWorldCoordOfNodeVisitor::apply(osg::Node &node)
00398 {
00399   if (!done)
00400   {
00401     if (0 == node.getNumParents())
00402     { // no parents
00403       wcMatrix->set(osg::computeLocalToWorld(this->getNodePath()));
00404       done = true;
00405     }
00406     traverse(node);
00407   }
00408 }
00409 
00410 boost::shared_ptr<osg::Matrix> getWorldCoordOfNodeVisitor::giveUpDaMat()
00411 {
00412   return wcMatrix;
00413 }
00414 
00415 boost::shared_ptr<osg::Matrix> getWorldCoords(osg::Node* node)
00416 {
00417   osg::ref_ptr<getWorldCoordOfNodeVisitor> ncv = new getWorldCoordOfNodeVisitor();
00418   if (node && ncv)
00419   {
00420     node->accept(*ncv);
00421     return ncv->giveUpDaMat();
00422   }
00423   else
00424   {
00425     return boost::shared_ptr<osg::Matrix>();
00426   }
00427 }
00428 
00429 // GETCATCHABLEOBJECTS
00430 
00431 GetCatchableObjects::GetCatchableObjects() :
00432     osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
00433 {
00434 }
00435 
00436 void GetCatchableObjects::apply(osg::Node &searchNode)
00437 {
00438   osg::ref_ptr < NodeDataType > data = dynamic_cast<NodeDataType*>(searchNode.getUserData());
00439   if (data != NULL && data->catchable)
00440   {
00441     foundNodeList.push_back(&searchNode);
00442   }
00443   traverse(searchNode);
00444 }
00445 


uwsim
Author(s): Mario Prats
autogenerated on Mon Oct 6 2014 08:24:07