MeshPoseTool.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Robot Operating System code by the University of Osnabrück
5  * Copyright (c) 2015, University of Osnabrück
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  *
21  * 3. Neither the name of the copyright holder nor the names of its
22  * contributors may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
30  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
33  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *
38  *
39  *
40  * MeshPoseTool.cpp
41  *
42  * authors: Sebastian Pütz <spuetz@uos.de>
43  *
44  */
45 
46 #include <OgrePlane.h>
47 #include <OgreRay.h>
48 #include <OgreSceneNode.h>
49 #include <OgreViewport.h>
50 
51 #include <rviz/geometry.h>
54 #include <rviz/load_resource.h>
55 #include <rviz/render_panel.h>
56 #include <rviz/display_context.h>
57 
58 #include "MeshPoseTool.hpp"
59 
60 namespace rviz_map_plugin
61 {
62 MeshPoseTool::MeshPoseTool() : rviz::Tool(), arrow_(NULL)
63 {
64 }
65 
67 {
68  delete arrow_;
69 }
70 
72 {
73  arrow_ = new rviz::Arrow(scene_manager_, NULL, 2.0f, 0.2f, 0.5f, 0.35f);
74  arrow_->setColor(0.0f, 1.0f, 0.0f, 1.0f);
75  arrow_->getSceneNode()->setVisible(false);
76 }
77 
79 {
80  setStatus("Click and on a mesh_msgs::TriangleMesh to set the position and drag the mouse for the orientation.");
81  state_ = Position;
82 }
83 
85 {
86  arrow_->getSceneNode()->setVisible(false);
87 }
88 
90 {
91  int flags = 0;
92 
93  if (event.leftDown())
94  {
96 
97  Ogre::Vector3 pos, ori;
98  if (selectTriangle(event, pos, ori))
99  {
100  pos_ = pos;
101  ori_ = ori;
104  flags |= Render;
105  }
106  }
107  else if (event.type == QEvent::MouseMove && event.left())
108  {
109  if (state_ == Orientation)
110  {
111  Ogre::Vector3 cur_pos;
112  Ogre::Plane plane(ori_, pos_);
113  if (rviz::getPointOnPlaneFromWindowXY(event.viewport, plane, event.x, event.y, cur_pos))
114  {
115  // right hand coordinate system
116  // x to the right, y to the top, and -z into the scene
117  // arrow foreward negative z
118  Ogre::Vector3 z_axis = -(cur_pos - pos_);
119  Ogre::Vector3 y_axis = ori_;
120  Ogre::Vector3 x_axis = y_axis.crossProduct(z_axis);
121 
122  x_axis.normalise();
123  y_axis.normalise();
124  z_axis.normalise();
125 
126  arrow_->getSceneNode()->setVisible(true);
127  arrow_->setOrientation(Ogre::Quaternion(x_axis, y_axis, z_axis));
128 
129  flags |= Render;
130  }
131  }
132  }
133  else if (event.leftUp())
134  {
135  if (state_ == Orientation)
136  {
137  Ogre::Vector3 cur_pos;
138  Ogre::Plane plane(ori_, pos_);
139  if (rviz::getPointOnPlaneFromWindowXY(event.viewport, plane, event.x, event.y, cur_pos))
140  {
141  // arrow foreward negative z
142  Ogre::Vector3 z_axis = -(cur_pos - pos_);
143  Ogre::Vector3 y_axis = ori_;
144  Ogre::Vector3 x_axis = y_axis.crossProduct(z_axis);
145 
146  x_axis.normalise();
147  y_axis.normalise();
148  z_axis.normalise();
149 
150  onPoseSet(pos_, Ogre::Quaternion(x_axis, y_axis, z_axis));
151 
152  flags |= (Finished | Render);
153  }
154  }
155  }
156 
157  return flags;
158 }
159 
160 bool MeshPoseTool::selectTriangle(rviz::ViewportMouseEvent& event, Ogre::Vector3& position,
161  Ogre::Vector3& triangle_normal)
162 {
163  Ogre::Ray ray = event.viewport->getCamera()->getCameraToViewportRay(
164  (float)event.x / event.viewport->getActualWidth(), (float)event.y / event.viewport->getActualHeight());
165 
166  Ogre::RaySceneQuery* query =
167  context_->getSceneManager()->createRayQuery(ray, Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK);
168  query->setSortByDistance(true);
169 
170  Ogre::RaySceneQueryResult& result = query->execute();
171 
172  for (size_t i = 0; i < result.size(); i++)
173  {
174  if (result[i].movable->getName().find("TriangleMesh") != std::string::npos)
175  {
176  Ogre::ManualObject* mesh = static_cast<Ogre::ManualObject*>(result[i].movable);
177  size_t goal_section = -1;
178  size_t goal_index = -1;
179  Ogre::Real dist = -1;
180  if (getPositionAndOrientation(mesh, ray, position, triangle_normal))
181  {
182  return true;
183  }
184  }
185  }
186  return false;
187 }
188 
189 bool MeshPoseTool::getPositionAndOrientation(const Ogre::ManualObject* mesh, const Ogre::Ray& ray,
190  Ogre::Vector3& position, Ogre::Vector3& orientation)
191 {
192  Ogre::Real dist = -1.0f;
193  Ogre::Vector3 a, b, c;
194 
195  size_t vertex_count = 0;
196  Ogre::Vector3* vertices;
197  size_t index_count = 0;
198  unsigned long* indices;
199  size_t num_sections = mesh->getNumSections();
200 
201  for (size_t i = 0; i < num_sections; i++)
202  {
203  getRawManualObjectData(mesh, i, vertex_count, vertices, index_count, indices);
204  if (index_count != 0)
205  {
206  for (size_t j = 0; j < index_count; j += 3)
207  {
208  std::pair<bool, Ogre::Real> goal = Ogre::Math::intersects(ray, vertices[indices[j]], vertices[indices[j + 1]],
209  vertices[indices[j + 2]], true, true);
210 
211  if (goal.first)
212  {
213  if ((dist < 0.0f) || (goal.second < dist))
214  {
215  dist = goal.second;
216  a = vertices[indices[j]];
217  b = vertices[indices[j + 1]];
218  c = vertices[indices[j + 2]];
219  }
220  }
221  }
222  }
223  }
224 
225  delete[] vertices;
226  delete[] indices;
227  if (dist != -1)
228  {
229  position = ray.getPoint(dist);
230  Ogre::Vector3 ab = b - a;
231  Ogre::Vector3 ac = c - a;
232  orientation = ac.crossProduct(ab).normalisedCopy();
233  return true;
234  }
235  else
236  {
237  return false;
238  }
239 }
240 
241 void MeshPoseTool::getRawManualObjectData(const Ogre::ManualObject* mesh, const size_t sectionNumber,
242  size_t& vertexCount, Ogre::Vector3*& vertices, size_t& indexCount,
243  unsigned long*& indices)
244 {
245  Ogre::VertexData* vertexData;
246  const Ogre::VertexElement* vertexElement;
247  Ogre::HardwareVertexBufferSharedPtr vertexBuffer;
248  unsigned char* vertexChar;
249  float* vertexFloat;
250 
251  vertexData = mesh->getSection(sectionNumber)->getRenderOperation()->vertexData;
252  vertexElement = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
253  vertexBuffer = vertexData->vertexBufferBinding->getBuffer(vertexElement->getSource());
254  vertexChar = static_cast<unsigned char*>(vertexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
255 
256  vertexCount = vertexData->vertexCount;
257  vertices = new Ogre::Vector3[vertexCount];
258 
259  for (size_t i = 0; i < vertexCount; i++, vertexChar += vertexBuffer->getVertexSize())
260  {
261  vertexElement->baseVertexPointerToElement(vertexChar, &vertexFloat);
262  vertices[i] =
263  (mesh->getParentNode()->_getDerivedOrientation() *
264  (Ogre::Vector3(vertexFloat[0], vertexFloat[1], vertexFloat[2]) * mesh->getParentNode()->_getDerivedScale())) +
265  mesh->getParentNode()->_getDerivedPosition();
266  }
267 
268  vertexBuffer->unlock();
269 
270  Ogre::IndexData* indexData;
271  Ogre::HardwareIndexBufferSharedPtr indexBuffer;
272  indexData = mesh->getSection(sectionNumber)->getRenderOperation()->indexData;
273  indexCount = indexData->indexCount;
274  indices = new unsigned long[indexCount];
275  indexBuffer = indexData->indexBuffer;
276  unsigned int* pLong = static_cast<unsigned int*>(indexBuffer->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
277  unsigned short* pShort = reinterpret_cast<unsigned short*>(pLong);
278 
279  for (size_t i = 0; i < indexCount; i++)
280  {
281  unsigned long index;
282  if (indexBuffer->getType() == Ogre::HardwareIndexBuffer::IT_32BIT)
283  {
284  index = static_cast<unsigned long>(pLong[i]);
285  }
286 
287  else
288  {
289  index = static_cast<unsigned long>(pShort[i]);
290  }
291 
292  indices[i] = index;
293  }
294  indexBuffer->unlock();
295 }
296 
297 } // namespace rviz_map_plugin
rviz::ViewportMouseEvent::leftDown
bool leftDown()
rviz::Arrow
rviz_map_plugin::MeshPoseTool::getRawManualObjectData
void getRawManualObjectData(const Ogre::ManualObject *mesh, const size_t sectionNumber, size_t &vertexCount, Ogre::Vector3 *&vertices, size_t &indexCount, unsigned long *&indices)
Definition: MeshPoseTool.cpp:241
rviz::Arrow::setOrientation
void setOrientation(const Ogre::Quaternion &orientation) override
rviz::Tool::scene_manager_
Ogre::SceneManager * scene_manager_
rviz_map_plugin::MeshPoseTool::arrow_
rviz::Arrow * arrow_
Definition: MeshPoseTool.hpp:84
rviz::ViewportMouseEvent
rviz::ViewportMouseEvent::x
int x
rviz::Tool::context_
DisplayContext * context_
viewport_mouse_event.h
MeshPoseTool.hpp
rviz::ViewportMouseEvent::left
bool left()
rviz::Tool::setStatus
void setStatus(const QString &message)
NULL
#define NULL
rviz::DisplayContext::getSceneManager
virtual Ogre::SceneManager * getSceneManager() const=0
f
f
rviz_map_plugin::MeshPoseTool::onPoseSet
virtual void onPoseSet(const Ogre::Vector3 &position, const Ogre::Quaternion &orientation)=0
rviz::getPointOnPlaneFromWindowXY
bool getPointOnPlaneFromWindowXY(Ogre::Viewport *viewport, Ogre::Plane &plane, int window_x, int window_y, Ogre::Vector3 &intersection_out)
rviz::ViewportMouseEvent::viewport
Ogre::Viewport * viewport
render_panel.h
rviz
rviz_map_plugin::MeshPoseTool::~MeshPoseTool
virtual ~MeshPoseTool()
Definition: MeshPoseTool.cpp:66
rviz::Tool::Render
Render
rviz_map_plugin::MeshPoseTool::processMouseEvent
virtual int processMouseEvent(rviz::ViewportMouseEvent &event)
Definition: MeshPoseTool.cpp:89
rviz::ViewportMouseEvent::y
int y
load_resource.h
rviz::ViewportMouseEvent::type
QEvent::Type type
rviz_map_plugin::MeshPoseTool::MeshPoseTool
MeshPoseTool()
Definition: MeshPoseTool.cpp:62
arrow.h
rviz_map_plugin::MeshPoseTool::Orientation
@ Orientation
Definition: MeshPoseTool.hpp:88
rviz_map_plugin::MeshPoseTool::pos_
Ogre::Vector3 pos_
Definition: MeshPoseTool.hpp:91
geometry.h
rviz::ViewportMouseEvent::leftUp
bool leftUp()
rviz_map_plugin::MeshPoseTool::onInitialize
virtual void onInitialize()
Definition: MeshPoseTool.cpp:71
rviz_map_plugin::MeshPoseTool::Position
@ Position
Definition: MeshPoseTool.hpp:87
rviz_map_plugin
Definition: ClusterLabelDisplay.hpp:120
rviz_map_plugin::MeshPoseTool::deactivate
virtual void deactivate()
Definition: MeshPoseTool.cpp:84
rviz_map_plugin::MeshPoseTool::selectTriangle
bool selectTriangle(rviz::ViewportMouseEvent &event, Ogre::Vector3 &position, Ogre::Vector3 &orientation)
Definition: MeshPoseTool.cpp:160
rviz::Arrow::setPosition
void setPosition(const Ogre::Vector3 &position) override
rviz_map_plugin::MeshPoseTool::state_
State state_
Definition: MeshPoseTool.hpp:90
rviz::Arrow::getSceneNode
Ogre::SceneNode * getSceneNode()
rviz_map_plugin::MeshPoseTool::activate
virtual void activate()
Definition: MeshPoseTool.cpp:78
rviz_map_plugin::MeshPoseTool::ori_
Ogre::Vector3 ori_
Definition: MeshPoseTool.hpp:92
ROS_ASSERT
#define ROS_ASSERT(cond)
mesh
HalfEdgeMesh< Vec > mesh
rviz::Tool::Finished
Finished
rviz::Arrow::setColor
void setColor(const Ogre::ColourValue &color)
display_context.h
rviz_map_plugin::MeshPoseTool::getPositionAndOrientation
bool getPositionAndOrientation(const Ogre::ManualObject *mesh, const Ogre::Ray &ray, Ogre::Vector3 &position, Ogre::Vector3 &orientation)
Definition: MeshPoseTool.cpp:189


rviz_map_plugin
Author(s): Sebastian Pütz , Kristin Schmidt , Jan Philipp Vogtherr , Malte kleine Piening
autogenerated on Sun Jan 21 2024 04:06:25