00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00029 #include <osgOcean/ShaderManager>
00030
00031
00032
00033 findNodeVisitor::findNodeVisitor() :
00034 osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), searchForName()
00035 {
00036 }
00037
00038
00039
00040
00041 findNodeVisitor::findNodeVisitor(const std::string &searchName) :
00042 osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), searchForName(searchName)
00043 {
00044 }
00045
00046
00047
00048
00049 void findNodeVisitor::apply(osg::Node &searchNode)
00050 {
00051
00052 if (searchNode.getName() == searchForName)
00053 {
00054 foundNodeList.push_back(&searchNode);
00055 }
00056 traverse(searchNode);
00057 }
00058
00059
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
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
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
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
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
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
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
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
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
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
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
00310 std::stringstream buffer;
00311 buffer.write((char *)resource.data.get(), resource.size);
00312
00313
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
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
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
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
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 {
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
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