00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <moveit/rviz_plugin_render_tools/render_shapes.h>
00033 #include <moveit/rviz_plugin_render_tools/octomap_render.h>
00034 #include <geometric_shapes/mesh_operations.h>
00035
00036 #include <OGRE/OgreSceneNode.h>
00037 #include <OGRE/OgreSceneManager.h>
00038 #include <OGRE/OgreManualObject.h>
00039 #include <OGRE/OgreMaterialManager.h>
00040
00041 #include <rviz/ogre_helpers/shape.h>
00042 #include <rviz/display_context.h>
00043 #include <rviz/robot/robot.h>
00044
00045 #include <boost/lexical_cast.hpp>
00046 #include <boost/math/constants/constants.hpp>
00047 #include <boost/scoped_ptr.hpp>
00048
00049 namespace moveit_rviz_plugin
00050 {
00051
00052 RenderShapes::RenderShapes(rviz::DisplayContext *context) : context_(context)
00053 {
00054 }
00055
00056 RenderShapes::~RenderShapes()
00057 {
00058 clear();
00059 }
00060
00061
00062 void RenderShapes::clear()
00063 {
00064 scene_shapes_.clear();
00065 for (std::size_t i = 0 ; i < movable_objects_.size() ; ++i)
00066 context_->getSceneManager()->destroyMovableObject(movable_objects_[i]);
00067
00068 movable_objects_.clear();
00069
00070 for (std::size_t i = 0; i < materials_.size(); ++i)
00071 {
00072 materials_[i]->unload();
00073 Ogre::MaterialManager::getSingleton().remove(materials_[i]->getName());
00074 }
00075 materials_.clear();
00076
00077 octree_voxel_grids_.clear();
00078 }
00079
00080 void RenderShapes::renderShape(Ogre::SceneNode *node,
00081 const shapes::Shape *s,
00082 const Eigen::Affine3d &p,
00083 OctreeVoxelRenderMode octree_voxel_rendering,
00084 OctreeVoxelColorMode octree_color_mode,
00085 const rviz::Color &color,
00086 float alpha)
00087 {
00088 rviz::Shape* ogre_shape = NULL;
00089
00090
00091 if (s->type == shapes::CONE)
00092 {
00093 boost::scoped_ptr<shapes::Mesh> m(shapes::createMeshFromShape(static_cast<const shapes::Cone&>(*s)));
00094 if (m)
00095 renderShape(node, m.get(), p, octree_voxel_rendering, octree_color_mode, color, alpha);
00096 return;
00097 }
00098
00099 switch (s->type)
00100 {
00101 case shapes::SPHERE:
00102 {
00103 ogre_shape = new rviz::Shape(rviz::Shape::Sphere,
00104 context_->getSceneManager(), node);
00105 double d = 2.0 * static_cast<const shapes::Sphere*>(s)->radius;
00106 ogre_shape->setScale(Ogre::Vector3(d, d, d));
00107 }
00108 break;
00109 case shapes::BOX:
00110 {
00111 ogre_shape = new rviz::Shape(rviz::Shape::Cube,
00112 context_->getSceneManager(), node);
00113 const double* sz = static_cast<const shapes::Box*>(s)->size;
00114 ogre_shape->setScale(Ogre::Vector3(sz[0], sz[1], sz[2]));
00115 }
00116 break;
00117 case shapes::CYLINDER:
00118 {
00119 ogre_shape = new rviz::Shape(rviz::Shape::Cylinder,
00120 context_->getSceneManager(), node);
00121 double d = 2.0 * static_cast<const shapes::Cylinder*>(s)->radius;
00122 double z = static_cast<const shapes::Cylinder*>(s)->length;
00123 ogre_shape->setScale(Ogre::Vector3(d, z, d));
00124 }
00125 break;
00126 case shapes::MESH:
00127 {
00128 const shapes::Mesh *mesh = static_cast<const shapes::Mesh*>(s);
00129 if (mesh->triangle_count > 0)
00130 {
00131
00132 std::string mname = "Planning Scene Display Mesh Material " + boost::lexical_cast<std::string>(materials_.size()) + " @" + boost::lexical_cast<std::string>(this);
00133 Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(mname, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
00134 mat->setReceiveShadows(true);
00135 mat->getTechnique(0)->setLightingEnabled(true);
00136 mat->setCullingMode(Ogre::CULL_NONE);
00137 mat->getTechnique(0)->setAmbient(color.r_ * 0.2f, color.g_ * 0.2f, color.b_ * 0.2f);
00138 mat->getTechnique(0)->setDiffuse(color.r_, color.g_, color.b_, alpha);
00139 if (alpha < 0.9998)
00140 {
00141 mat->getTechnique(0)->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
00142 mat->getTechnique(0)->setDepthWriteEnabled( false );
00143 }
00144 else
00145 {
00146 mat->getTechnique(0)->setSceneBlending( Ogre::SBT_REPLACE );
00147 mat->getTechnique(0)->setDepthWriteEnabled( true );
00148 }
00149 materials_.push_back(mat);
00150
00151 std::string name = "Planning Scene Display Mesh " + boost::lexical_cast<std::string>(movable_objects_.size()) + " @" + boost::lexical_cast<std::string>(this);
00152 Ogre::ManualObject *manual_object = context_->getSceneManager()->createManualObject(name);
00153 manual_object->estimateVertexCount(mesh->triangle_count * 3);
00154 manual_object->begin(materials_.back()->getName(), Ogre::RenderOperation::OT_TRIANGLE_LIST);
00155 Eigen::Vector3d normal(0.0, 0.0, 0.0);
00156 Eigen::Matrix3d rot = p.rotation();
00157 for (unsigned int i = 0 ; i < mesh->triangle_count ; ++i)
00158 {
00159 unsigned int i3 = i * 3;
00160 if (mesh->triangle_normals && !mesh->vertex_normals)
00161 normal = rot * Eigen::Vector3d(mesh->triangle_normals[i3], mesh->triangle_normals[i3 + 1], mesh->triangle_normals[i3 + 2]);
00162
00163 for (int k = 0 ; k < 3 ; ++k)
00164 {
00165 unsigned int vi = 3 * mesh->triangles[i3 + k];
00166 Eigen::Vector3d v = p * Eigen::Vector3d(mesh->vertices[vi], mesh->vertices[vi + 1], mesh->vertices[vi + 2]);
00167 manual_object->position(v.x(), v.y(), v.z());
00168 if (mesh->vertex_normals)
00169 {
00170 normal = rot * Eigen::Vector3d(mesh->vertex_normals[vi], mesh->vertex_normals[vi + 1], mesh->vertex_normals[vi + 2]);
00171 manual_object->normal(normal.x(), normal.y(), normal.z());
00172 }
00173 else
00174 if (mesh->triangle_normals)
00175 manual_object->normal(normal.x(), normal.y(), normal.z());
00176 }
00177 }
00178 manual_object->end();
00179 node->attachObject(manual_object);
00180 movable_objects_.push_back(manual_object);
00181 }
00182 }
00183 break;
00184
00185 case shapes::OCTREE:
00186 {
00187 boost::shared_ptr<OcTreeRender> octree(new OcTreeRender(static_cast<const shapes::OcTree*>(s)->octree,
00188 octree_voxel_rendering,
00189 octree_color_mode,
00190 0u,
00191 context_->getSceneManager(),
00192 node));
00193
00194
00195 octree_voxel_grids_.push_back(octree);
00196 }
00197 break;
00198
00199 default:
00200 break;
00201 }
00202
00203 if (ogre_shape)
00204 {
00205 ogre_shape->setColor(color.r_, color.g_, color.b_, alpha);
00206 Ogre::Vector3 position(p.translation().x(), p.translation().y(), p.translation().z());
00207 Eigen::Quaterniond q(p.rotation());
00208 Ogre::Quaternion orientation(q.w(), q.x(), q.y(), q.z());
00209
00210 if (s->type == shapes::CYLINDER)
00211 {
00212
00213
00214 static Ogre::Quaternion fix(Ogre::Radian(boost::math::constants::pi<double>()/2.0), Ogre::Vector3(1.0, 0.0, 0.0));
00215 orientation = orientation * fix;
00216 }
00217
00218 ogre_shape->setPosition(position);
00219 ogre_shape->setOrientation(orientation);
00220 scene_shapes_.push_back(boost::shared_ptr<rviz::Shape>(ogre_shape));
00221 }
00222 }
00223
00224 }