SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
AppNodeSceneView.cpp
Go to the documentation of this file.
1 /**
2  * \file AppNodeSceneView.cpp
3  * \brief Node transform test app to demonstrates all transforms of SLNode
4  * \date July 2015
5  * \remarks Please use clangformat to format the code. See more code style on
6  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
7  * \authors Marc Wacker, Marcus Hudritsch
8  * \copyright http://opensource.org/licenses/GPL-3.0
9 */
10 
11 #include <AppCommon.h>
12 #include <AppNodeGui.h>
13 #include <AppNodeSceneView.h>
14 
15 #include <SLAssimpImporter.h>
16 #include <SLAssetManager.h>
17 #include <SLBox.h>
18 #include <SLGLVertexArrayExt.h>
19 #include <SLLightSpot.h>
20 #include <SLTexFont.h>
21 #include <GlobalTimer.h>
22 
23 //-----------------------------------------------------------------------------
24 /*! AppNodeSceneView inherits the base class SLSceneView and overrides some
25  eventhandler.
26  Most events such as all mouse and keyboard events from the OS is forwarded to
27  SLSceneview. SLSceneview implements a default behaviour. If you want a
28  different or additional behaviour for a certain eventhandler you have to sub-
29  class SLSceneView and override the eventhandler.
30  */
32  int dpi,
33  SLInputManager& inputManager)
34  : SLSceneView(s, dpi, inputManager),
35  _modifiers(K_none),
36  _continuousInput(true),
37  _curMode(TranslationMode),
38  _curObject(nullptr),
39  _curSpace(TS_parent)
40 {
41  for (bool& ks : _keyStates)
42  ks = false;
43 
44  _pivotPos.set(0, 0, 0);
45 }
46 //-----------------------------------------------------------------------------
48 {
49 }
50 //-----------------------------------------------------------------------------
52 {
53  _moveBox = _s->root3D()->findChild<SLNode>("Parent");
54  _moveBoxChild = _s->root3D()->findChild<SLNode>("Child");
55  _axesNode = _s->root3D()->findChild<SLNode>("Axes");
56 
57  if (!_curObject)
58  {
61  }
62 
65 }
66 //-----------------------------------------------------------------------------
68 {
69  static SLfloat lastTime = GlobalTimer::timeS();
70  SLfloat currentTime = GlobalTimer::timeS();
71  _deltaTime = currentTime - lastTime;
72  lastTime = currentTime;
73 
74  if (_keyStates['W'])
75  if (_deltaTime > 0.1f)
76  cout << _deltaTime << endl;
77 
78  bool updated = false;
79  for (int i = 0; i < 65536; ++i)
80  {
81  if (_keyStates[i])
82  updated = onContinuousKeyPress((SLKey)i);
83  }
84 
85  if (updated)
86  {
89  }
90 }
91 //-----------------------------------------------------------------------------
93 {
94  _pivotPos.set(0, 0, 0);
97 }
98 //-----------------------------------------------------------------------------
100 {
101  if (_continuousInput)
102  val *= _deltaTime;
103  else
104  val *= 0.1f;
105 
107 }
108 //-----------------------------------------------------------------------------
110 {
111  SLfloat angle = 22.5;
112  if (_continuousInput)
113  angle *= _deltaTime;
114 
115  _curObject->rotate(angle, val, _curSpace);
116 }
117 //-----------------------------------------------------------------------------
119 {
120  SLfloat angle = 22.5;
121  if (_continuousInput)
122  angle *= _deltaTime;
123 
125 }
126 //-----------------------------------------------------------------------------
128 {
129  if (_continuousInput)
130  val *= _deltaTime;
131  else
132  val *= 0.1f;
133 
134  _pivotPos += val;
135 }
136 //-----------------------------------------------------------------------------
138 {
139  if (!_continuousInput)
140  _keyStates[key] = false;
141 
142  if (_curMode == TranslationMode)
143  {
144  switch (key)
145  {
146  case 'W': translateObject(SLVec3f(0, 0, -1)); return true;
147  case 'S': translateObject(SLVec3f(0, 0, 1)); return true;
148  case 'A': translateObject(SLVec3f(-1, 0, 0)); return true;
149  case 'D': translateObject(SLVec3f(1, 0, 0)); return true;
150  case 'Q': translateObject(SLVec3f(0, 1, 0)); return true;
151  case 'E': translateObject(SLVec3f(0, -1, 0)); return true;
152  }
153  }
154  else if (_curMode == RotationMode)
155  {
156  switch (key)
157  {
158  case 'W': rotateObject(SLVec3f(-1, 0, 0)); return true;
159  case 'S': rotateObject(SLVec3f(1, 0, 0)); return true;
160  case 'A': rotateObject(SLVec3f(0, 1, 0)); return true;
161  case 'D': rotateObject(SLVec3f(0, -1, 0)); return true;
162  case 'Q': rotateObject(SLVec3f(0, 0, 1)); return true;
163  case 'E': rotateObject(SLVec3f(0, 0, -1)); return true;
164  }
165  }
166  else if (_curMode == RotationAroundMode)
167  {
168  if (_modifiers & K_shift)
169  {
170  switch (key)
171  {
172  case 'W': translatePivot(SLVec3f(0, 0, -1)); return true;
173  case 'S': translatePivot(SLVec3f(0, 0, 1)); return true;
174  case 'A': translatePivot(SLVec3f(-1, 0, 0)); return true;
175  case 'D': translatePivot(SLVec3f(1, 0, 0)); return true;
176  case 'Q': translatePivot(SLVec3f(0, 1, 0)); return true;
177  case 'E': translatePivot(SLVec3f(0, -1, 0)); return true;
178  }
179  }
180  else
181  {
182  switch (key)
183  {
184  case 'W': rotateObjectAroundPivot(SLVec3f(-1, 0, 0)); return true;
185  case 'S': rotateObjectAroundPivot(SLVec3f(1, 0, 0)); return true;
186  case 'A': rotateObjectAroundPivot(SLVec3f(0, -1, 0)); return true;
187  case 'D': rotateObjectAroundPivot(SLVec3f(0, 1, 0)); return true;
188  case 'Q': rotateObjectAroundPivot(SLVec3f(0, 0, 1)); return true;
189  case 'E': rotateObjectAroundPivot(SLVec3f(0, 0, -1)); return true;
190  }
191  }
192  }
193  else if (_curMode == LookAtMode)
194  {
195  switch (key)
196  {
197  case 'W': translatePivot(SLVec3f(0, 0, -1)); break;
198  case 'S': translatePivot(SLVec3f(0, 0, 1)); break;
199  case 'A': translatePivot(SLVec3f(-1, 0, 0)); break;
200  case 'D': translatePivot(SLVec3f(1, 0, 0)); break;
201  case 'Q': translatePivot(SLVec3f(0, 1, 0)); break;
202  case 'E': translatePivot(SLVec3f(0, -1, 0)); break;
203  }
204 
205  // if we look at a point in local space then the local space will change.
206  // we want to keep the old look at position in world space though so that
207  // the user can confirm that his object is in fact looking at the point it should.
208  if (_curSpace == TS_object)
209  {
210  SLVec3f pivotWorldPos = _curObject->updateAndGetWM() * _pivotPos;
212  _pivotPos = _curObject->updateAndGetWMI() * pivotWorldPos;
213  }
214  else // else just look at the point
216 
217  return true;
218  }
219  return false;
220 }
221 //-----------------------------------------------------------------------------
223 {
224  _keyStates[key] = true;
225  _modifiers = mod;
226 
227  switch (key)
228  {
229  // general input
230  case '1': _curMode = TranslationMode; break;
231  case '2': _curMode = RotationMode; break;
232  case '3': _curMode = RotationAroundMode; break;
233  case '4': _curMode = LookAtMode; break;
234 
235  // select parent object
236  case K_F1:
239  _curObject->mesh());
240  break;
241  case K_F2: _continuousInput = !_continuousInput; break;
242  case 'R': reset(); break;
243  case 'Y':
244  case 'Z': _curSpace = TS_object; break;
245  case 'X': _curSpace = TS_parent; break;
246  case 'C': _curSpace = TS_world; break;
247  }
248 
249  updateInfoText();
250  updateCurOrigin();
251 
252  return false;
253 }
254 //-----------------------------------------------------------------------------
256 {
257  _keyStates[key] = false;
258  _modifiers = mod;
259 
260  return false;
261 }
262 //-----------------------------------------------------------------------------
264 {
265  switch (_curSpace)
266  {
267  case TS_world:
270  break;
271 
272  case TS_parent:
273  _curOrigin.setMatrix(_curObject->parent()->updateAndGetWM());
274  _axesNode->om(_curObject->parent()->updateAndGetWM());
275  break;
276 
277  case TS_object:
280  break;
281  }
282 
283  // if in rotation mode, move the axis to the objects origin, but keep the orientation
285  {
287  }
288  // look at nd rotate around mode both move the pivot relative to the current system
290  {
292  }
293 
294  _curOrigin;
295 }
296 //-----------------------------------------------------------------------------
298 {
299  SLchar m[2550]; // message character array
300  m[0] = 0; // set zero length
301 
302  SLstring keyBinds;
303  keyBinds = "Key bindings: \n";
304  keyBinds += "F1: toggle current object \n";
305  keyBinds += "F2: toggle continuous input \n\n";
306  keyBinds += "1: translation mode \n";
307  keyBinds += "2: rotation mode \n";
308  keyBinds += "3: rotate around point mode \n";
309  keyBinds += "4: look at mode \n\n";
310 
311  keyBinds += "Y: Set relative space to Object\n";
312  keyBinds += "X: Set relative space to Parent\n";
313  keyBinds += "C: Set relative space to World\n\n";
314 
315  SLstring space;
316  switch (_curSpace)
317  {
318  case TS_object: space = "TS_Object"; break;
319  case TS_parent: space = "TS_Parent"; break;
320  case TS_world: space = "TS_World"; break;
321  }
322 
323  SLstring mode;
324  switch (_curMode)
325  {
326  case TranslationMode:
327  mode = "Translate";
328  keyBinds += "W: forward in " + space + " space \n";
329  keyBinds += "S: backward in " + space + " space \n";
330  keyBinds += "A: left in " + space + " space \n";
331  keyBinds += "D: right in " + space + " space \n";
332  keyBinds += "Q: up in " + space + " space \n";
333  keyBinds += "E: down in " + space + " space \n";
334  break;
335  case RotationMode:
336  mode = "Rotate";
337  keyBinds += "W: rotate around -X in " + space + "\n";
338  keyBinds += "S: rotate around X in " + space + "\n";
339  keyBinds += "A: rotate around Y in " + space + "\n";
340  keyBinds += "D: rotate around -Y in " + space + "\n";
341  keyBinds += "Q: rotate around Z in " + space + "\n";
342  keyBinds += "E: rotate around -Z in " + space + "\n";
343  break;
344  case RotationAroundMode:
345  mode = "RotateAround";
346  keyBinds += "W: rotate around -X in " + space + "\n";
347  keyBinds += "S: rotate around X in " + space + "\n";
348  keyBinds += "A: rotate around -Y in " + space + "\n";
349  keyBinds += "D: rotate around Y in " + space + "\n";
350  keyBinds += "Q: rotate around Z in " + space + "\n";
351  keyBinds += "E: rotate around -Z in " + space + "\n\n";
352 
353  keyBinds += "Shift-W: pivot forward in " + space + "\n";
354  keyBinds += "Shift-S: pivot left in " + space + "\n";
355  keyBinds += "Shift-A: pivot backward in " + space + "\n";
356  keyBinds += "Shift-D: pivot right in " + space + "\n";
357  keyBinds += "Shift-Q: pivot up in " + space + "\n";
358  keyBinds += "Shift-E: pivot down in " + space + "\n";
359  break;
360  case LookAtMode:
361  mode = "LookAt";
362  keyBinds += "W: move lookAt point forward in " + space + "\n";
363  keyBinds += "S: move lookAt point left in " + space + "\n";
364  keyBinds += "A: move lookAt point backward in " + space + "\n";
365  keyBinds += "D: move lookAt point right in " + space + "\n";
366  keyBinds += "Q: move lookAt point up in " + space + "\n";
367  keyBinds += "E: move lookAt point down in " + space + "\n";
368  break;
369  }
370 
371  keyBinds += "\nR: Reset \n";
372  snprintf(m + strlen(m), sizeof(m), "%s", keyBinds.c_str());
373 
374  SLTexFont* f = SLAssetManager::getFont(1.2f, dpi());
376 }
377 //-----------------------------------------------------------------------------
The AppCommon class holds the top-level instances of the app-demo.
static SLint dpi
Dot per inch resolution of screen.
Definition: AppGLFW.cpp:41
Node transform test app to demonstrates all transforms of SLNode.
@ RotationMode
@ RotationAroundMode
@ LookAtMode
@ TranslationMode
float SLfloat
Definition: SL.h:173
char SLchar
Definition: SL.h:162
bool SLbool
Definition: SL.h:175
string SLstring
Definition: SL.h:158
@ TS_world
Definition: SLEnums.h:208
@ TS_parent
Definition: SLEnums.h:209
@ TS_object
Definition: SLEnums.h:210
SLKey
Keyboard key codes enumeration.
Definition: SLEnums.h:16
@ K_F2
Definition: SLEnums.h:50
@ K_F1
Definition: SLEnums.h:49
@ K_none
Definition: SLEnums.h:17
@ K_shift
Definition: SLEnums.h:62
Extension class with functions for quick line & point drawing.
SLVec3< SLfloat > SLVec3f
Definition: SLVec3.h:318
static WAI::ModeOrbSlam2 * mode
Definition: WAIInterface.cpp:5
static SLScene * scene
Pointer to the one and only SLScene instance.
Definition: AppCommon.h:61
static SLstring infoText
Definition: AppNodeGui.h:36
void rotateObject(const SLVec3f &val) const
SLNode * _curObject
current object to transform
SLNode * _moveBoxChild
little child cube
TransformMode _curMode
current transform mode
SLNode * _moveBox
big parent cube
void translateObject(SLVec3f vec) const
SLbool onContinuousKeyPress(SLKey key)
AppNodeSceneView(SLScene *s, int dpi, SLInputManager &inputManager)
SLKey _modifiers
pressed modifier keys
bool _keyStates[65536]
key press states of all keys
void translatePivot(SLVec3f vec)
SLbool onKeyPress(const SLKey key, const SLKey mod)
SLNode * _axesNode
node for axis mesh
SLMat4f _curOrigin
current origin of relative space (orientation and position of axes)
SLbool onKeyRelease(const SLKey key, const SLKey mod)
bool _continuousInput
flag for continuous input processing
void rotateObjectAroundPivot(SLVec3f val) const
SLVec3f _pivotPos
position of the pivot point
SLTransformSpace _curSpace
current transform space
SLfloat _deltaTime
delta time of a frame
static float timeS()
Definition: GlobalTimer.cpp:20
static SLTexFont * getFont(SLfloat heightMM, SLint dpi)
returns nearest font for a given height in mm
SLInputManager. manages system input and custom input devices.
SLVec3< T > translation() const
Definition: SLMat4.h:184
void setMatrix(const SLMat4 &A)
Set matrix by other 4x4 matrix.
Definition: SLMat4.h:335
void identity()
Sets the identity matrix.
Definition: SLMat4.h:1333
SLNode represents a node in a hierarchical scene graph.
Definition: SLNode.h:147
void resetToInitialState()
Definition: SLNode.cpp:1092
void translation(const SLVec3f &pos, SLTransformSpace relativeTo=TS_parent)
Definition: SLNode.cpp:828
void parent(SLNode *p)
Definition: SLNode.cpp:600
void rotate(const SLQuat4f &rot, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:945
const SLMat4f & updateAndGetWM() const
Definition: SLNode.cpp:703
SLMesh * mesh()
Definition: SLNode.h:304
void om(const SLMat4f &mat)
Definition: SLNode.h:276
const SLMat4f & updateAndGetWMI() const
Definition: SLNode.cpp:714
void lookAt(SLfloat targetX, SLfloat targetY, SLfloat targetZ, SLfloat upX=0, SLfloat upY=1, SLfloat upZ=0, SLTransformSpace relativeTo=TS_world)
Definition: SLNode.h:652
void rotateAround(const SLVec3f &point, SLVec3f &axis, SLfloat angleDeg, SLTransformSpace relativeTo=TS_world)
Definition: SLNode.cpp:979
void translate(const SLVec3f &vec, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:906
The SLScene class represents the top level instance holding the scene structure.
Definition: SLScene.h:47
void selectNodeMesh(SLNode *nodeToSelect, SLMesh *meshToSelect)
Handles the full mesh selection from double-clicks.
Definition: SLScene.cpp:234
void root3D(SLNode *root3D)
Definition: SLScene.h:78
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
SLint dpi() const
Definition: SLSceneView.h:175
SLScene * _s
Pointer to the scene observed by this scene view.
Definition: SLSceneView.h:224
Texture Font class inherits SLGLTexture for alpha blended font rendering.
Definition: SLTexFont.h:40
T y
Definition: SLVec3.h:43
static SLVec3 AXISY
Definition: SLVec3.h:298
T x
Definition: SLVec3.h:43
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
T z
Definition: SLVec3.h:43
T mod(T a, T b)
Definition: Utils.h:250