render_shapes.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /* Author: Ioan Sucan */
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   // we don't know how to render cones directly, but we can convert them to a mesh
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)); // the shape has z as major axis, but the rendered cylinder has y as major axis (assuming z is upright);
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         //construct the material
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       // in geometric shapes, the z axis of the cylinder is it height;
00213       // for the rviz shape, the y axis is the height; we add a transform to fix this
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 }


visualization
Author(s): Ioan Sucan , Dave Coleman
autogenerated on Mon Oct 6 2014 02:34:03