mesh_resource_marker.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "mesh_resource_marker.h"
31 
35 
36 #include "rviz/display_context.h"
37 #include "rviz/mesh_loader.h"
38 #include "marker_display.h"
39 
40 #include <OgreSceneNode.h>
41 #include <OgreSceneManager.h>
42 #include <OgreEntity.h>
43 #include <OgreSubEntity.h>
44 #include <OgreMaterialManager.h>
45 #include <OgreTextureManager.h>
46 #include <OgreSharedPtr.h>
47 #include <OgreTechnique.h>
48 
49 namespace rviz
50 {
51 
52 MeshResourceMarker::MeshResourceMarker(MarkerDisplay* owner, DisplayContext* context, Ogre::SceneNode* parent_node)
53 : MarkerBase(owner, context, parent_node)
54 , entity_(0)
55 {
56 }
57 
59 {
60  reset();
61 }
62 
64 {
65  //destroy entity
66  if (entity_)
67  {
68  context_->getSceneManager()->destroyEntity(entity_);
69  entity_ = 0;
70  }
71 
72 
73  // destroy all the materials we've created
74  S_MaterialPtr::iterator it;
75  for (it = materials_.begin(); it != materials_.end(); it++)
76  {
77  Ogre::MaterialPtr material = *it;
78  if (!material.isNull())
79  {
80  material->unload();
81  Ogre::MaterialManager::getSingleton().remove(material->getName());
82  }
83  }
84  materials_.clear();
85 
86 }
87 
88 void MeshResourceMarker::onNewMessage(const MarkerConstPtr& old_message, const MarkerConstPtr& new_message)
89 {
90  ROS_ASSERT(new_message->type == visualization_msgs::Marker::MESH_RESOURCE);
91 
92  // flag indicating if the mesh material color needs to be updated
93  bool update_color = false;
94 
95  scene_node_->setVisible(false);
96 
97  // Get the color information from the message
98  float r = new_message->color.r;
99  float g = new_message->color.g;
100  float b = new_message->color.b;
101  float a = new_message->color.a;
102 
103  Ogre::SceneBlendType blending;
104  bool depth_write;
105 
106  if (a < 0.9998)
107  {
108  blending = Ogre::SBT_TRANSPARENT_ALPHA;
109  depth_write = false;
110  }
111  else
112  {
113  blending = Ogre::SBT_REPLACE;
114  depth_write = true;
115  }
116 
117 
118  if (!entity_ ||
119  old_message->mesh_resource != new_message->mesh_resource ||
120  old_message->mesh_use_embedded_materials != new_message->mesh_use_embedded_materials)
121  {
122  reset();
123 
124  if (new_message->mesh_resource.empty())
125  {
126  return;
127  }
128 
129  if (loadMeshFromResource(new_message->mesh_resource).isNull())
130  {
131  std::stringstream ss;
132  ss << "Mesh resource marker [" << getStringID() << "] could not load [" << new_message->mesh_resource << "]";
133  if (owner_)
134  {
136  }
137  ROS_DEBUG("%s", ss.str().c_str());
138  return;
139  }
140 
141  static uint32_t count = 0;
142  std::stringstream ss;
143  ss << "mesh_resource_marker_" << count++;
144  std::string id = ss.str();
145  entity_ = context_->getSceneManager()->createEntity(id, new_message->mesh_resource);
146  scene_node_->attachObject(entity_);
147 
148  // create a default material for any sub-entities which don't have their own.
149  ss << "Material";
150  Ogre::MaterialPtr default_material = Ogre::MaterialManager::getSingleton().create(ss.str(), ROS_PACKAGE_NAME);
151  default_material->setReceiveShadows(false);
152  default_material->getTechnique(0)->setLightingEnabled(true);
153  default_material->getTechnique(0)->setAmbient(0.5, 0.5, 0.5);
154 
155  materials_.insert(default_material);
156 
157  if (new_message->mesh_use_embedded_materials)
158  {
159  // make clones of all embedded materials so selection works correctly
160  S_MaterialPtr materials = getMaterials();
161 
162  S_MaterialPtr::iterator it;
163  for (it = materials.begin(); it != materials.end(); it++)
164  {
165  if ((*it)->getName() != "BaseWhiteNoLighting")
166  {
167  Ogre::MaterialPtr new_material = (*it)->clone(id + (*it)->getName());
168  materials_.insert(new_material);
169  }
170  }
171 
172  // make sub-entities use cloned materials
173  for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i)
174  {
175  std::string mat_name = entity_->getSubEntity(i)->getMaterialName();
176  if (mat_name != "BaseWhiteNoLighting")
177  {
178  entity_->getSubEntity(i)->setMaterialName(id + mat_name);
179  }
180  else
181  {
182  // BaseWhiteNoLighting is the default material Ogre uses
183  // when it sees a mesh with no material. Here we replace
184  // that with our default_material which gets colored with
185  // new_message->color.
186  entity_->getSubEntity(i)->setMaterial(default_material);
187  }
188  }
189  }
190  else
191  {
192  entity_->setMaterial(default_material);
193  }
194 
195  update_color = true;
196 
197  handler_.reset(new MarkerSelectionHandler(this, MarkerID(new_message->ns, new_message->id), context_));
198  handler_->addTrackedObject(entity_);
199  }
200  else
201  {
202  // underlying mesh resource has not changed but if the color has
203  // then we need to update the materials color
204  if (new_message->mesh_use_embedded_materials == false
205  && (!old_message
206  || old_message->mesh_use_embedded_materials == true
207  || old_message->color.r != new_message->color.r
208  || old_message->color.g != new_message->color.g
209  || old_message->color.b != new_message->color.b
210  || old_message->color.a != new_message->color.a))
211  {
212  update_color = true;
213  }
214  }
215 
216  // update material color
217  // if the mesh_use_embedded_materials is true and color is non-zero
218  // then the color will be used to tint the embedded materials
219  if (update_color)
220  {
221  if( new_message->mesh_use_embedded_materials && r == 0 && g == 0 && b == 0 && a == 0 )
222  {
223  blending = Ogre::SBT_REPLACE;
224  depth_write = true;
225  r = 1; g = 1; b = 1; a = 1;
226  }
227  S_MaterialPtr::iterator material_it;
228  for (material_it = materials_.begin(); material_it != materials_.end(); material_it++)
229  {
230  Ogre::Technique* technique = (*material_it)->getTechnique(0);
231  technique->setAmbient( r*0.5, g*0.5, b*0.5 );
232  technique->setDiffuse( r, g, b, a );
233  technique->setSceneBlending( blending );
234  technique->setDepthWriteEnabled( depth_write );
235  technique->setLightingEnabled( true );
236  }
237 
238  }
239 
240  Ogre::Vector3 pos, scale;
241  Ogre::Quaternion orient;
242  transform(new_message, pos, orient, scale);
243 
244  scene_node_->setVisible(true);
245  setPosition(pos);
246  setOrientation(orient);
247 
248  scene_node_->setScale(scale);
249 }
250 
252 {
253  S_MaterialPtr materials;
254  if (entity_)
255  {
256  extractMaterials(entity_, materials);
257  }
258  return materials;
259 }
260 
261 }
Ogre::SceneNode * scene_node_
Definition: marker_base.h:104
bool transform(const MarkerConstPtr &message, Ogre::Vector3 &pos, Ogre::Quaternion &orient, Ogre::Vector3 &scale)
Definition: marker_base.cpp:88
void setMarkerStatus(MarkerID id, StatusLevel level, const std::string &text)
MeshResourceMarker(MarkerDisplay *owner, DisplayContext *context, Ogre::SceneNode *parent_node)
std::string getStringID()
Definition: marker_base.h:78
virtual void onNewMessage(const MarkerConstPtr &old_message, const MarkerConstPtr &new_message)
virtual void setPosition(const Ogre::Vector3 &position)
Ogre::MeshPtr loadMeshFromResource(const std::string &resource_path)
MarkerDisplay * owner_
Definition: marker_base.h:101
void extractMaterials(Ogre::Entity *entity, S_MaterialPtr &materials)
std::pair< std::string, int32_t > MarkerID
Pure-virtual base class for objects which give Display subclasses context in which to work...
boost::shared_ptr< MarkerSelectionHandler > handler_
Definition: marker_base.h:110
virtual S_MaterialPtr getMaterials()
DisplayContext * context_
Definition: marker_base.h:102
MarkerID getID()
Definition: marker_base.h:77
visualization_msgs::Marker::ConstPtr MarkerConstPtr
Definition: marker_base.h:63
virtual Ogre::SceneManager * getSceneManager() const =0
Returns the Ogre::SceneManager used for the main RenderPanel.
std::set< Ogre::MaterialPtr > S_MaterialPtr
Definition: marker_base.h:57
virtual void setOrientation(const Ogre::Quaternion &orientation)
#define ROS_ASSERT(cond)
r
Displays "markers" sent in by other ROS nodes on the "visualization_marker" topic.
#define ROS_DEBUG(...)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Wed Aug 28 2019 04:01:51