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 #include "trianglemesh_display.h"
00031 #include "rviz/visualization_manager.h"
00032 #include "rviz/properties/property.h"
00033 #include "rviz/properties/property_manager.h"
00034 #include "rviz/common.h"
00035
00036 #include <tf/transform_listener.h>
00037
00038 #include <boost/bind.hpp>
00039
00040 #include <OGRE/OgreSceneNode.h>
00041 #include <OGRE/OgreSceneManager.h>
00042 #include <OGRE/OgreManualObject.h>
00043 #include <OGRE/OgreBillboardSet.h>
00044
00045 typedef struct {int a,b,c;} triangle;
00047 namespace triangle_mesh
00048 {
00049
00050 TriangleMeshDisplay::TriangleMeshDisplay(const std::string & name, rviz::VisualizationManager * manager)
00051 : Display(name, manager)
00052 , color_(0.1f, 1.0f, 0.0f)
00053 , wf_(false)
00054 , tf_filter_(*manager->getTFClient(), "", 2, update_nh_)
00055 , count (0)
00056 {
00057 scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00058
00059 static int count = 0;
00060 std::stringstream ss;
00061 ss << "TriangleMesh " << count++;
00062 tf_filter_.connectInput(sub_);
00063 tf_filter_.registerCallback(boost::bind(&TriangleMeshDisplay::incomingMessage, this, _1));
00064 }
00065
00066 TriangleMeshDisplay::~TriangleMeshDisplay()
00067 {
00068 unsubscribe();
00069 }
00070
00071 void TriangleMeshDisplay::setTopic(const std::string & topic)
00072 {
00073 unsubscribe();
00074 topic_ = topic;
00075 subscribe();
00076
00077 propertyChanged(topic_property_);
00078
00079 causeRender();
00080 }
00081
00082 void TriangleMeshDisplay::setColor(const rviz::Color & color)
00083 {
00084 color_ = color;
00085
00086 propertyChanged(color_property_);
00087 processMessage(current_message_);
00088 causeRender();
00089 }
00090
00091 void TriangleMeshDisplay::setWireFrameEnabled(const bool & wf)
00092 {
00093 wf_ = wf;
00094
00095 propertyChanged(wireframe_property_);
00096 processMessage(current_message_);
00097 causeRender();
00098 }
00099
00100 void TriangleMeshDisplay::subscribe()
00101 {
00102 if (!isEnabled())
00103 return;
00104
00105 if (!topic_.empty())
00106 {
00107 sub_.subscribe(update_nh_, topic_, 1);
00108 }
00109 }
00110
00111 void TriangleMeshDisplay::unsubscribe()
00112 {
00113 sub_.unsubscribe();
00114 }
00115
00116 void TriangleMeshDisplay::onEnable()
00117 {
00118 scene_node_->setVisible(true);
00119 subscribe();
00120 }
00121
00122 void TriangleMeshDisplay::onDisable()
00123 {
00124 unsubscribe();
00125 scene_node_->setVisible(false);
00126 }
00127
00128 void TriangleMeshDisplay::fixedFrameChanged()
00129 {
00130 tf_filter_.setTargetFrame(fixed_frame_);
00131 }
00132
00133 void TriangleMeshDisplay::update(float wall_dt, float ros_dt)
00134 {
00135 }
00136
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 void TriangleMeshDisplay::processMessage(const triangle_mesh_msgs::TriangleMesh::ConstPtr& msg)
00149 {
00150 if (!msg)
00151 {
00152 return;
00153 }
00154 if (count++ > 0)
00155 {
00157
00158
00159
00160 scene_manager_->destroyEntity(entity_);
00161 Ogre::MeshManager::getSingleton().unload ("trianglemesh");
00162 Ogre::MeshManager::getSingleton().remove ("trianglemesh");
00163 }
00164 std::vector<geometry_msgs::Point32> normals;
00165 bool use_normals = false;
00166
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 mesh_ = Ogre::MeshManager::getSingleton().createManual ("trianglemesh", "General");
00189 submesh_ = mesh_->createSubMesh();
00190
00191
00192 data = new Ogre::VertexData();
00193
00194 mesh_->sharedVertexData = data;
00195
00196
00197
00198 data->vertexCount = msg->points.size();
00199
00200 Ogre::VertexDeclaration* decl = data->vertexDeclaration;
00201 decl->addElement (0,0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00203 if (use_normals)
00204 decl->addElement (0,Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3), Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
00205
00206
00207 vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
00208 decl->getVertexSize(0),
00209 msg->points.size(),
00210 Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY
00211 );
00212
00213 double min_x=FLT_MAX, min_y=FLT_MAX, min_z=FLT_MAX;
00214 double max_x=-FLT_MAX, max_y=-FLT_MAX, max_z=-FLT_MAX;
00215 int vertex_size_in_bytes = 3;
00216 if (use_normals)
00217 vertex_size_in_bytes = 6;
00218 float* array = (float*) malloc (sizeof(float)*vertex_size_in_bytes*msg->points.size());
00219 for (unsigned int i = 0; i < msg->points.size(); i++)
00220 {
00221 array[i*vertex_size_in_bytes+0] = msg->points[i].x;
00222 array[i*vertex_size_in_bytes+1] = msg->points[i].y;
00223 array[i*vertex_size_in_bytes+2] = msg->points[i].z;
00224 if (use_normals)
00225 {
00226 array[i*vertex_size_in_bytes+3] = normals[i].x;
00227 array[i*vertex_size_in_bytes+4] = normals[i].x;
00228 array[i*vertex_size_in_bytes+5] = normals[i].x;
00229 }
00230 if (msg->points[i].x < min_x) min_x = msg->points[i].x;
00231 if (msg->points[i].y < min_y) min_y = msg->points[i].y;
00232 if (msg->points[i].z < min_z) min_z = msg->points[i].z;
00233 if (msg->points[i].x > max_x) max_x = msg->points[i].x;
00234 if (msg->points[i].y > max_y) max_y = msg->points[i].y;
00235 if (msg->points[i].z > max_z) max_z = msg->points[i].z;
00236 }
00237
00238 vbuf->writeData (0, vbuf->getSizeInBytes(), array, true);
00239 free (array);
00240
00241 Ogre::VertexBufferBinding* bind = data->vertexBufferBinding;
00242 bind->setBinding (0, vbuf);
00243
00244 bool back_face_duplicate = true;
00245 int stride = 3;
00246 if (back_face_duplicate)
00247 stride = 6;
00248
00249
00250 ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
00251 Ogre::HardwareIndexBuffer::IT_32BIT,
00252 msg->triangles.size()*stride,
00253 Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY
00254 );
00255
00256 submesh_->indexData->indexBuffer = ibuf;
00257
00258 submesh_->indexData->indexCount = msg->triangles.size()*stride;
00259 submesh_->indexData->indexStart = 0;
00260
00261 unsigned int *index;
00262 index = (unsigned int*) malloc (sizeof(unsigned int)*stride*msg->triangles.size());
00263 for (unsigned int i = 0; i < msg->triangles.size(); i++)
00264 {
00265 index[i*stride+0] = msg->triangles[i].i;
00266 index[i*stride+1] = msg->triangles[i].j;
00267 index[i*stride+2] = msg->triangles[i].k;
00268 if (back_face_duplicate)
00269 {
00270 index[i*stride+3] = msg->triangles[i].i;
00271 index[i*stride+4] = msg->triangles[i].k;
00272 index[i*stride+5] = msg->triangles[i].j;
00273 }
00274 }
00275
00276 ibuf->writeData (0, ibuf->getSizeInBytes(), index, true);
00277 free (index);
00278
00279 mesh_->_setBounds (Ogre::AxisAlignedBox (min_x, min_y, min_z, max_x, max_y, max_z));
00280 mesh_->_setBoundingSphereRadius (std::max(max_x-min_x, std::max(max_y-min_y, max_z-min_z))/2.0f);
00281
00282 mesh_->load ();
00283
00284 std::stringstream ss;
00285 ss << "tm" << count;
00286 entity_ = scene_manager_->createEntity(ss.str(), "trianglemesh");
00287 for (unsigned int i = 0; i < entity_->getNumSubEntities (); i++)
00288 {
00289 entity_->getSubEntity (i)->getMaterial ()->getTechnique(0)->getPass(0)->setDiffuse(Ogre::ColourValue(color_.r_, color_.g_, color_.b_));
00290 entity_->getSubEntity (i)->getMaterial ()->getTechnique(0)->getPass(0)->setAmbient(Ogre::Real(color_.r_), Ogre::Real(color_.g_), Ogre::Real(color_.b_));
00291 if (wf_)
00292 entity_->getSubEntity (i)->getMaterial ()->getTechnique(0)->getPass(0)->setPolygonMode(Ogre::PM_WIREFRAME);
00293 else
00294 entity_->getSubEntity (i)->getMaterial ()->getTechnique(0)->getPass(0)->setPolygonMode(Ogre::PM_SOLID);
00295 }
00296
00297 scene_node_->attachObject(entity_);
00298
00299
00300 tf::Stamped<tf::Pose> pose(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f),
00301 btVector3(0, 0, 0)), msg->header.stamp,
00302 msg->header.frame_id);
00303
00304 try
00305 {
00306 vis_manager_->getTFClient()->transformPose(fixed_frame_, pose, pose);
00307 }
00308 catch (tf::TransformException & e)
00309 {
00310 ROS_ERROR("Error transforming from frame '%s' to frame '%s'",
00311 msg->header.frame_id.c_str(), fixed_frame_.c_str());
00312 }
00313
00314 Ogre::Vector3 position = Ogre::Vector3(pose.getOrigin().x(),
00315 pose.getOrigin().y(), pose.getOrigin().z());
00316
00317 Ogre::Quaternion orientation = Ogre::Quaternion (pose.getRotation().w(), pose.getRotation().x(), pose.getRotation().y(), pose.getRotation().z());
00318
00319 rviz::robotToOgre(position);
00320 rviz::robotToOgre(orientation);
00321
00322 scene_node_->setOrientation (orientation);
00323 scene_node_->setPosition (position);
00324
00325 }
00326
00327 void TriangleMeshDisplay::incomingMessage(const triangle_mesh_msgs::TriangleMesh::ConstPtr& message)
00328 {
00329 current_message_ = message;
00330 processMessage(message);
00331 }
00332
00333 void TriangleMeshDisplay::reset()
00334 {
00335 }
00336
00337 void TriangleMeshDisplay::targetFrameChanged()
00338 {
00339 }
00340
00341 void TriangleMeshDisplay::createProperties()
00342 {
00343 wireframe_property_ = property_manager_->createProperty<rviz::BoolProperty>
00344 ("Wireframe enable", property_prefix_, boost::bind(&TriangleMeshDisplay::getWireFrameEnabled, this),
00345 boost::bind(&TriangleMeshDisplay::setWireFrameEnabled, this, _1), parent_category_, this);
00346 color_property_ = property_manager_->createProperty<rviz::ColorProperty>
00347 ("Color", property_prefix_, boost::bind(&TriangleMeshDisplay::getColor, this),
00348 boost::bind(&TriangleMeshDisplay::setColor, this, _1), parent_category_, this);
00349 topic_property_ = property_manager_->createProperty<rviz::ROSTopicStringProperty>
00350 ("Topic", property_prefix_, boost::bind(&TriangleMeshDisplay::getTopic, this),
00351 boost::bind(&TriangleMeshDisplay::setTopic, this, _1), parent_category_, this);
00352 rviz::ROSTopicStringPropertyPtr topic_prop = topic_property_.lock();
00353 topic_prop->setMessageType(ros::message_traits::DataType<triangle_mesh_msgs::TriangleMesh>().value());
00354 }
00355
00356
00357 }