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 
39 #include <OgreSceneNode.h>
40 #include <OgreSceneManager.h>
41 #include <OgreEntity.h>
42 #include <OgreSubEntity.h>
43 #include <OgreMaterialManager.h>
44 #include <OgreTextureManager.h>
45 #include <OgreSharedPtr.h>
46 #include <OgreTechnique.h>
47 
48 namespace rviz
49 {
51  DisplayContext* context,
52  Ogre::SceneNode* parent_node)
53  : MarkerBase(owner, context, parent_node), entity_(nullptr)
54 {
55 }
56 
58 {
59  reset();
60 }
61 
63 {
64  // destroy entity
65  if (entity_)
66  {
67  context_->getSceneManager()->destroyEntity(entity_);
68  entity_ = nullptr;
69  }
70 
71 
72  // destroy all the materials we've created
73  S_MaterialPtr::iterator it;
74  for (it = materials_.begin(); it != materials_.end(); it++)
75  {
76  Ogre::MaterialPtr material = *it;
77  if (!material.isNull())
78  {
79  Ogre::MaterialManager::getSingleton().remove(material->getName());
80  }
81  }
82  materials_.clear();
83 }
84 
86  const MarkerConstPtr& new_message)
87 {
88  ROS_ASSERT(new_message->type == visualization_msgs::Marker::MESH_RESOURCE);
89 
90  // flag indicating if the mesh material color needs to be updated
91  bool update_color = false;
92 
93  scene_node_->setVisible(false);
94 
95  // Get the color information from the message
96  float r = new_message->color.r;
97  float g = new_message->color.g;
98  float b = new_message->color.b;
99  float a = new_message->color.a;
100 
101  if (!entity_ || old_message->mesh_resource != new_message->mesh_resource ||
102  old_message->mesh_use_embedded_materials != new_message->mesh_use_embedded_materials)
103  {
104  reset();
105 
106  if (new_message->mesh_resource.empty())
107  {
108  return;
109  }
110 
111  if (loadMeshFromResource(new_message->mesh_resource).isNull())
112  {
113  std::stringstream ss;
114  ss << "Mesh resource marker [" << getStringID() << "] could not load ["
115  << new_message->mesh_resource << "]";
116  if (owner_)
117  {
119  }
120  ROS_DEBUG("%s", ss.str().c_str());
121  return;
122  }
123 
124  static uint32_t count = 0;
125  std::stringstream ss;
126  ss << "mesh_resource_marker_" << count++;
127  std::string id = ss.str();
128  entity_ = context_->getSceneManager()->createEntity(id, new_message->mesh_resource);
129  scene_node_->attachObject(entity_);
130 
131  // create a default material for any sub-entities which don't have their own.
132  ss << "Material";
133  Ogre::MaterialPtr default_material = Ogre::MaterialManager::getSingleton().create(
134  ss.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
135  default_material->setReceiveShadows(false);
136  default_material->getTechnique(0)->setLightingEnabled(true);
137  default_material->getTechnique(0)->setAmbient(0.5, 0.5, 0.5);
138  materials_.insert(default_material);
139 
140  if (new_message->mesh_use_embedded_materials)
141  {
142  // make clones of all embedded materials so selection works correctly
143  for (const Ogre::MaterialPtr& material : getMaterials())
144  {
145  if (material->getName() != "BaseWhiteNoLighting")
146  {
147  Ogre::MaterialPtr new_material = material->clone(id + material->getName());
148  // add a new pass to every custom material to perform the color tinting
149  Ogre::Pass* pass = new_material->getTechnique(0)->createPass();
150  pass->setAmbient(0.0f, 0.0f, 0.0f);
151  pass->setDiffuse(0.0f, 0.0f, 0.0f, 0.0f);
152  pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
153  pass->setDepthWriteEnabled(false);
154  pass->setLightingEnabled(true);
155  materials_.insert(new_material);
156  }
157  }
158 
159  // make sub-entities use cloned materials
160  for (uint32_t i = 0; i < entity_->getNumSubEntities(); ++i)
161  {
162  std::string mat_name = entity_->getSubEntity(i)->getMaterialName();
163  if (mat_name != "BaseWhiteNoLighting")
164  {
165  entity_->getSubEntity(i)->setMaterialName(id + mat_name);
166  }
167  else
168  {
169  // BaseWhiteNoLighting is the default material Ogre uses
170  // when it sees a mesh with no material. Here we replace
171  // that with our default_material which gets colored with
172  // new_message->color.
173  entity_->getSubEntity(i)->setMaterial(default_material);
174  }
175  }
176  }
177  else
178  {
179  entity_->setMaterial(default_material);
180  }
181 
182  update_color = !(new_message->mesh_use_embedded_materials && r == 0 && g == 0 && b == 0 && a == 0);
183 
184  handler_.reset(
185  new MarkerSelectionHandler(this, MarkerID(new_message->ns, new_message->id), context_));
186  handler_->addTrackedObject(entity_);
187  }
188  else
189  {
190  // underlying mesh resource has not changed but if the color has
191  // then we need to update the materials color
192  if (!old_message || old_message->color.r != r || old_message->color.g != g ||
193  old_message->color.b != b || old_message->color.a != a)
194  {
195  update_color = true;
196  }
197  }
198 
199  // update material color
200  if (update_color)
201  {
202  bool depth_write = a >= 0.9998;
203  Ogre::SceneBlendType blending = depth_write ? Ogre::SBT_REPLACE : Ogre::SBT_TRANSPARENT_ALPHA;
204  bool tinting = new_message->mesh_use_embedded_materials;
205 
206  for (const Ogre::MaterialPtr& material : materials_)
207  {
208  Ogre::Technique* technique = material->getTechnique(0);
209  Ogre::Pass* pass0 = technique->getPass(0);
210  Ogre::Pass* passT = technique->getPass(technique->getNumPasses() - 1);
211  if (tinting)
212  {
213  // modify material's original color to use given alpha value
214  Ogre::ColourValue color = pass0->getDiffuse();
215  color.a = a;
216  pass0->setDiffuse(color);
217  // tint by re-rendering with marker color
218  passT->setAmbient(r * 0.5f, g * 0.5f, b * 0.5f);
219  passT->setDiffuse(r, g, b, std::min(a, 0.5f));
220  }
221  else
222  {
223  pass0->setAmbient(r * 0.5f, g * 0.5f, b * 0.5f);
224  pass0->setDiffuse(r, g, b, a);
225  }
226 
227  pass0->setSceneBlending(blending);
228  pass0->setDepthWriteEnabled(depth_write);
229  pass0->setLightingEnabled(true);
230  }
231  }
232 
233  Ogre::Vector3 pos, scale;
234  Ogre::Quaternion orient;
235  if (!transform(new_message, pos, orient, scale))
236  {
237  scene_node_->setVisible(false);
238  return;
239  }
240 
241  scene_node_->setVisible(true);
242  setPosition(pos);
243  setOrientation(orient);
244 
245  scene_node_->setScale(scale);
246 }
247 
249 {
250  S_MaterialPtr materials;
251  if (entity_)
252  {
253  extractMaterials(entity_, materials);
254  }
255  return materials;
256 }
257 
258 } // namespace rviz
rviz::MarkerBase::context_
DisplayContext * context_
Definition: marker_base.h:108
rviz::MarkerBase::getStringID
std::string getStringID()
Definition: marker_base.h:78
rviz::S_MaterialPtr
std::set< Ogre::MaterialPtr > S_MaterialPtr
Definition: marker_base.h:51
rviz::MarkerDisplay
Displays "markers" sent in by other ROS nodes on the "visualization_marker" topic.
Definition: marker_display.h:70
marker_selection_handler.h
rviz::MarkerBase::setPosition
virtual void setPosition(const Ogre::Vector3 &position)
Definition: marker_base.cpp:124
rviz::StatusProperty::Error
@ Error
Definition: status_property.h:46
rviz::MarkerBase
Definition: marker_base.h:53
rviz::MeshResourceMarker::MeshResourceMarker
MeshResourceMarker(MarkerDisplay *owner, DisplayContext *context, Ogre::SceneNode *parent_node)
Definition: mesh_resource_marker.cpp:50
marker_display.h
rviz::MarkerBase::scene_node_
Ogre::SceneNode * scene_node_
Definition: marker_base.h:110
rviz::MarkerBase::setOrientation
virtual void setOrientation(const Ogre::Quaternion &orientation)
Definition: marker_base.cpp:129
rviz::MeshResourceMarker::onNewMessage
void onNewMessage(const MarkerConstPtr &old_message, const MarkerConstPtr &new_message) override
Definition: mesh_resource_marker.cpp:85
rviz::MarkerBase::handler_
boost::shared_ptr< MarkerSelectionHandler > handler_
Definition: marker_base.h:116
selection_manager.h
rviz::MeshResourceMarker::reset
void reset()
Definition: mesh_resource_marker.cpp:62
rviz::MeshResourceMarker::getMaterials
S_MaterialPtr getMaterials() override
Definition: mesh_resource_marker.cpp:248
rviz::DisplayContext::getSceneManager
virtual Ogre::SceneManager * getSceneManager() const =0
Returns the Ogre::SceneManager used for the main RenderPanel.
f
f
ROS_DEBUG
#define ROS_DEBUG(...)
rviz::MarkerBase::transform
bool transform(const MarkerConstPtr &message, Ogre::Vector3 &pos, Ogre::Quaternion &orient, Ogre::Vector3 &scale)
Definition: marker_base.cpp:87
rviz
Definition: add_display_dialog.cpp:54
rviz::MarkerSelectionHandler
Definition: marker_selection_handler.h:45
mesh_loader.h
rviz::DisplayContext
Pure-virtual base class for objects which give Display subclasses context in which to work.
Definition: display_context.h:81
rviz::loadMeshFromResource
Ogre::MeshPtr loadMeshFromResource(const std::string &resource_path)
Definition: mesh_loader.cpp:605
rviz::MeshResourceMarker::materials_
S_MaterialPtr materials_
Definition: mesh_resource_marker.h:61
rviz::MarkerID
std::pair< std::string, int32_t > MarkerID
Definition: interactive_marker_display.h:58
rviz::MeshResourceMarker::~MeshResourceMarker
~MeshResourceMarker() override
Definition: mesh_resource_marker.cpp:57
rviz::MarkerBase::owner_
MarkerDisplay * owner_
Definition: marker_base.h:107
mesh_resource_marker.h
rviz::MeshResourceMarker::entity_
Ogre::Entity * entity_
Definition: mesh_resource_marker.h:60
rviz::MarkerBase::getID
MarkerID getID()
Definition: marker_base.h:74
display_context.h
rviz::MarkerBase::extractMaterials
void extractMaterials(Ogre::Entity *entity, S_MaterialPtr &materials)
Definition: marker_base.cpp:144
ROS_ASSERT
#define ROS_ASSERT(cond)
rviz::MarkerBase::MarkerConstPtr
visualization_msgs::Marker::ConstPtr MarkerConstPtr
Definition: marker_base.h:57
rviz::MarkerDisplay::setMarkerStatus
void setMarkerStatus(const MarkerID &id, StatusLevel level, const std::string &text)
Definition: marker_display.cpp:237


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust, William Woodall
autogenerated on Fri Aug 2 2024 08:43:09