ogre_panel.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2020, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
36 #include <nav_2d_utils/bounds.h>
38 #include <OgreMaterialManager.h>
39 #include <OgreTextureManager.h>
40 #include <OgreTechnique.h>
41 #include <OgreSceneNode.h>
42 #include <ros/ros.h>
43 #include <algorithm>
44 #include <memory>
45 #include <string>
46 #include <vector>
47 
48 namespace robot_nav_rviz_plugins
49 {
50 
52  Ogre::SceneManager& scene_manager, Ogre::SceneNode& scene_node)
53  : data_(data), scene_manager_(scene_manager), scene_node_(scene_node)
54 {
55 }
56 
58 {
59  unsigned int rows = 1, cols = 1;
61 
62  /*
63  * Start by making one really large subpanel.
64  * If that doesn't work (i.e. throws an exception) divide the panel by its largest dimension and
65  * try again with more smaller subpanels.
66  */
67  while (true)
68  {
69  unsigned int n_swatches = rows * cols;
70  ROS_DEBUG("Creating %d swatches", n_swatches);
71  swatches_.clear();
72  try
73  {
74  for (const auto& bounds : nav_2d_utils::divideBounds(original_bounds, cols, rows))
75  {
76  swatches_.push_back(std::make_shared<PartialOgrePanel>(scene_manager_, scene_node_, bounds, info.resolution));
77  }
78  // successfully created swatches without error. Return
79  return;
80  }
81  catch (Ogre::RenderingAPIException&)
82  {
83  ROS_DEBUG("Failed to create %d swatches", n_swatches);
84  // Divide by the largest dimension
85  if (info.width / cols > info.height / rows)
86  cols *= 2;
87  else
88  rows *= 2;
89  }
90  }
91 }
92 
93 
94 void OgrePanel::updateData(const nav_core2::UIntBounds& updated_bounds)
95 {
96  // Copy the updated data to the partial panels
97  std::vector<unsigned char> pixels;
98  unsigned int updated_panels = 0;
99  for (PartialOgrePanel::Ptr& swatch : swatches_)
100  {
101  const nav_core2::UIntBounds& swatch_bounds = swatch->getBounds();
102 
103  // If the bounds of the swatch do not overlap with updated area, we can skip updating this swatch
104  if (!swatch_bounds.overlaps(updated_bounds)) continue;
105  updated_panels++;
106 
107  unsigned int swatch_width = swatch_bounds.getWidth(),
108  swatch_height = swatch_bounds.getHeight();
109  pixels.resize(swatch_width * swatch_height);
110 
111  auto pixel_it = pixels.begin();
112 
113  // The data for both data_ and the swatch_ are in row-major order, but with
114  // possibly different row sizes, so we need to create the new pixels array for the
115  // swatch with the smaller row size.
116  unsigned int x_min = swatch_bounds.getMinX();
117  unsigned int y_min = swatch_bounds.getMinY();
118  unsigned int y_max = swatch_bounds.getMaxY();
119  unsigned int width = data_.getWidth();
120  for (unsigned int yy = y_min; yy <= y_max; yy++)
121  {
122  int index = yy * width + x_min;
123  std::copy(&data_[index], &data_[index + swatch_width], pixel_it);
124  pixel_it += swatch_width;
125  }
126  swatch->updateData(pixels);
127  }
128  ROS_DEBUG("Updated %d/%zu panels", updated_panels, swatches_.size());
129 }
130 
132 {
133  const std::string name = palette.getName();
134 
135  // Get Proper Number of Colors
136  auto colors = palette.getColors();
137  if (colors.size() < NavGridPalette::NUM_COLORS)
138  {
139  ROS_DEBUG("Palette %s only has %zu colors defined. The rest will be black.",
140  name.c_str(), colors.size());
141  colors.resize(NavGridPalette::NUM_COLORS);
142  }
143  else if (colors.size() > NavGridPalette::NUM_COLORS)
144  {
145  ROS_WARN("Palette %s has %zu colors defined...can only use the first %d.",
146  name.c_str(), colors.size(), NavGridPalette::NUM_COLORS);
147  colors.resize(NavGridPalette::NUM_COLORS);
148  }
149 
150  // Construct Ogre Palette
151  Ogre::DataStreamPtr palette_stream;
152  palette_stream.bind(new Ogre::MemoryDataStream(&colors[0],
154  static int palette_tex_count = 0;
155  std::stringstream ss;
156  ss << "NavGridPaletteTexture" << palette_tex_count++;
157 
158  palettes_[name] = Ogre::TextureManager::getSingleton().loadRawData(ss.str(),
159  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
160  palette_stream, NavGridPalette::NUM_COLORS, 1, Ogre::PF_BYTE_RGBA, Ogre::TEX_TYPE_1D, 0);
161 
162  palette_transparency_[name] = palette.hasTransparency();
163 }
164 
165 void OgrePanel::setPalette(const std::string& palette_name)
166 {
167  current_palette_ = palette_name;
168  std::string ogre_palette_name = palettes_[palette_name]->getName();
169  for (PartialOgrePanel::Ptr& swatch : swatches_)
170  {
171  swatch->setTexture(ogre_palette_name, 1);
172  }
173 }
174 
175 void OgrePanel::updateAlpha(float alpha, bool draw_behind)
176 {
177  Ogre::SceneBlendType scene_blending;
178  bool depth_write;
179  int group = draw_behind ? Ogre::RENDER_QUEUE_4 : Ogre::RENDER_QUEUE_MAIN;
180 
181  if (alpha < 1.0 || palette_transparency_[current_palette_])
182  {
183  scene_blending = Ogre::SBT_TRANSPARENT_ALPHA;
184  depth_write = false;
185  }
186  else
187  {
188  scene_blending = Ogre::SBT_REPLACE;
189  depth_write = !draw_behind;
190  }
191 
192  // helper class to set alpha parameter on all renderables.
193  class AlphaSetter: public Ogre::Renderable::Visitor
194  {
195  public:
196  explicit AlphaSetter(float alpha)
197  : alpha_vec_(alpha, alpha, alpha, alpha)
198  {}
199 
200  void visit(Ogre::Renderable *rend, ushort lodIndex, bool isDebug, Ogre::Any *pAny = 0)
201  {
202  rend->setCustomParameter(ALPHA_PARAMETER, alpha_vec_);
203  }
204  private:
205  Ogre::Vector4 alpha_vec_;
206  };
207 
208  AlphaSetter alpha_setter(alpha);
209  for (PartialOgrePanel::Ptr& swatch : swatches_)
210  {
211  swatch->updateAlphaRendering(scene_blending, depth_write, group, &alpha_setter);
212  }
213 }
214 
216 {
217  for (PartialOgrePanel::Ptr& swatch : swatches_)
218  {
219  swatch->clear();
220  }
221 }
222 
224 {
225  // Translate origin of nav grid to ogre coordinates
226  geometry_msgs::Pose origin = nav_2d_utils::getOrigin3D(data_.getInfo());
227 
228  Ogre::Vector3 position;
229  Ogre::Quaternion orientation;
230  bool ret = fm.transform(data_.getFrameId(), ros::Time(0), origin, position, orientation);
231 
232  scene_node_.setPosition(position);
233  scene_node_.setOrientation(orientation);
234 
235  return ret;
236 }
237 } // namespace robot_nav_rviz_plugins
#define ALPHA_PARAMETER
bool overlaps(const GenericBounds< unsigned int > &other) const
unsigned int getMinX() const
unsigned int getMinY() const
std::map< std::string, bool > palette_transparency_
Definition: ogre_panel.h:157
std::vector< nav_core2::UIntBounds > divideBounds(const nav_core2::UIntBounds &original_bounds, unsigned int n_cols, unsigned int n_rows)
void updateInfo(const nav_grid::NavGridInfo &info)
Update the location/shape of the grid.
Definition: ogre_panel.cpp:57
static const unsigned int NUM_CHANNELS
OgrePanel(nav_grid::VectorNavGrid< unsigned char > &data, Ogre::SceneManager &scene_manager, Ogre::SceneNode &scene_node)
Definition: ogre_panel.cpp:51
#define ROS_WARN(...)
virtual std::vector< color_util::ColorRGBA24 > getColors() const =0
The actual definition of the colors.
static const unsigned int NUM_COLORS
std::shared_ptr< PartialOgrePanel > Ptr
Definition: ogre_panel.h:140
std::string getFrameId() const
virtual bool hasTransparency() const
See if the palette has any transparent colors.
Ogre::SceneManager & scene_manager_
Definition: ogre_panel.h:152
nav_grid::VectorNavGrid< unsigned char > & data_
Definition: ogre_panel.h:151
void clear()
Clear the panel from the visualization by making it invisible.
Definition: ogre_panel.cpp:215
Several reusable pieces for displaying polygons.
bool transform(const Header &header, const geometry_msgs::Pose &pose, Ogre::Vector3 &position, Ogre::Quaternion &orientation)
void addPalette(const NavGridPalette &palette)
Add a palette with the given name.
Definition: ogre_panel.cpp:131
geometry_msgs::Pose getOrigin3D(const nav_grid::NavGridInfo &info)
std::map< std::string, Ogre::TexturePtr > palettes_
Definition: ogre_panel.h:156
unsigned int getWidth() const
NavGridInfo getInfo() const
bool transformMap(rviz::FrameManager &fm)
Move the map to its proper position and orientation.
Definition: ogre_panel.cpp:223
unsigned int getHeight() const
nav_core2::UIntBounds getFullUIntBounds(const nav_grid::NavGridInfo &info)
void updateData(const nav_core2::UIntBounds &updated_bounds)
Update the panel data within the given bounds.
Definition: ogre_panel.cpp:94
void updateAlpha(float alpha, bool draw_behind)
Sets the alpha/draw_behind properties.
Definition: ogre_panel.cpp:175
virtual std::string getName() const =0
Unique descriptive name for this particular palette.
std::vector< PartialOgrePanel::Ptr > swatches_
Definition: ogre_panel.h:154
unsigned int getWidth() const
void setPalette(const std::string &palette_name)
Set the palette to use.
Definition: ogre_panel.cpp:165
A simple datastructure representing a palette of up to 256 24-bit colors.
unsigned int getMaxY() const
#define ROS_DEBUG(...)


robot_nav_rviz_plugins
Author(s):
autogenerated on Sun Jan 10 2021 04:08:58