billboard_line.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, 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 "billboard_line.h"
31 
32 #include <OgreSceneManager.h>
33 #include <OgreSceneNode.h>
34 #include <OgreVector3.h>
35 #include <OgreQuaternion.h>
36 #include <OgreBillboardChain.h>
37 #include <OgreMaterialManager.h>
38 #include <OgreTechnique.h>
39 
40 #include <sstream>
41 
42 #include <ros/assert.h>
43 
44 #define MAX_ELEMENTS (65536 / 4)
45 
46 namespace rviz
47 {
48 BillboardLine::BillboardLine(Ogre::SceneManager* scene_manager, Ogre::SceneNode* parent_node)
49  : Object(scene_manager)
50  , width_(0.1f)
51  , current_line_(0)
52  , total_elements_(0)
53  , num_lines_(1)
54  , max_points_per_line_(100)
55  , lines_per_chain_(0)
56  , current_chain_(0)
57  , elements_in_current_chain_(0)
58 {
59  if (!parent_node)
60  {
61  parent_node = scene_manager_->getRootSceneNode();
62  }
63 
64  scene_node_ = parent_node->createChildSceneNode();
65 
66  static int count = 0;
67  std::stringstream ss;
68  ss << "BillboardLineMaterial" << count++;
69  material_ = Ogre::MaterialManager::getSingleton().create(
70  ss.str(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
71  material_->setReceiveShadows(false);
72  material_->getTechnique(0)->setLightingEnabled(false);
73 
75 }
76 
78 {
79  V_Chain::iterator it = chains_.begin();
80  V_Chain::iterator end = chains_.end();
81  for (; it != end; ++it)
82  {
83  scene_manager_->destroyBillboardChain(*it);
84  }
85 
86  scene_manager_->destroySceneNode(scene_node_->getName());
87 
88  Ogre::MaterialManager::getSingleton().remove(material_->getName());
89 }
90 
91 Ogre::BillboardChain* BillboardLine::createChain()
92 {
93  std::stringstream ss;
94  static int count = 0;
95  ss << "BillboardLine chain" << count++;
96  Ogre::BillboardChain* chain = scene_manager_->createBillboardChain(ss.str());
97  chain->setMaterialName(material_->getName());
98  scene_node_->attachObject(chain);
99 
100  chains_.push_back(chain);
101 
102  return chain;
103 }
104 
106 {
107  V_Chain::iterator it = chains_.begin();
108  V_Chain::iterator end = chains_.end();
109  for (; it != end; ++it)
110  {
111  (*it)->clearAllChains();
112  }
113 
114  current_line_ = 0;
115  total_elements_ = 0;
116  current_chain_ = 0;
118 
119  for (V_uint32::iterator it = num_elements_.begin(); it != num_elements_.end(); ++it)
120  {
121  *it = 0;
122  }
123 }
124 
126 {
127  uint32_t total_points = max_points_per_line_ * num_lines_;
128  uint32_t num_chains = total_points / MAX_ELEMENTS;
129  if (total_points % MAX_ELEMENTS != 0)
130  {
131  ++num_chains;
132  }
133 
134  for (uint32_t i = chains_.size(); i < num_chains; ++i)
135  {
136  createChain();
137  }
138 
140 
141  V_Chain::iterator it = chains_.begin();
142  V_Chain::iterator end = chains_.end();
143  for (; it != end; ++it)
144  {
145  (*it)->setMaxChainElements(max_points_per_line_);
146 
147  // shorten the number of chains in the last bbchain, to avoid memory wasteage
148  if (it + 1 == end)
149  {
150  uint32_t lines_left = num_lines_ % lines_per_chain_;
151 
152  // Handle the case where num_lines_ is a multiple of lines_per_chain
153  if (lines_left == 0)
154  {
155  (*it)->setNumberOfChains(lines_per_chain_);
156  }
157  else
158  {
159  (*it)->setNumberOfChains(lines_left);
160  }
161  }
162  else
163  {
164  (*it)->setNumberOfChains(lines_per_chain_);
165  }
166  }
167 }
168 
170 {
171  if (max <= MAX_ELEMENTS)
172  {
173  max_points_per_line_ = max;
174  setupChains();
175  }
176  else // need to split points across several lines
177  {
178  ROS_ASSERT(num_lines_ == 1);
180  num_lines_ = max / MAX_ELEMENTS;
181  if (max % MAX_ELEMENTS != 0)
182  ++num_lines_;
184  }
185 }
186 
187 void BillboardLine::setNumLines(uint32_t num)
188 {
189  num_lines_ = num;
190 
191  setupChains();
192 
193  num_elements_.resize(num);
194 
195  for (V_uint32::iterator it = num_elements_.begin(); it != num_elements_.end(); ++it)
196  {
197  *it = 0;
198  }
199 }
200 
202 {
203  ++current_line_;
204 
206 }
207 
208 void BillboardLine::addPoint(const Ogre::Vector3& point)
209 {
210  addPoint(point, color_);
211 }
212 
213 void BillboardLine::addPoint(const Ogre::Vector3& point, const Ogre::ColourValue& color)
214 {
217  {
218  ++current_chain_;
220 
222  newLine();
223  }
224 
226  ++total_elements_;
227 
229 
230  Ogre::BillboardChain::Element e;
231  e.position = point;
232  e.width = width_;
233  e.colour = color;
234  chains_[current_chain_]->addChainElement(current_line_ % lines_per_chain_, e);
235 }
236 
238 {
239  width_ = width;
240 
241  for (uint32_t line = 0; line < num_lines_; ++line)
242  {
243  uint32_t element_count = num_elements_[line];
244 
245  for (uint32_t i = 0; i < element_count; ++i)
246  {
247  Ogre::BillboardChain* c = chains_[line / lines_per_chain_];
248  Ogre::BillboardChain::Element e = c->getChainElement(line % lines_per_chain_, i);
249 
250  e.width = width_;
251  c->updateChainElement(line % lines_per_chain_, i, e);
252  }
253  }
254 }
255 
256 void BillboardLine::setPosition(const Ogre::Vector3& position)
257 {
258  scene_node_->setPosition(position);
259 }
260 
261 void BillboardLine::setOrientation(const Ogre::Quaternion& orientation)
262 {
263  scene_node_->setOrientation(orientation);
264 }
265 
266 void BillboardLine::setScale(const Ogre::Vector3& /*scale*/)
267 {
268  // Setting scale doesn't really make sense here
269 }
270 
271 void BillboardLine::setColor(float r, float g, float b, float a)
272 {
273  if (a < 0.9998)
274  {
275  material_->getTechnique(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
276  material_->getTechnique(0)->setDepthWriteEnabled(false);
277  }
278  else
279  {
280  material_->getTechnique(0)->setSceneBlending(Ogre::SBT_REPLACE);
281  material_->getTechnique(0)->setDepthWriteEnabled(true);
282  }
283 
284  color_ = Ogre::ColourValue(r, g, b, a);
285 
286  for (uint32_t line = 0; line < num_lines_; ++line)
287  {
288  uint32_t element_count = num_elements_[line];
289 
290  for (uint32_t i = 0; i < element_count; ++i)
291  {
292  Ogre::BillboardChain* c = chains_[line / lines_per_chain_];
293  Ogre::BillboardChain::Element e = c->getChainElement(line % lines_per_chain_, i);
294 
295  e.colour = color_;
296  c->updateChainElement(line % lines_per_chain_, i, e);
297  }
298  }
299 }
300 
301 const Ogre::Vector3& BillboardLine::getPosition()
302 {
303  return scene_node_->getPosition();
304 }
305 
306 const Ogre::Quaternion& BillboardLine::getOrientation()
307 {
308  return scene_node_->getOrientation();
309 }
310 
311 } // namespace rviz
Ogre::MaterialPtr material_
uint32_t elements_in_current_chain_
Ogre::ColourValue color_
void setPosition(const Ogre::Vector3 &position) override
Set the position of this object.
void addPoint(const Ogre::Vector3 &point)
f
#define MAX_ELEMENTS
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation of the object.
Base class for visible objects, providing a minimal generic interface.
Definition: object.h:50
const Ogre::Vector3 & getPosition() override
Get the local position of this object.
void setColor(float r, float g, float b, float a) override
Set the color of the object. Values are in the range [0, 1].
void setNumLines(uint32_t num)
void setMaxPointsPerLine(uint32_t max)
const Ogre::Quaternion & getOrientation() override
Get the local orientation of this object.
Ogre::BillboardChain * createChain()
uint32_t max_points_per_line_
Ogre::SceneManager * scene_manager_
Ogre scene manager this object is part of.
Definition: object.h:106
BillboardLine(Ogre::SceneManager *manager, Ogre::SceneNode *parent_node=nullptr)
Constructor.
#define ROS_ASSERT(cond)
void setScale(const Ogre::Vector3 &scale) override
Set the scale of the object. Always relative to the identity orientation of the object.
void setLineWidth(float width)
Ogre::SceneNode * scene_node_


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Sat May 27 2023 02:06:24