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 "triangle_list_marker.h"
00031
00032 #include "marker_selection_handler.h"
00033 #include "rviz/default_plugin/marker_display.h"
00034 #include "rviz/selection/selection_manager.h"
00035
00036 #include "rviz/visualization_manager.h"
00037 #include "rviz/mesh_loader.h"
00038 #include "marker_display.h"
00039
00040 #include <OGRE/OgreSceneNode.h>
00041 #include <OGRE/OgreSceneManager.h>
00042 #include <OGRE/OgreManualObject.h>
00043 #include <OGRE/OgreMaterialManager.h>
00044 #include <OGRE/OgreTextureManager.h>
00045
00046 namespace rviz
00047 {
00048
00049 TriangleListMarker::TriangleListMarker(MarkerDisplay* owner, VisualizationManager* manager, Ogre::SceneNode* parent_node)
00050 : MarkerBase(owner, manager, parent_node)
00051 , manual_object_(0)
00052 {
00053 if (parent_node)
00054 {
00055 scene_node_ = parent_node->createChildSceneNode();
00056 }
00057 else
00058 {
00059 scene_node_ = vis_manager_->getSceneManager()->getRootSceneNode()->createChildSceneNode();
00060 }
00061 }
00062
00063 TriangleListMarker::~TriangleListMarker()
00064 {
00065 vis_manager_->getSceneManager()->destroySceneNode(scene_node_->getName());
00066 vis_manager_->getSceneManager()->destroyManualObject(manual_object_);
00067
00068 for (size_t i = 0; i < material_->getNumTechniques(); ++i)
00069 {
00070 Ogre::Technique* t = material_->getTechnique(i);
00071
00072
00073 if (t->getSchemeName() == "Pick")
00074 {
00075 Ogre::TextureManager::getSingleton().remove(t->getPass(0)->getTextureUnitState(0)->getTextureName());
00076 }
00077 }
00078
00079 material_->unload();
00080 Ogre::MaterialManager::getSingleton().remove(material_->getName());
00081 }
00082
00083 void TriangleListMarker::onNewMessage(const MarkerConstPtr& old_message, const MarkerConstPtr& new_message)
00084 {
00085 ROS_ASSERT(new_message->type == visualization_msgs::Marker::TRIANGLE_LIST);
00086
00087 scene_node_->setVisible(false);
00088
00089 if (!manual_object_)
00090 {
00091 static uint32_t count = 0;
00092 std::stringstream ss;
00093 ss << "Mesh Marker" << count++;
00094 manual_object_ = vis_manager_->getSceneManager()->createManualObject(ss.str());
00095 scene_node_->attachObject(manual_object_);
00096
00097 ss << "Material";
00098 material_name_ = ss.str();
00099 material_ = Ogre::MaterialManager::getSingleton().create( material_name_, ROS_PACKAGE_NAME );
00100 material_->setReceiveShadows(false);
00101 material_->getTechnique(0)->setLightingEnabled(false);
00102 material_->getTechnique(0)->setAmbient( 0.5, 0.5, 0.5 );
00103 material_->setCullingMode(Ogre::CULL_NONE);
00104
00105 SelectionManager* sel_man = vis_manager_->getSelectionManager();
00106 coll_ = sel_man->createHandle();
00107 sel_man->addPickTechnique(coll_, material_);
00108 }
00109
00110 size_t num_points = new_message->points.size();
00111 if ((num_points % 3) != 0)
00112 {
00113 std::stringstream ss;
00114 ss << "TriMesh marker [" << getStringID() << "] has a point count which is not divisible by 3 [" << num_points <<"]";
00115 owner_->setMarkerStatus(getID(), status_levels::Error, ss.str());
00116 ROS_DEBUG("%s", ss.str().c_str());
00117
00118 manual_object_->clear();
00119 return;
00120 }
00121
00122 bool has_vertex_colors = new_message->colors.size() == num_points;
00123 if (has_vertex_colors)
00124 {
00125 material_->getTechnique(0)->setLightingEnabled(false);
00126 }
00127 else
00128 {
00129 material_->getTechnique(0)->setLightingEnabled(true);
00130 }
00131
00132
00133 if (old_message && num_points == old_message->points.size())
00134 {
00135 manual_object_->beginUpdate(0);
00136 }
00137 else
00138 {
00139 manual_object_->clear();
00140 manual_object_->estimateVertexCount(num_points);
00141 manual_object_->begin(material_name_, Ogre::RenderOperation::OT_TRIANGLE_LIST);
00142 }
00143
00144 for (size_t i = 0; i < num_points; ++i)
00145 {
00146 manual_object_->position(new_message->points[i].x, new_message->points[i].y, new_message->points[i].z);
00147
00148 if (has_vertex_colors)
00149 {
00150 manual_object_->colour(new_message->colors[i].r, new_message->colors[i].g, new_message->colors[i].b, new_message->color.a);
00151 }
00152 }
00153
00154 manual_object_->end();
00155
00156 Ogre::Vector3 pos, scale;
00157 Ogre::Quaternion orient;
00158 transform(new_message, pos, orient, scale, false);
00159
00160 if (new_message->scale.x * new_message->scale.y * new_message->scale.z == 0.0f)
00161 {
00162 owner_->setMarkerStatus(getID(), status_levels::Warn, "Scale of 0 in one of x/y/z");
00163 }
00164
00165 scene_node_->setVisible(true);
00166 scene_node_->setPosition(pos);
00167 scene_node_->setOrientation(orient);
00168 scene_node_->setScale(scale);
00169
00170 float r = new_message->color.r;
00171 float g = new_message->color.g;
00172 float b = new_message->color.b;
00173 float a = new_message->color.a;
00174 material_->getTechnique(0)->setAmbient( r*0.5, g*0.5, b*0.5 );
00175 material_->getTechnique(0)->setDiffuse( r, g, b, a );
00176
00177 if ( a < 0.9998 )
00178 {
00179 material_->getTechnique(0)->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
00180 material_->getTechnique(0)->setDepthWriteEnabled( false );
00181 }
00182 else
00183 {
00184 material_->getTechnique(0)->setSceneBlending( Ogre::SBT_REPLACE );
00185 material_->getTechnique(0)->setDepthWriteEnabled( true );
00186 }
00187 }
00188
00189 }
00190