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