RobotViewer.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #include "RobotViewer.h"
25 
27 
28 #include <Inventor/events/SoLocation2Event.h>
29 #include <Inventor/events/SoMouseButtonEvent.h>
30 #include <Inventor/nodes/SoDrawStyle.h>
31 #include <Inventor/nodes/SoLineSet.h>
32 #include <Inventor/nodes/SoMaterial.h>
33 #include <Inventor/nodes/SoPickStyle.h>
34 #include <Inventor/nodes/SoSelection.h>
35 #include <Inventor/nodes/SoSeparator.h>
36 #include <Inventor/nodes/SoVertexProperty.h>
37 
38 armarx::RobotViewer::RobotViewer(QWidget* widget) :
39  SoQtExaminerViewer(widget),
40  sceneRootNode(new SoSeparator),
41  contentRootNode(new SoSelection),
42  camera(new SoPerspectiveCamera)
43 {
44  this->setBackgroundColor(SbColor(150 / 255.0f, 150 / 255.0f, 150 / 255.0f));
45  this->setAccumulationBuffer(true);
46  this->setHeadlight(true);
47  this->setViewing(false);
48  this->setDecoration(false);
49 #ifdef WIN32
50 #ifndef _DEBUG
51  this->setAntialiasing(true, 4);
52 #endif
53 #endif
54  this->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
55  this->setFeedbackVisibility(true);
56 
57  //Create scene root node
58  sceneRootNode->ref();
59  this->setSceneGraph(sceneRootNode);
60 
61  //Add camera to scene
62  sceneRootNode->addChild(camera);
63  this->setCamera(camera);
64 
65  //Give camera standard position
66  camera->position.setValue(SbVec3f(10, -10, 5));
67  camera->pointAt(SbVec3f(0, 0, 0), SbVec3f(0, 0, 1));
68 
69  //Add gridfloor root and make it unpickable
70  SoSeparator* gridFloorRoot = new SoSeparator();
71  SoPickStyle* unpickable = new SoPickStyle();
72  unpickable->style = SoPickStyle::UNPICKABLE;
73  SoPickStyle* pickable = new SoPickStyle();
74  pickable->style = SoPickStyle::SHAPE;
75 
76  sceneRootNode->addChild(unpickable);
77  sceneRootNode->addChild(gridFloorRoot);
78  sceneRootNode->addChild(pickable);
79 
80  /*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81  Here we draw our grid floor. To change the way the grid floor is drawn change the following constants.
82  GRIDSIZE: How many lines to display for each direction of each axis.
83  E. g.: 2 would lead to 2 lines in negative and positive direction respectively, plus indicator for axis.
84  5 lines in sum.
85  GRIDUNIT: Factor for coin units, e.g. 2 means between 2 lines there is space for 2 coin units.
86  GRIDSUBSIZE: How many subunits to display between the larger lines. So 5 would lead to 3 lines between 2 large lines for 5
87  subunits.
88  GRIDPATTERN: Pattern for sublines. Bitpattern, where 1 is line and 0 is no line.
89  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
90  const int GRIDSIZE = 3;
91  const int GRIDUNIT = 15;
92  const int GRIDSUBSIZE = 10;
93  const unsigned short GRIDPATTERN = 0xCCCC;
94 
95  //Red material for X axis
96  SoMaterial* red = new SoMaterial;
97  red->diffuseColor = SbColor(1, 0, 0);
98  //Green material for Y axis
99  SoMaterial* green = new SoMaterial;
100  green->diffuseColor = SbColor(0, 1, 0);
101  //Blue material for Z axis
102  SoMaterial* blue = new SoMaterial;
103  blue->diffuseColor = SbColor(0, 0, 1);
104 
105  //Small lines
106  SoDrawStyle* thinStyle = new SoDrawStyle;
107  thinStyle->lineWidth = 1;
108  thinStyle->linePattern = GRIDPATTERN;
109  //Larger lines
110  SoDrawStyle* largeStyle = new SoDrawStyle;
111  largeStyle->lineWidth = 2;
112 
113  //Our set of vertices for the grid lines
114  SoVertexProperty* vertices = new SoVertexProperty;
115  SoVertexProperty* subVertices = new SoVertexProperty;
116  SoVertexProperty* xVertices = new SoVertexProperty;
117  SoVertexProperty* yVertices = new SoVertexProperty;
118  SoVertexProperty* zVertices = new SoVertexProperty;
119 
120  //Definition of which vertex belongs to which line and should be connected
121  SoLineSet* lines = new SoLineSet;
122  SoLineSet* subLines = new SoLineSet;
123  SoLineSet* xLines = new SoLineSet;
124  SoLineSet* yLines = new SoLineSet;
125  SoLineSet* zLines = new SoLineSet;
126 
127  //Add 2 vertices for X axis
128  xVertices->vertex.set1Value(0, GRIDSIZE * GRIDUNIT, 0, 0);
129  xVertices->vertex.set1Value(1, -(GRIDSIZE * GRIDUNIT), 0, 0);
130  //Connect them to a line by adding '2' to numVertices at the correct position
131  xLines->numVertices.set1Value(0, 2);
132 
133  //Y axis
134  yVertices->vertex.set1Value(0, 0, GRIDSIZE * GRIDUNIT, 0);
135  yVertices->vertex.set1Value(1, 0, -(GRIDSIZE * GRIDUNIT), 0);
136  yLines->numVertices.set1Value(0, 2);
137 
138  //Z axis
139  zVertices->vertex.set1Value(0, 0, 0, GRIDSIZE * GRIDUNIT);
140  zVertices->vertex.set1Value(1, 0, 0, -(GRIDSIZE * GRIDUNIT));
141  zLines->numVertices.set1Value(0, 2);
142 
143  //Counters to keep track of vertex index
144  int verticescounter = 0;
145  int subverticescounter = 0;
146 
147  //Draw all lines parallel to the X and Y axis and all sublines, excepted axis itself
148  for (int i = -(GRIDSIZE * GRIDUNIT); i < GRIDUNIT * (GRIDSIZE + 1); i += GRIDUNIT)
149  {
150  if (i != 0)
151  {
152  vertices->vertex.set1Value(verticescounter++, GRIDSIZE * GRIDUNIT, i, 0);
153  vertices->vertex.set1Value(verticescounter++, -(GRIDSIZE * GRIDUNIT), i, 0);
154  lines->numVertices.set1Value((verticescounter - 1) / 2, 2);
155 
156  vertices->vertex.set1Value(verticescounter++, i, GRIDSIZE * GRIDUNIT, 0);
157  vertices->vertex.set1Value(verticescounter++, i, -(GRIDSIZE * GRIDUNIT), 0);
158  lines->numVertices.set1Value((verticescounter - 1) / 2, 2);
159  }
160 
161  //If this is not the last line to draw, draw sublines
162  if (i < GRIDUNIT * GRIDSIZE)
163  {
164  float delta = (float)GRIDUNIT / (float)GRIDSUBSIZE;
165 
166  for (int n = 1; n < GRIDSUBSIZE; n++)
167  {
168  subVertices->vertex.set1Value(
169  subverticescounter++, GRIDSIZE * GRIDUNIT, (float)i + (float)n * delta, 0);
170  subVertices->vertex.set1Value(
171  subverticescounter++, -(GRIDSIZE * GRIDUNIT), (float)i + (float)n * delta, 0);
172  subLines->numVertices.set1Value((subverticescounter - 1) / 2, 2);
173 
174  subVertices->vertex.set1Value(
175  subverticescounter++, (float)i + (float)n * delta, GRIDSIZE * GRIDUNIT, 0);
176  subVertices->vertex.set1Value(
177  subverticescounter++, (float)i + (float)n * delta, -(GRIDSIZE * GRIDUNIT), 0);
178  subLines->numVertices.set1Value((subverticescounter - 1) / 2, 2);
179  }
180  }
181  }
182 
183 
184  lines->vertexProperty.setValue(vertices);
185  subLines->vertexProperty.setValue(subVertices);
186  xLines->vertexProperty.setValue(xVertices);
187  yLines->vertexProperty.setValue(yVertices);
188  zLines->vertexProperty.setValue(zVertices);
189 
190  gridFloorRoot->addChild(thinStyle);
191  gridFloorRoot->addChild(subLines);
192  gridFloorRoot->addChild(largeStyle);
193  gridFloorRoot->addChild(lines);
194  gridFloorRoot->addChild(red);
195  gridFloorRoot->addChild(xLines);
196  gridFloorRoot->addChild(green);
197  gridFloorRoot->addChild(yLines);
198  gridFloorRoot->addChild(blue);
199  gridFloorRoot->addChild(zLines);
200 
201  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
202  //Gridfloor done
203 
204  //Create content root node
205  sceneRootNode->addChild(contentRootNode);
206 }
207 
208 armarx::RobotViewer::~RobotViewer()
209 {
210  sceneRootNode->unref();
211 }
212 
213 SoSelection*
214 armarx::RobotViewer::getRootNode()
215 {
216  return this->contentRootNode;
217 }
218 
219 void
220 armarx::RobotViewer::cameraViewAll()
221 {
222  camera->viewAll(this->contentRootNode, SbViewportRegion());
223 }
224 
225 //Override the default navigation behaviour of the SoQtExaminerViewer
226 SbBool
227 armarx::RobotViewer::processSoEvent(const SoEvent* const event)
228 {
229  const SoType type(event->getTypeId());
230 
231  //Remapping mouse press events
232  if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId()))
233  {
234  SoMouseButtonEvent* const ev = (SoMouseButtonEvent*)event;
235  const int button = ev->getButton();
236  const SbBool press = ev->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
237 
238  //LEFT MOUSE BUTTON
239  if (button == SoMouseButtonEvent::BUTTON1)
240  {
241  SoQtExaminerViewer::processSoEvent(ev);
242  }
243 
244  //MIDDLE MOUSE BUTTON
245  if (button == SoMouseButtonEvent::BUTTON3)
246  {
247  /*Middle mouse button now is used for all changes in camera perspective.
248  To also display the cool little rotation cursor, viewing mode is set to on
249  while button is down*/
250 
251  //Enable or disable viewing mode while BUTTON3 pressed
252  if (press)
253  {
254  if (!this->isViewing())
255  {
256  this->setViewing(true);
257  }
258  }
259  else
260  {
261  if (this->isViewing())
262  {
263  this->setViewing(false);
264  }
265  }
266 
267  //Remap BUTTON3 to BUTTON1
268  ev->setButton(SoMouseButtonEvent::BUTTON1);
269 
270  //Make sure this REALLY only can happen when viewing mode is on.
271  //Zooming can also turn it on and it leads to weird effects when doing both
272  //(deselections in scene etc.) because SoQtExaminerViewer passes BUTTON1
273  //events up to scenegraph when not in viewing mode.
274  if (this->isViewing())
275  {
276  //ARMARX_WARNING << "PROCESS";
277  return SoQtExaminerViewer::processSoEvent(ev);
278  //ARMARX_WARNING << "PROCESS END";
279  }
280  }
281 
282  //MOUSE WHEEL UP AND DOWN
283  if ((button == SoMouseButtonEvent::BUTTON4 || button == SoMouseButtonEvent::BUTTON5))
284  {
285  /*Zooming is allowed, so just use it. We have to temporarily turn viewing mode
286  on to make SoQtExaminerViewer allow zooming.*/
287 
288  //Swap BUTTON4 and BUTTON5 because zooming out while scrolling up is just retarded
289  ev->setButton(button == SoMouseButtonEvent::BUTTON4 ? SoMouseButtonEvent::BUTTON5
290  : SoMouseButtonEvent::BUTTON4);
291 
292  //Zooming is allowed, so just pass it and temporarily set viewing mode on, if it is not already
293  //(otherwise coin gives us warning messages...)
294  if (!this->isViewing())
295  {
296  if (!this->isViewing())
297  {
298  this->setViewing(true);
299  }
300 
301  SoQtExaminerViewer::processSoEvent(ev);
302 
303  if (this->isViewing())
304  {
305  this->setViewing(false);
306  }
307  }
308  else
309  {
310  SoQtExaminerViewer::processSoEvent(ev);
311  }
312 
313  return TRUE;
314  }
315  }
316 
317  // Keyboard handling
318  if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId()))
319  {
320  const SoKeyboardEvent* const ev = (const SoKeyboardEvent*)event;
321 
322  /*The escape key and super key (windows key) is used to switch between
323  viewing modes. We need to disable this behaviour completely.*/
324 
325  //65513 seems to be the super key, which is not available in the enum of keys in coin....
326  if (ev->getKey() == SoKeyboardEvent::ESCAPE || ev->getKey() == 65513 ||
327  ev->getKey() == SoKeyboardEvent::LEFT_CONTROL)
328  {
329  return TRUE;
330  }
331  /*else if (ev->getKey() == SoKeyboardEvent::S && ev->getState() == SoButtonEvent::DOWN)
332  {
333  if (!this->isSeekMode())
334  {
335  if (!this->isViewing())
336  {
337  this->setViewing(true);
338  }
339 
340  SoQtExaminerViewer::processSoEvent(ev);
341  this->setSeekTime(0.5);
342  this->seekToPoint(ev->getPosition());
343 
344  if (this->isViewing())
345  {
346  this->setViewing(false);
347  }
348  }
349  }*/
350  else
351  {
352  SoQtExaminerViewer::processSoEvent(ev);
353  }
354 
355  SoQtExaminerViewer::processSoEvent(ev);
356  }
357 
358  //Let all move events trough
359  if (type.isDerivedFrom(SoLocation2Event::getClassTypeId()))
360  {
361  //ARMARX_WARNING << "EVENT START";
362  return SoQtExaminerViewer::processSoEvent(event);
363  //ARMARX_WARNING << "EVENT END";
364  }
365  //ARMARX_WARNING << "YOU SHALL NOT PASS!";
366  //YOU SHALL NOT PASS!
367  return TRUE;
368 
369  return SoQtExaminerViewer::processSoEvent(event);
370 }
RobotViewer.h
Logging.h
armarx::RobotViewer::RobotViewer
RobotViewer(QWidget *widget)
Definition: RobotViewer.cpp:35