SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLCamera.cpp
Go to the documentation of this file.
1 /**
2  * \file SLCamera.cpp
3  * \date July 2014
4  * \authors Marc Wacker, Marcus Hudritsch
5  * \copyright http://opensource.org/licenses/GPL-3.0
6  * \remarks Please use clangformat to format the code. See more code style on
7  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
8  */
9 
10 #include "SL.h"
11 #include <SLSceneView.h>
12 #include <SLDeviceLocation.h>
13 #include <SLDeviceRotation.h>
14 #include <SLGLProgramManager.h>
15 #include <SLFrustum.h>
16 
17 //-----------------------------------------------------------------------------
18 // Static global default parameters for new cameras
23 //-----------------------------------------------------------------------------
24 /**
25  * @brief Construct a new SLCamera::SLCamera object
26  * @remarks It is important that during instantiation NO OpenGL functions (gl*)
27  * get called because this constructor will be most probably called in a parallel
28  * thread from within a SLScene::assemble function. All objects that get rendered
29  * have to do their OpenGL initialization when they are used the first time
30  * during rendering in the main thread.
31  * @param name Name of the camera
32  */
34  : SLNode(name),
35  _movedLastFrame(false),
36  _oldTouchPos1(0, 0),
37  _oldTouchPos2(0, 0),
38  _trackballSize(0.8f),
39  _drag(0.05f),
40  _maxSpeed(0.0f),
41  _velocity(0.0f, 0.0f, 0.0f),
42  _acceleration(0, 0, 0),
43  _brakeAccel(16.0f),
44  _moveAccel(16.0f),
45  _unitScaling(1.0f),
46  _fogIsOn(false),
47  _fogMode(FM_linear),
48  _fogDensity(0.1f),
49  _fogStart(1.0f),
50  _fogEnd(6.0f),
51  _fogColor(SLCol4f::GRAY),
52  _fogColorIsBack(true),
53  _viewport(0, 0, 640, 480),
56  _onCamUpdateCB(nullptr)
57 {
58  _fovInit = 0;
59  _viewportRatio = 640.0f / 480.0f; // will be overwritten in setProjection
60  _clipNear = 0.1f;
61  _clipFar = 300.0f;
62  _fovV = 45.0;
65  _castsShadows = false;
66 
67  // depth of field parameters
68  _lensDiameter = 0.3f;
69  _lensSamples.samples(1, 1); // e.g. 10,10 > 10x10=100 lens samples
70  _focalDist = 5;
72 
73  _background.colors(SLCol4f(0.6f, 0.6f, 0.6f), SLCol4f(0.3f, 0.3f, 0.3f));
74 
76 
77  // Set the state of all movement keys to released.
78  _keyStates['W'] = false;
79  _keyStates['A'] = false;
80  _keyStates['S'] = false;
81  _keyStates['D'] = false;
82  _keyStates['Q'] = false;
83  _keyStates['E'] = false;
84  _keyStates[(SLchar)K_up] = false;
85  _keyStates[(SLchar)K_down] = false;
86  _keyStates[(SLchar)K_right] = false;
87  _keyStates[(SLchar)K_left] = false;
88 }
89 //-----------------------------------------------------------------------------
91 {
92 }
93 //-----------------------------------------------------------------------------
94 /*! SLCamera::camUpdate does the smooth transition for the walk animation. It
95 is called in every frame. It moves the camera after the key was released and
96 smoothly stops the motion by decreasing the speed every frame.
97 */
99 {
100  // call option update callback
101  if (_onCamUpdateCB)
103 
104  SLVec3f moveDir(0, 0, 0);
105  if (_keyStates['W'] || _keyStates[(SLchar)K_up]) moveDir.z -= 1.0;
106  if (_keyStates['A'] || _keyStates[(SLchar)K_left]) moveDir.x -= 1.0;
107  if (_keyStates['S'] || _keyStates[(SLchar)K_down]) moveDir.z += 1.0;
108  if (_keyStates['D'] || _keyStates[(SLchar)K_right]) moveDir.x += 1.0;
109  if (_keyStates['Q']) moveDir.y -= 1.0;
110  if (_keyStates['E']) moveDir.y += 1.0;
111 
112  if (_velocity == SLVec3f::ZERO && moveDir == SLVec3f::ZERO)
113  {
114  return false;
115  }
116 
117  if (!_movedLastFrame)
118  {
119  _movedLastFrame = true;
120  return true;
121  }
122 
123  SLfloat dtS = elapsedTimeMS * 0.001f;
124 
125  SLbool braking = false;
126  if (moveDir != SLVec3f::ZERO)
127  {
128  // x and z movement direction vector should be projected on the x,z plane while
129  // but still in local space
130  // the y movement direction should always be in world space
131  SLVec3f f = forwardOS();
132  f.y = 0;
133  f.normalize();
134 
135  SLVec3f r = rightOS();
136  r.y = 0;
137  r.normalize();
138 
139  _acceleration = f * -moveDir.z + r * moveDir.x;
140  _acceleration.y = moveDir.y;
143 
144  } // accelerate in the opposite velocity to brake
145  else
146  {
148  braking = true;
149  }
150 
151  // accelerate
152  SLVec3f increment = _acceleration * dtS; // all units in m/s, convert MS to S
153 
154  // early out if we're braking and the velocity would fall < 0
155  if (braking && increment.lengthSqr() > _velocity.lengthSqr())
156  {
158  _movedLastFrame = false;
159  return false;
160  }
161 
162  _velocity += increment - _drag * _velocity * dtS;
163  SLfloat velMag = _velocity.length();
164 
165  // don't go over max speed
166  SLfloat maxSpeed = _maxSpeed > 0.0f ? _maxSpeed : _clipFar / 50.0f;
167  if (velMag > maxSpeed)
169 
170  // final delta movement vector
171  SLVec3f delta = _velocity * dtS;
172 
173  // adjust for scaling (if the character is shrinked or enlarged)
174  delta *= _unitScaling;
175 
176  translate(delta, TS_world);
177 
178  _movedLastFrame = true;
179  return true;
180 }
181 
182 //-----------------------------------------------------------------------------
183 //! SLCamera::drawMeshes draws the cameras frustum lines
184 /*!
185 Only draws the frustum lines without lighting when the camera is not the
186 active one. This means that it can be seen from the active view point.
187 */
189 {
190  if (sv->camera() != this)
191  {
192  // Vertices of the far plane
193  SLVec3f farRT, farRB, farLT, farLB;
194 
196  {
197  const SLMat4f& vm = updateAndGetWMI();
198  SLVVec3f P;
199  SLVec3f pos(vm.translation());
200  SLfloat t = tan(Utils::DEG2RAD * _fovV * 0.5f) * pos.length(); // top
201  SLfloat b = -t; // bottom
202  SLfloat l = -sv->scrWdivH() * t; // left
203  SLfloat r = -l; // right
204  SLfloat c = std::min(l, r) * 0.05f; // size of cross at focal point
205 
206  // small line in view direction
207  P.push_back(SLVec3f(0, 0, 0));
208  P.push_back(SLVec3f(0, 0, _clipNear * 4));
209 
210  // frustum pyramid lines
211  farRT.set(r, t, -_clipFar);
212  farRB.set(r, b, -_clipFar);
213  farLT.set(l, t, -_clipFar);
214  farLB.set(l, b, -_clipFar);
215  P.push_back(SLVec3f(r, t, _clipNear));
216  P.push_back(farRT);
217  P.push_back(SLVec3f(l, t, _clipNear));
218  P.push_back(farLT);
219  P.push_back(SLVec3f(l, b, _clipNear));
220  P.push_back(farLB);
221  P.push_back(SLVec3f(r, b, _clipNear));
222  P.push_back(farRB);
223 
224  // around far clipping plane
225  P.push_back(farRT);
226  P.push_back(farRB);
227  P.push_back(farRB);
228  P.push_back(farLB);
229  P.push_back(farLB);
230  P.push_back(farLT);
231  P.push_back(farLT);
232  P.push_back(farRT);
233 
234  // around projection plane at focal distance
235  P.push_back(SLVec3f(r, t, -_focalDist));
236  P.push_back(SLVec3f(r, b, -_focalDist));
237  P.push_back(SLVec3f(r, b, -_focalDist));
238  P.push_back(SLVec3f(l, b, -_focalDist));
239  P.push_back(SLVec3f(l, b, -_focalDist));
240  P.push_back(SLVec3f(l, t, -_focalDist));
241  P.push_back(SLVec3f(l, t, -_focalDist));
242  P.push_back(SLVec3f(r, t, -_focalDist));
243 
244  // cross at focal point in focal distance
245  P.push_back(SLVec3f(-c, 0, -_focalDist));
246  P.push_back(SLVec3f(c, 0, -_focalDist));
247  P.push_back(SLVec3f(0, -c, -_focalDist));
248  P.push_back(SLVec3f(0, c, -_focalDist));
249  P.push_back(SLVec3f(0, 0, -_focalDist - c));
250  P.push_back(SLVec3f(0, 0, -_focalDist + c));
251 
252  // around near clipping plane
253  P.push_back(SLVec3f(r, t, _clipNear));
254  P.push_back(SLVec3f(r, b, _clipNear));
255  P.push_back(SLVec3f(r, b, _clipNear));
256  P.push_back(SLVec3f(l, b, _clipNear));
257  P.push_back(SLVec3f(l, b, _clipNear));
258  P.push_back(SLVec3f(l, t, _clipNear));
259  P.push_back(SLVec3f(l, t, _clipNear));
260  P.push_back(SLVec3f(r, t, _clipNear));
261 
263  }
265  {
266  SLVVec3f P;
267  SLfloat aspect = sv->scrWdivH();
268  SLfloat tanFov = tan(_fovV * Utils::DEG2RAD * 0.5f);
269  SLfloat tF = tanFov * _clipFar; // top far
270  SLfloat rF = tF * aspect; // right far
271  SLfloat lF = -rF; // left far
272  SLfloat tP = tanFov * _focalDist; // top projection at focal distance
273  SLfloat rP = tP * aspect; // right projection at focal distance
274  SLfloat lP = -tP * aspect; // left projection at focal distance
275  SLfloat cP = std::min(lP, rP) * 0.05f; // size of cross at focal point
276  SLfloat tN = tanFov * _clipNear; // top near
277  SLfloat rN = tN * aspect; // right near
278  SLfloat lN = -tN * aspect; // left near
279 
280  // small line in view direction
281  P.push_back(SLVec3f(0, 0, 0));
282  P.push_back(SLVec3f(0, 0, _clipNear * 4));
283 
284  // frustum pyramid lines
285  farRT.set(rF, tF, -_clipFar);
286  farRB.set(rF, -tF, -_clipFar);
287  farLT.set(lF, tF, -_clipFar);
288  farLB.set(lF, -tF, -_clipFar);
289  P.push_back(SLVec3f(0, 0, 0));
290  P.push_back(farRT);
291  P.push_back(SLVec3f(0, 0, 0));
292  P.push_back(farLT);
293  P.push_back(SLVec3f(0, 0, 0));
294  P.push_back(farLB);
295  P.push_back(SLVec3f(0, 0, 0));
296  P.push_back(farRB);
297 
298  // around far clipping plane
299  P.push_back(farRT);
300  P.push_back(farRB);
301  P.push_back(farRB);
302  P.push_back(farLB);
303  P.push_back(farLB);
304  P.push_back(farLT);
305  P.push_back(farLT);
306  P.push_back(farRT);
307 
308  // around projection plane at focal distance
309  P.push_back(SLVec3f(rP, tP, -_focalDist));
310  P.push_back(SLVec3f(rP, -tP, -_focalDist));
311  P.push_back(SLVec3f(rP, -tP, -_focalDist));
312  P.push_back(SLVec3f(lP, -tP, -_focalDist));
313  P.push_back(SLVec3f(lP, -tP, -_focalDist));
314  P.push_back(SLVec3f(lP, tP, -_focalDist));
315  P.push_back(SLVec3f(lP, tP, -_focalDist));
316  P.push_back(SLVec3f(rP, tP, -_focalDist));
317 
318  // cross at focal point in focal distance
319  P.push_back(SLVec3f(-cP, 0, -_focalDist));
320  P.push_back(SLVec3f(cP, 0, -_focalDist));
321  P.push_back(SLVec3f(0, -cP, -_focalDist));
322  P.push_back(SLVec3f(0, cP, -_focalDist));
323  P.push_back(SLVec3f(0, 0, -_focalDist - cP));
324  P.push_back(SLVec3f(0, 0, -_focalDist + cP));
325 
326  // around near clipping plane
327  P.push_back(SLVec3f(rN, tN, -_clipNear));
328  P.push_back(SLVec3f(rN, -tN, -_clipNear));
329  P.push_back(SLVec3f(rN, -tN, -_clipNear));
330  P.push_back(SLVec3f(lN, -tN, -_clipNear));
331  P.push_back(SLVec3f(lN, -tN, -_clipNear));
332  P.push_back(SLVec3f(lN, tN, -_clipNear));
333  P.push_back(SLVec3f(lN, tN, -_clipNear));
334  P.push_back(SLVec3f(rN, tN, -_clipNear));
335 
337  }
338 
339  SLCol4f color = sv->s()->singleNodeSelected() == this ? SLCol4f::YELLOW : SLCol4f::WHITE * 0.7f;
341 
342  if (!sv->s()->skybox())
343  _background.renderInScene(updateAndGetWM(), farLT, farLB, farRT, farRB);
344  }
345 }
346 //-----------------------------------------------------------------------------
347 //! SLCamera::statsRec updates the statistic parameters
349 {
350  stats.numTriangles += 12;
351  stats.numBytes += sizeof(SLCamera);
352  SLNode::statsRec(stats);
353 }
354 //-----------------------------------------------------------------------------
355 /*!
356 SLCamera::calcMinMax calculates the axis aligned minimum and maximum point of
357 the camera position and the 4 near clipping plane points in object space (OS).
358 */
359 void SLCamera::calcMinMax(SLVec3f& minV, SLVec3f& maxV) const
360 {
361  SLVec3f P[5];
362  SLfloat tanFov = tan(_fovV * Utils::DEG2RAD * 0.5f);
363  SLfloat tN = tanFov * _clipNear; // top near
364  SLfloat rN = tN * _viewportRatio; // right near
365 
366  // The camera center
367  P[0].set(0, 0, 0);
368 
369  // around near clipping plane
370  P[1].set(rN, tN, -_clipNear);
371  P[2].set(rN, -tN, -_clipNear);
372  P[3].set(-rN, -tN, -_clipNear);
373  P[4].set(-rN, tN, -_clipNear);
374 
375  // init min & max points
376  minV.set(FLT_MAX, FLT_MAX, FLT_MAX);
377  maxV.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
378 
379  // calc min and max point of all vertices
380  for (auto& i : P)
381  {
382  if (i.x < minV.x) minV.x = i.x;
383  if (i.x > maxV.x) maxV.x = i.x;
384  if (i.y < minV.y) minV.y = i.y;
385  if (i.y > maxV.y) maxV.y = i.y;
386  if (i.z < minV.z) minV.z = i.z;
387  if (i.z > maxV.z) maxV.z = i.z;
388  }
389 }
390 //-----------------------------------------------------------------------------
391 /*!
392  SLCamera::buildAABB builds the passed axis-aligned bounding box in OS and
393  updates the min & max points in WS with the passed WM of the node. The camera
394  node has no mesh associated, so we have to calculate the min and max point
395  from the camera frustum.
396  */
397 void SLCamera::buildAABB(SLAABBox& aabb, const SLMat4f& wmNode)
398 {
399  SLVec3f minP, maxP;
400  calcMinMax(minP, maxP);
401 
402  // Apply world matrix
403  aabb.fromOStoWS(minP, maxP, wmNode);
404 }
405 
406 //-----------------------------------------------------------------------------
407 //! Calculate and return frustum size at distance to camera center
409 {
410  SLVec2f frustumSize;
411 
412  frustumSize.y = 2.f * distance * std::tan(_fovV * 0.5f * DEG2RAD);
413  frustumSize.x = frustumSize.y * _viewportRatio; // w / h
414 
415  return frustumSize;
416 }
417 //-----------------------------------------------------------------------------
418 //! Returns the projection type as string
420 {
421  switch (pt)
422  {
423  case P_monoPerspective: return "Perspective";
424  case P_monoIntrinsic: return "Perspective Intrinsic";
425  case P_monoOrthographic: return "Orthographic";
426  case P_stereoSideBySide: return "Side by Side";
427  case P_stereoSideBySideP: return "Side by Side proportional";
428  case P_stereoSideBySideD: return "Side by Side distorted";
429  case P_stereoLineByLine: return "Line by Line";
430  case P_stereoColumnByColumn: return "Column by Column";
431  case P_stereoPixelByPixel: return "Checkerboard";
432  case P_stereoColorRC: return "Red-Cyan";
433  case P_stereoColorRG: return "Red-Green";
434  case P_stereoColorRB: return "Red-Blue";
435  case P_stereoColorYB: return "Yellow-Blue";
436  default: return "Unknown";
437  }
438 }
439 //-----------------------------------------------------------------------------
440 /*!
441 Returns the height of the screen at focal distance. In stereo rendering this
442 should correspond to the height of the projection plane.
443 */
445 {
446  return tan(_fovV * Utils::DEG2RAD / 2.0f) * _focalDist * 2.0f;
447 }
448 //-----------------------------------------------------------------------------
449 /*!
450 Returns the width of the screen at focal distance. In stereo rendering this
451 should correspond to the width of the projection plane.
452 */
454 {
455  return focalDistScrH() * _viewportRatio;
456 }
457 //-----------------------------------------------------------------------------
458 //! Sets the viewport transform depending on the projection
460 {
461  SLGLState* stateGL = SLGLState::instance();
462  SLRecti vpRect = sv->viewportRect();
463  _viewportRatio = (float)vpRect.width / (float)vpRect.height;
464 
465  //////////////////
466  // Set viewport //
467  //////////////////
468 
469  // calculate frame buffer size
470  SLint fbX = vpRect.x;
471  SLint fbY = vpRect.y;
472  SLint fbW = vpRect.width;
473  SLint fbH = vpRect.height;
474  SLint fbW2 = fbW >> 1; // fbW/2
475  SLint fbH2 = fbH >> 1; // fbH/2
476  SLint fbH4 = fbH2 >> 1; // fbH2/2
477 
479  {
480  SLint fbOcW2 = sv->oculusFB()->halfWidth();
481  SLint fbOcH = sv->oculusFB()->height();
482  if (eye == ET_left)
483  stateGL->viewport(0, 0, fbOcW2, fbOcH);
484  else
485  stateGL->viewport(fbOcW2, 0, fbOcW2, fbOcH);
486  }
487  else if (_projType == P_stereoSideBySide)
488  {
489  if (eye == ET_left)
490  stateGL->viewport(0, 0, fbW2, fbH);
491  else
492  stateGL->viewport(fbW2, 0, fbW2, fbH);
493  }
494  else if (_projType == P_stereoSideBySideP)
495  {
496  if (eye == ET_left)
497  stateGL->viewport(0, fbH4, fbW2, fbH2);
498  else
499  stateGL->viewport(fbW2, fbH4, fbW2, fbH2);
500  }
501  else
502  stateGL->viewport(fbX, fbY, fbW, fbH);
503 
504  _viewport.set(fbX, fbY, fbW, fbH);
505 }
506 //-----------------------------------------------------------------------------
507 /*!
508 Sets the projection transformation matrix and the drawing buffer.
509 In case of a stereographic projection it additionally sets the
510 stereo splitting parameters such as the color masks and the color filter matrix
511 for stereo color anaglyph.
512 */
514 {
515  ////////////////////
516  // Set Projection //
517  ////////////////////
518 
519  const SLMat4f& vm = updateAndGetWMI();
520  SLGLState* stateGL = SLGLState::instance();
521 
522  _stereoEye = eye;
523 
524  SLVec3f pos(vm.translation());
525  SLfloat top, bottom, left, right, d; // frustum parameters
526 
527  switch (_projType)
528  {
529  case P_monoPerspective:
531  break;
532 
533  case P_monoIntrinsic:
535  (float)_viewport.height,
536  _fx,
537  _fy,
538  _cx,
539  _cy,
540  _clipNear,
541  _clipFar);
542  break;
543 
544  case P_monoOrthographic:
545  top = tan(Utils::DEG2RAD * _fovV * 0.5f) * pos.length();
546  bottom = -top;
547  left = -_viewportRatio * top;
548  right = -left;
549 
550  // The orthographic projection should have its near clip plane behind the camera
551  // rather than slightly in front of it. Else we will see cross sections of scenes if
552  // we zoom in close
553  stateGL->projectionMatrix.ortho(left, right, bottom, top, -_clipNear, _clipFar);
554  break;
555 
556  case P_stereoSideBySideD:
557  stateGL->projectionMatrix = sv->s()->oculus()->projection(eye);
558 
559  break;
560  // all other stereo projections
561  default:
562  // asymmetric frustum shift d (see chapter stereo projection)
563  d = (SLfloat)eye * 0.5f * _stereoEyeSeparation * _clipNear / _focalDist;
564  top = tan(Utils::DEG2RAD * _fovV / 2) * _clipNear;
565  bottom = -top;
566  left = -_viewportRatio * top - d;
567  right = _viewportRatio * top - d;
568  stateGL->projectionMatrix.frustum(left, right, bottom, top, _clipNear, _clipFar);
569  }
570 
571  ///////////////////
572  // Clear Buffers //
573  ///////////////////
574 
575  if (eye == ET_right)
576  // Do not clear color on right eye because it contains the color of the
577  // left eye. The right eye must be drawn after the left into the same buffer
578  stateGL->clearDepthBuffer();
579 
580  /////////////////////////////////
581  // Set Color Mask and Filter //
582  /////////////////////////////////
583 
584  if (_projType >= P_stereoColorRC)
585  {
586  if (eye == ET_left)
587  {
588  switch (_projType)
589  {
590  case P_stereoColorRC:
591  case P_stereoColorRB:
592  case P_stereoColorRG: stateGL->colorMask(1, 0, 0, 1); break;
593  case P_stereoColorYB: stateGL->colorMask(1, 1, 0, 1); break;
594  default: break;
595  }
596  }
597  else
598  {
599  switch (_projType)
600  {
601  case P_stereoColorRC: stateGL->colorMask(0, 1, 1, 1); break;
602  case P_stereoColorRB: stateGL->colorMask(0, 0, 1, 1); break;
603  case P_stereoColorRG: stateGL->colorMask(0, 1, 0, 1); break;
604  case P_stereoColorYB: stateGL->colorMask(0, 0, 1, 1); break;
605  default: break;
606  }
607  }
608 
609  // Set color filter matrix for red-cyan and yello-blue (ColorCode3D)
610  switch (_projType)
611  {
612  case P_stereoColorRC:
614  0.59f,
615  0.12f,
616  0.00f,
617  1.00f,
618  0.00f,
619  0.00f,
620  0.00f,
621  1.00f);
622  break;
623  case P_stereoColorYB:
625  0.00f,
626  0.00f,
627  0.00f,
628  1.00f,
629  0.00f,
630  0.15f,
631  0.15f,
632  0.70f);
633  break;
634  default: break;
635  }
636  }
637  GET_GL_ERROR;
638 }
639 //-----------------------------------------------------------------------------
640 //! Calculate and apply correction from finger x-y-rotation
642  const SLMat3f& enuRc,
643  float& f,
644  SLVec3f& enuOffsetPix)
645 {
646  /* 1. Estimate horizon in enu-frame: intersection between camera x-y-plane
647  defined in enu-frame and enu x-y-plane: normal vector of camera x-y-plane
648  in enu frame definition: this is the camera z-axis expressed in enu frame.*/
649  SLVec3f normalCamXYPlane = enuRc * SLVec3f(0, 0, 1);
650 
651  // enu x-y-plane definition: this is just the z-axis
652  SLVec3f normalEnuXYPlane = SLVec3f(0, 0, 1);
653 
654  /* 2. Estimation of intersection line (horizon): Then the crossproduct of
655  both vectors defines the direction of the intersection line. In our special
656  case we know that the origin is a point the lies on both planes. Then
657  origin plus direction vector defines the horizon.*/
658  SLVec3f enuHorizon;
659  enuHorizon.cross(normalEnuXYPlane, normalCamXYPlane);
660  enuHorizon.normalize();
661 
662  /* 3. Use horizon angle to express screen (camera plane) finger movement
663  in enuUp-horizon plane express horizon in camera coordinate system.*/
664  SLMat3f cRenu = enuRc.transposed();
665  SLVec3f cHorizon = cRenu * enuHorizon;
666  cHorizon.normalize();
667 
668  // angle between x-axis and horizon
669  float horizAngDEG = atan2f((float)cHorizon.y, (float)cHorizon.x) * RAD2DEG;
670 
671  // rotate display x- and y-offsets to enuUp - horizon plane
672  SLVec3f cOffsetPix((SLfloat)_xOffsetPix, (SLfloat)_yOffsetPix, 0.f);
673  SLMat3f rot(horizAngDEG, 0, 0, 1);
674  enuOffsetPix = rot * cOffsetPix;
675 
676  /* 4. Apply rotation angles defined in camera plane onto vertical enu axis
677  and horizon axis estimate focal length (todo: calculate once when fov is set)*/
678  f = (SLfloat)sv->scrH() / (2.0f * tan(0.5f * fovV() * DEG2RAD));
679 
681  {
682  if (_xOffsetPix != 0 && _yOffsetPix != 0)
683  {
684  float yawOffsetRAD = atanf((float)enuOffsetPix.x / f);
685  float pitchOffsetRAD = atanf((float)enuOffsetPix.y / f);
686  SLMat3f rotVertical(yawOffsetRAD * RAD2DEG,
687  SLVec3f(0, 0, 1));
688  SLMat3f rotHorizon(pitchOffsetRAD * RAD2DEG,
689  enuHorizon.x,
690  enuHorizon.y,
691  enuHorizon.z);
692 
693  // we have to right multiply new rotation because new rotations
694  // are estimated w.r.t. enu coordinate frame
695  _enucorrRenu = _enucorrRenu * rotHorizon * rotVertical;
696  }
697  }
698  else if (_devRot->offsetMode() == ROM_oneFingerX) //||_devRot->offsetMode() == OM_fingerXRotYTrans)
699  {
700  if (_xOffsetPix != 0)
701  {
702  float yawOffsetRAD = atanf((float)enuOffsetPix.x / f);
703  SLMat3f rotVertical(yawOffsetRAD * RAD2DEG,
704  SLVec3f(0, 0, 1));
705 
706  // we have to right multiply new rotation because new rotations are estimated w.r.t. enu coordinate frame
707  _enucorrRenu = _enucorrRenu * rotVertical;
708  }
709  }
710 }
711 //-----------------------------------------------------------------------------
712 /*!
713 Applies the view transform to the modelview matrix depending on the eye:
714 eye=-1 for the left and eye=1 for the right eye.
715 The view matrix that projects all points from the world coordinate system to
716 the camera coordinate system (that means relative to the camera) is the camera
717 nodes inverse world matrix.
718 */
720 {
721  SLGLState* stateGL = SLGLState::instance();
722 
723  if (_camAnim == CA_deviceRotYUp)
724  {
725  if (!_devRot)
726  {
727  SL_WARN_MSG("SLCamera: _devRot is invalid");
728  return;
729  }
730 
731  // camera focal length
732  float f = 1.f;
733 
734  // finger x-y-movement expressed in enu frame
735  SLVec3f enuOffsetPix;
736 
737  ///////////////////////////////////////////////////////////////////////
738  // Build pose of camera in world frame (scene) using device rotation //
739  ///////////////////////////////////////////////////////////////////////
740 
741  // camera rotation with respect to (w.r.t.) sensor
742  SLMat3f sRc;
743  sRc.rotation(-90, 0, 0, 1);
744 
745  // sensor rotation w.r.t. east-north-down
746  SLMat3f enuRs;
748 
749  // define camera to enu rotation matrix
750  SLMat3f enuRc = enuRs * sRc;
751 
752  // Calculate and apply correction from finger x-y-rotation
753  updateEnuCorrRenu(sv, enuRc, f, enuOffsetPix);
754 
755  SLMat3f wyRenucorr;
756  if (_devRot->zeroYawAtStart())
757  {
758  // east-north-down w.r.t. world-yaw
759  SLfloat rotYawOffsetDEG = -1 * _devRot->startYawRAD() * Utils::RAD2DEG + 90;
760  if (rotYawOffsetDEG > 180)
761  rotYawOffsetDEG -= 360;
762  wyRenucorr.rotation(rotYawOffsetDEG, 0, 0, 1);
763  }
764 
765  // world-yaw rotation w.r.t. world
766  SLMat3f wRwy;
767  wRwy.rotation(-90, 1, 0, 0);
768 
769  // combination of partial rotations to orientation of camera w.r.t world
770  SLMat3f wRc = wRwy * wyRenucorr * _enucorrRenu * enuRc;
771 
772  // camera translations w.r.t world:
773  // SLVec3f wtc = updateAndGetWM().translation();
774  // SLVec3f wtc = _om.translation();
775 
776  // combination of rotation and translation:
777  // SLMat4f wTc;
778  // wTc.setRotation(wRc);
779  // wTc.setTranslation(wtc);
780 
781  // set camera pose to the object matrix
782  // om(wTc);
783  _om.setRotation(wRc);
784  needUpdate();
785 
786  /*
787  //alternative concatenation of single transformations
788  SLMat4f wTc_2;
789  wTc_2.translate(updateAndGetWM().translation());
790  wTc_2.rotate(-90, 1, 0, 0);
791  wTc_2.rotate(rotYawOffsetDEG, 0, 0, 1);
792  SLMat4f enuTs;
793  enuTs.setRotation(s->deviceRotation());
794  wTc_2 *= enuTs;
795  wTc_2.rotate(-90, 0, 0, 1);
796  */
797  }
798 
799  // location sensor is turned on and the scene has a global reference position
800  else if (_camAnim == CA_deviceRotLocYUp)
801  {
802  // camera focal length
803  float f = 1.f;
804 
805  // finger x-y-movement expressed in enu frame
806  SLVec3f enuOffsetPix;
807 
808  if (!_devRot) SL_EXIT_MSG("SLCamera::setView: _devRot not set!");
809  if (!_devLoc) SL_EXIT_MSG("SLCamera::setView: _devLoc not set!");
810 
811  // The device rotation sensor (IMU) is turned on and sends rotation angles
812  if (_devRot->isUsed())
813  {
814  /* Camera rotation w.r.t. to sensor
815  This is how the camera coordinate system is aligned relative to the sensor coordinate
816  system: we are in the camera coordinate system if we rotate the sensor coordinate
817  system -90 degrees about the z-axis)*/
818  SLMat3f sRc;
819  sRc.rotation(-90, 0, 0, 1);
820 
821  /* Sensor rotation w.r.t. east-north-up (gliding averaged)
822  This is how the sensor is aligned relative to the east-north-down coordinate system:
823  this rotation is what we get from the device rotation sensor api.*/
824  SLMat3f enuRs;
826 
827  // define camera to enu rotation matrix
828  SLMat3f enuRc = enuRs * sRc;
829 
830  // Calculate and apply correction from finger x-y-rotation
831  updateEnuCorrRenu(sv, enuRc, f, enuOffsetPix);
832 
833  /* enu rotation (after correction) w.r.t. world
834  "world" is our scene coordinate system! This rotation matrix defines how the scene
835  coordinate system is aligned relative to the enu coordinate system */
836  SLMat3f wRenucorr;
837  wRenucorr.rotation(-90, 1, 0, 0);
838 
839  /* camera rotation w.r.t world
840  "world" is our scene coordinate system! We are searching for the camera pose in the
841  scene (world) coordinate system! Combination of partial rotations to orientation of
842  camera w.r.t world */
843  SLMat3f wRc = wRenucorr * _enucorrRenu * enuRc;
844 
845  _om.setRotation(wRc);
846 
847  needUpdate();
848  }
849 
850  // The device location sensor (GPS) is turned on and the scene has a global reference position
851  if (_devLoc && _devLoc->hasOrigin())
852  {
853  if (_devLoc->isUsed())
854  {
855  // Direction vector from camera to world origin
857 
858  // Reset to default if device is too far away
859  if (wtc.length() > _devLoc->locMaxDistanceM())
861 
862  // Set the camera position
863  SLVec3f wtc_f((SLfloat)wtc.x, (SLfloat)wtc.y, (SLfloat)wtc.z);
864 
865  _om.setTranslation(wtc_f);
866 
867  needUpdate();
868  }
869  else // with disabled GPS use the default location
870  {
871  // Direction vector from camera to world origin with default location in ENU
873 
874  // Set the camera position
875  SLVec3f wtc_f((SLfloat)wtc.x, (SLfloat)wtc.y, (SLfloat)wtc.z);
876 
877  _om.setTranslation(wtc_f);
878 
879  needUpdate();
880  }
881  }
882 
883  /*Calculate and apply finger y-translation
884  if (_devRot->offsetMode() == OM_fingerYTrans || _devRot->offsetMode() == OM_fingerXRotYTrans)
885  {
886  //_enucorrTRenu += enuOffsetPix.y / f * _distanceToObjectM;
887  // Set the camera position
888  const SLVec3f& wtc = _om.translation();
889  SLVec3f wtc_f((SLfloat)wtc.x,
890  (SLfloat)wtc.y + enuOffsetPix.y / f * _distanceToObjectM,
891  (SLfloat)wtc.z);
892  _om.setTranslation(wtc_f);
893  needUpdate();
894  }*/
895  }
896  else if (_camAnim == CA_off)
897  {
898  // nothing
899  }
900 
901  // clear stored finger rotation
902  _xOffsetPix = 0;
903  _yOffsetPix = 0;
904 
905  // The view matrix is the camera nodes inverse world matrix
906  SLMat4f vm = updateAndGetWMI();
907 
908  // Single eye projection
909  if (eye == ET_center)
910  {
911  // Standard case: Just overwrite the view matrix
912  stateGL->viewMatrix.setMatrix(vm);
913  }
914  else // stereo viewing
915  {
917  {
918  // half inter-pupilar distance
919  SLfloat halfIPD = (SLfloat)eye * _stereoEyeSeparation * -0.5f;
920 
921  SLMat4f trackingPos;
922  if (_camAnim == CA_deviceRotYUp)
923  {
924  // get the oculus or mobile device orientation
926  if (sv->s()->oculus()->isConnected())
927  {
928  rotation = sv->s()->oculus()->orientation(eye);
929  trackingPos.translate(-1 * sv->s()->oculus()->position(eye));
930  }
931  // todo else rotation = s->deviceRotation();
932 
933  SLfloat rotX = 0.0f, rotY = 0.0f, rotZ = 0.0f;
934  rotation.toMat4().toEulerAnglesZYX(rotZ, rotY, rotX);
935  /*
936  SL_LOG("rotx : %3.1f, roty: %3.1f, rotz: %3.1f",
937  rotX * SL_RAD2DEG,
938  rotY * SL_RAD2DEG,
939  rotZ * SL_RAD2DEG);
940  */
941 
942  SLVec3f viewAdjust = sv->s()->oculus()->viewAdjust(eye) * _unitScaling;
943 
944  SLMat4f vmEye(SLMat4f(viewAdjust.x,
945  viewAdjust.y,
946  viewAdjust.z) *
947  rotation.inverted().toMat4() * trackingPos * vm);
948  stateGL->viewMatrix = vmEye;
949  }
950  else
951  {
952  SLMat4f vmEye(SLMat4f(halfIPD, 0.0f, 0.f) * vm);
953  stateGL->viewMatrix = vmEye;
954  }
955  }
956  else
957  {
958  // Get central camera vectors eye, lookAt, lookUp out of the view matrix vm
959  SLVec3f EYE, LA, LU, LR;
960  vm.lookAt(&EYE, &LA, &LU, &LR);
961 
962  // Shorten LR to half of the eye dist (eye=-1 for left, eye=1 for right)
963  LR *= _stereoEyeSeparation * 0.5f * (SLfloat)eye;
964 
965  // Set the OpenGL view matrix for the left eye
966  SLMat4f vmEye;
967  vmEye.lookAt(EYE + LR, EYE + _focalDist * LA + LR, LU);
968  stateGL->viewMatrix = vmEye;
969  }
970  }
971 }
972 //-----------------------------------------------------------------------------
973 //! Sets the view to look from a direction towards the current focal point
974 void SLCamera::lookFrom(const SLVec3f& fromDir,
975  const SLVec3f& upDir)
976 {
978  translation(lookAt + _focalDist * fromDir);
979  this->lookAt(lookAt, upDir);
980 }
981 //-----------------------------------------------------------------------------
982 //! SLCamera::animationStr() returns the animation enum as string
984 {
985  switch (_camAnim)
986  {
987  case CA_turntableYUp: return "Turntable Y up";
988  case CA_turntableZUp: return "Turntable Z up";
989  case CA_walkingYUp: return "Walking Y up";
990  case CA_walkingZUp: return "Walking Z up";
991  case CA_deviceRotYUp: return "Device Rotated Y up";
992  case CA_deviceRotLocYUp: return "Device Rotated Y up and Gps Positioned";
993  default: return "unknown";
994  }
995 }
996 
997 //-----------------------------------------------------------------------------
998 /*
999 Event Handlers: Because the SLNode class also inherits the SLEventHandler
1000 class a node can also act as a event handler. The camera class uses this to
1001 implement the camera animation.
1002 */
1003 //-----------------------------------------------------------------------------
1004 //! Gets called whenever a mouse button gets pressed.
1006  const SLint x,
1007  const SLint y,
1008  const SLKey mod)
1009 {
1010  // Init both position in case that the second finger came with delay
1011  _oldTouchPos1.set((SLfloat)x, (SLfloat)y);
1012  _oldTouchPos2.set((SLfloat)x, (SLfloat)y);
1013 
1014  if (button == MB_left)
1015  {
1016  // Start selection rectangle. See also SLMesh::handleRectangleSelection
1017  if (mod & K_ctrl)
1019 
1020  // Start deselection rectangle. See also SLMesh::handleRectangleSelection
1021  if (mod & K_alt)
1023 
1024  if (_camAnim == CA_trackball)
1026  }
1027  return true;
1028 }
1029 //-----------------------------------------------------------------------------
1030 //! Gets called whenever the mouse is moved.
1032  const SLint x,
1033  const SLint y,
1034  const SLKey mod)
1035 {
1036  if (button == MB_left) //==================================================
1037  {
1038  // Set selection rectangle. See also SLMesh::handleRectangleSelection
1039  if (mod & K_ctrl)
1040  {
1042  return true;
1043  }
1044 
1045  // Set deselection rectangle. See also SLMesh::handleRectangleSelection
1046  if (mod & K_alt)
1047  {
1049  return true;
1050  }
1051 
1052  // Position and directions in view space
1053  SLVec3f positionVS = this->translationOS();
1054  SLVec3f forwardVS = this->forwardOS();
1055  SLVec3f rightVS = this->rightOS();
1056 
1057  // The lookAt point
1058  SLVec3f lookAtPoint = positionVS + _focalDist * forwardVS;
1059 
1060  // Determine rot angles around x- & y-axis
1063 
1064  if (_camAnim == CA_turntableYUp) //....................................
1065  {
1066  SLMat4f rot;
1067  rot.translate(lookAtPoint);
1068  rot.rotate(-dX, SLVec3f(0, 1, 0));
1069  rot.rotate(-dY, rightVS);
1070  rot.translate(-lookAtPoint);
1071 
1072  _om.setMatrix(rot * _om);
1073  needUpdate();
1074  }
1075  else if (_camAnim == CA_turntableZUp) //...............................
1076  {
1077  SLMat4f rot;
1078  rot.translate(lookAtPoint);
1079  rot.rotate(dX, SLVec3f(0, 0, 1));
1080  rot.rotate(dY, rightVS);
1081  rot.translate(-lookAtPoint);
1082 
1083  _om.setMatrix(rot * _om);
1084  needUpdate();
1085  }
1086  else if (_camAnim == CA_trackball) //..................................
1087  {
1088  // Reference: https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Arcball
1089  // calculate current mouse vector at current mouse position
1090  SLVec3f curMouseVec = trackballVec(x, y);
1091 
1092  // calculate angle between the old and the current mouse vector
1093  // Take care that the dot product isn't greater than 1.0 otherwise
1094  // the acos will return undefined.
1095  SLfloat dot = _trackballStartVec.dot(curMouseVec);
1096  SLfloat angle = acos(dot > 1 ? 1 : dot) * Utils::RAD2DEG;
1097 
1098  // calculate rotation axis with the cross product
1099  SLVec3f axisVS;
1100  axisVS.cross(_trackballStartVec, curMouseVec);
1101 
1102  // To stabilise the axis we average it with the last axis
1103  static SLVec3f lastAxisVS = SLVec3f::ZERO;
1104  if (lastAxisVS != SLVec3f::ZERO) axisVS = (axisVS + lastAxisVS) / 2.0f;
1105 
1106  // Because we calculate the mouse vectors from integer mouse positions
1107  // we can get some numerical instability from the dot product when the
1108  // mouse is on the silhouette of the virtual sphere.
1109  // We calculate therefore an alternative for the angle from the mouse
1110  // motion length.
1111  SLVec2f dMouse(_oldTouchPos1.x - (SLfloat)x,
1112  _oldTouchPos1.y - (SLfloat)y);
1113  SLfloat dMouseLenght = dMouse.length();
1114  if (angle > dMouseLenght) angle = dMouseLenght * 0.2f;
1115 
1116  // Transform rotation axis into world space
1117  // Remember: The cameras om is the view matrix inversed
1118  SLVec3f axisWS = _om.mat3() * axisVS;
1119 
1120  // Create rotation from one rotation around one axis
1121  SLMat4f rot;
1122  rot.translate(lookAtPoint); // undo camera translation
1123  rot.rotate((SLfloat)-angle, axisWS); // create incremental rotation
1124  rot.translate(-lookAtPoint); // redo camera translation
1125  _om.setMatrix(rot * _om); // accumulate rotation to the existing camera matrix
1126 
1127  // set current to last
1128  _trackballStartVec = curMouseVec;
1129  lastAxisVS = axisVS;
1130 
1131  needUpdate();
1132  }
1133  else if (_camAnim == CA_walkingYUp) //.................................
1134  {
1135  dY *= 0.5f;
1136  dX *= 0.5f;
1137 
1138  SLMat4f rot;
1139  rot.rotate(-dX, SLVec3f(0, 1, 0));
1140  rot.rotate(-dY, rightVS);
1141 
1142  forwardVS.set(rot.multVec(forwardVS));
1143  lookAt(positionVS + forwardVS);
1144  needUpdate();
1145  }
1146  else if (_camAnim == CA_walkingZUp) //.................................
1147  {
1148  dY *= 0.5f;
1149  dX *= 0.5f;
1150 
1151  SLMat4f rot;
1152  rot.rotate(-dX, SLVec3f(0, 0, 1));
1153  rot.rotate(-dY, rightVS);
1154 
1155  forwardVS.set(rot.multVec(forwardVS));
1156  lookAt(positionVS + forwardVS, SLVec3f(0, 0, 1));
1157  needWMUpdate();
1158  }
1160  {
1161  if (_devRot)
1162  {
1163  if (_devRot->offsetMode() == ROM_oneFingerX ||
1165  {
1168  }
1169  }
1170  }
1171 
1172  _oldTouchPos1.set((SLfloat)x, (SLfloat)y);
1173  }
1174  else if (button == MB_middle) //===========================================
1175  {
1176  if (_camAnim == CA_turntableYUp ||
1179  {
1180  // Calculate the fraction delta of the mouse movement
1181  SLVec2f dMouse((SLfloat)x - _oldTouchPos1.x,
1182  _oldTouchPos1.y - (SLfloat)y);
1183  dMouse.x /= (SLfloat)_viewport.width;
1184  dMouse.y /= (SLfloat)_viewport.height;
1185 
1186  // scale factor depending on the space size at focal dist
1187  SLfloat spaceH = tan(Utils::DEG2RAD * _fovV / 2) * _focalDist * 2.0f;
1188  SLfloat spaceW = spaceH * _viewportRatio;
1189 
1190  dMouse.x *= spaceW;
1191  dMouse.y *= spaceH;
1192 
1193  if (mod == K_ctrl)
1194  translate(SLVec3f(-dMouse.x, 0, dMouse.y), TS_object);
1195  else
1196  translate(SLVec3f(-dMouse.x, -dMouse.y, 0), TS_object);
1197 
1198  // todo anim : bleibt!!
1199  _oldTouchPos1.set((SLfloat)x, (SLfloat)y);
1200  }
1201  } //=======================================================================
1202 
1203  return true;
1204 }
1205 //-----------------------------------------------------------------------------
1206 //! Gets called whenever the mouse button is released
1208  const SLint x,
1209  const SLint y,
1210  const SLKey mod)
1211 {
1212  if (button == MB_left)
1213  {
1214  // End rectangle select. See also SLMesh::handleRectangleSelection
1215  if (mod & K_ctrl)
1216  {
1217  _selectRect.setZero();
1218  return true;
1219  }
1220  // End rectangle deselect. See also SLMesh::handleRectangleSelection
1221  if (mod & K_alt)
1222  {
1224  return true;
1225  }
1226 
1227  // todo anim
1228  if (_camAnim == CA_turntableYUp)
1229  return true;
1230  else if (_camAnim == CA_walkingYUp)
1231  return true;
1232  }
1233  else if (button == MB_middle)
1234  {
1235  return true;
1236  }
1237  return false;
1238 }
1239 //-----------------------------------------------------------------------------
1240 /*!
1241 SLCamera::onMouseWheel event handler moves camera forwards or backwards
1242 */
1244  const SLKey mod)
1245 {
1246  SLfloat sign = (SLfloat)Utils::sign(delta);
1247 
1248  if (_camAnim == CA_turntableYUp ||
1250  _camAnim == CA_trackball) //...........................................
1251  {
1252  if (mod == K_none)
1253  {
1256 
1257  needUpdate();
1258  }
1259  if (mod == K_ctrl)
1260  {
1261  _stereoEyeSeparation *= (1.0f + sign * 0.1f);
1262  }
1263  if (mod == K_alt)
1264  {
1265  _fovV += sign * 5.0f;
1266  currentFOV = _fovV;
1267  }
1268  }
1269  else if (_camAnim == CA_walkingYUp || _camAnim == CA_walkingZUp) //........
1270  {
1271  _maxSpeed *= (1.0f + sign * 0.1f);
1272  }
1273  return false;
1274 }
1275 //-----------------------------------------------------------------------------
1276 /*!
1277 SLCamera::onDoubleTouch gets called whenever two fingers touch a handheld
1278 screen.
1279 */
1281  const SLint y1,
1282  const SLint x2,
1283  const SLint y2)
1284 {
1285  _oldTouchPos1.set((SLfloat)x1, (SLfloat)y1);
1286  _oldTouchPos2.set((SLfloat)x2, (SLfloat)y2);
1287  return true;
1288 }
1289 
1290 //-----------------------------------------------------------------------------
1291 /*!
1292 SLCamera::onTouch2Move gets called whenever two fingers move on a handheld
1293 screen.
1294 */
1296  const SLint y1,
1297  const SLint x2,
1298  const SLint y2)
1299 {
1300  SLVec2f now1((SLfloat)x1, (SLfloat)y1);
1301  SLVec2f now2((SLfloat)x2, (SLfloat)y2);
1302  SLVec2f delta1(now1 - _oldTouchPos1);
1303  SLVec2f delta2(now2 - _oldTouchPos2);
1304 
1305  // Average out the deltas over the last 4 events for correct 1 pixel moves
1306  static SLuint cnt = 0;
1307  static SLVec2f d1[4];
1308  static SLVec2f d2[4];
1309  d1[cnt % 4] = delta1;
1310  d2[cnt % 4] = delta2;
1311  SLVec2f avgDelta1(d1[0].x + d1[1].x + d1[2].x + d1[3].x,
1312  d1[0].y + d1[1].y + d1[2].y + d1[3].y);
1313  SLVec2f avgDelta2(d2[0].x + d2[1].x + d2[2].x + d2[3].x,
1314  d2[0].y + d2[1].y + d2[2].y + d2[3].y);
1315  avgDelta1 /= 4.0f;
1316  avgDelta2 /= 4.0f;
1317  cnt++;
1318 
1319  SLfloat r1, phi1, r2, phi2;
1320  avgDelta1.toPolar(r1, phi1);
1321  avgDelta2.toPolar(r2, phi2);
1322 
1323  // scale factor depending on the space sice at focal dist
1324  SLfloat spaceH = tan(Utils::DEG2RAD * _fovV / 2) * _focalDist * 2.0f;
1325  SLfloat spaceW = spaceH * _viewportRatio;
1326 
1327  // if fingers move parallel slide camera vertically or horizontally
1328  if (Utils::abs(phi1 - phi2) < 0.2f)
1329  {
1330  // Calculate center between finger points
1331  SLVec2f nowCenter((now1 + now2) * 0.5f);
1332  SLVec2f oldCenter((_oldTouchPos1 + _oldTouchPos2) * 0.5f);
1333 
1334  // For first move set oldCenter = nowCenter
1335  if (oldCenter == SLVec2f::ZERO) oldCenter = nowCenter;
1336 
1337  SLVec2f delta(nowCenter - oldCenter);
1338 
1339  // scale to 0-1
1340  delta.x /= (SLfloat)_viewport.width;
1341  delta.y /= (SLfloat)_viewport.height;
1342 
1343  // scale to space size
1344  delta.x *= spaceW;
1345  delta.y *= spaceH;
1346 
1348  {
1349  // apply delta to x- and y-position
1350  translate(SLVec3f(-delta.x, delta.y, 0), TS_object);
1351  }
1352  else if (_camAnim == CA_walkingYUp || _camAnim == CA_walkingZUp)
1353  {
1354  //_moveDir.x = delta.x * 100.0f,
1355  //_moveDir.z = delta.y * 100.0f;
1356  }
1358  {
1359  if (_devLoc)
1360  {
1361  if (_devLoc->offsetMode() == LOM_twoFingerY)
1362  {
1363  // string msg = "TwoFingerOffset: " + delta.toString();
1364  // SL_LOG(msg.c_str());
1365  SLVec3d offsetENU = _devLoc->offsetENU();
1366  delta *= _mouseRotationFactor;
1367  offsetENU.y += delta.y;
1368  _devLoc->offsetENU(offsetENU);
1369  }
1370  }
1371  }
1372  }
1373  else // Two finger pinch
1374  {
1375  // Calculate vector between fingers
1376  SLVec2f nowDist(now2 - now1);
1377  SLVec2f oldDist(_oldTouchPos2 - _oldTouchPos1);
1378 
1379  // For first move set oldDist = nowDist
1380  if (oldDist == SLVec2f::ZERO) oldDist = nowDist;
1381 
1382  SLfloat delta = oldDist.length() - nowDist.length();
1383 
1384  if (_camAnim == CA_turntableYUp)
1385  { // scale to 0-1
1386  delta /= (SLfloat)_viewport.height;
1387 
1388  // scale to space height
1389  delta *= spaceH * 2;
1390 
1391  // apply delta to the z-position
1392  translate(SLVec3f(0, 0, delta), TS_object);
1393  _focalDist += delta;
1394  }
1395  else if (_camAnim == CA_walkingYUp)
1396  {
1397  // change field of view
1398  _fovV += Utils::sign(delta) * 0.5f;
1399  currentFOV = _fovV;
1400  }
1401  }
1402 
1403  _oldTouchPos1.set((SLfloat)x1, (SLfloat)y1);
1404  _oldTouchPos2.set((SLfloat)x2, (SLfloat)y2);
1405  return true;
1406 }
1407 //-----------------------------------------------------------------------------
1408 /*!
1409 SLCamera::onDoubleTouch gets called whenever two fingers touch a handheld
1410 screen.
1411 */
1413  const SLint y1,
1414  const SLint x2,
1415  const SLint y2)
1416 {
1417  _velocity.set(0.0f, 0.0f, 0.0f);
1418  return true;
1419 }
1420 //-----------------------------------------------------------------------------
1421 /*!
1422 SLCamera::onKeyPress applies the keyboard view navigation to the view matrix.
1423 The key code constants are defined in SL.h
1424 */
1426 {
1427  // Keep in sync with SLDemoGui::buildMenuBar
1428  switch ((SLchar)key)
1429  {
1430  case 'W':
1431  case 'A':
1432  case 'S':
1433  case 'D':
1434  case 'Q':
1435  case 'E':
1436  case (SLchar)K_up:
1437  case (SLchar)K_down:
1438  case (SLchar)K_right:
1439  case (SLchar)K_left:
1440  _keyStates[(SLchar)key] = true;
1441  return true;
1442 
1443  // View setting as in standard Blender
1444  case '1':
1445  if (mod == K_ctrl)
1447  else
1449  return true;
1450  case '3':
1451  if (mod == K_ctrl)
1453  else
1455  return true;
1456  case '7':
1457  if (mod == K_ctrl)
1459  else
1461  return true;
1462 
1463  default: return false;
1464  }
1465 }
1466 //-----------------------------------------------------------------------------
1467 /*!
1468 SLCamera::onKeyRelease gets called when a key is released
1469 */
1471 {
1472  switch ((SLchar)key)
1473  {
1474  case 'W':
1475  case 'A':
1476  case 'S':
1477  case 'D':
1478  case 'Q':
1479  case 'E':
1480  case (SLchar)K_up:
1481  case (SLchar)K_down:
1482  case (SLchar)K_right:
1483  case (SLchar)K_left:
1484  _keyStates[(SLchar)key] = false;
1485  return true;
1486  }
1487 
1488  return false;
1489 }
1490 //-----------------------------------------------------------------------------
1491 //! SLCamera::setFrustumPlanes set the 6 plane from the view frustum.
1492 /*! SLCamera::setFrustumPlanes set the 6 frustum planes by extracting the plane
1493 coefficients from the combined view and projection matrix.
1494 */
1496 {
1497  SLGLState* stateGL = SLGLState::instance();
1499  stateGL->projectionMatrix,
1500  stateGL->viewMatrix);
1501 }
1502 //-----------------------------------------------------------------------------
1503 //!< Horizontal field of view
1505 {
1506  float f = (0.5f * (float)_viewport.height) / tanf(_fovV * 0.5f * Utils::DEG2RAD);
1507  return 2.f * atanf(0.5f * (float)_viewport.width / f) * Utils::RAD2DEG;
1508 }
1509 //-----------------------------------------------------------------------------
1510 //! eyeToPixelRay returns the a ray from the eye to the center of a pixel.
1511 /*! This method is used for object picking. The calculation is the same as for
1512 primary rays in Ray Tracing.
1513 */
1515 {
1516  SLVec3f EYE, LA, LU, LR;
1517 
1518  // get camera vectors eye, lookAt, lookUp from view matrix
1519  updateAndGetVM().lookAt(&EYE, &LA, &LU, &LR);
1520 
1522  { /*
1523  In orthographic projection the top-left vector (TL) points
1524  from the eye to the center of the TL-left pixel of a plane that
1525  parallel to the projection plan at zero distance from the eye.
1526  */
1528  SLfloat hh = tan(Utils::DEG2RAD * _fovV * 0.5f) * pos.length();
1529  SLfloat hw = hh * _viewportRatio;
1530 
1531  // calculate the size of a pixel in world coords.
1532  SLfloat pixel = hw * 2 / (SLfloat)_viewport.width;
1533 
1534  SLVec3f TL = EYE - hw * LR + hh * LU + pixel / 2 * LR - pixel / 2 * LU;
1535  SLVec3f dir = LA;
1536  dir.normalize();
1537  ray->setDir(dir);
1538  ray->origin.set(TL + pixel * (x * LR - y * LU));
1539  }
1540  else
1541  { /*
1542  In perspective projection the top-left vector (TL) points
1543  from the eye to the center of the top-left pixel on a projection
1544  plan in focal distance. See also the computer graphics script about
1545  primary ray calculation.
1546  */
1547  // calculate half window width & height in world coords
1548  SLfloat hh = tan(Utils::DEG2RAD * _fovV * 0.5f) * _focalDist;
1549  SLfloat hw = hh * _viewportRatio;
1550 
1551  // calculate the size of a pixel in world coords.
1552  SLfloat pixel = hw * 2 / (SLfloat)_viewport.width;
1553 
1554  // calculate a vector to the center (C) of the top left (TL) pixel
1555  SLVec3f C = LA * _focalDist;
1556  SLVec3f TL = C - hw * LR + hh * LU + pixel * 0.5f * (LR - LU);
1557  SLVec3f dir = TL + pixel * (x * LR - y * LU);
1558 
1559  dir.normalize();
1560  ray->setDir(dir);
1561  ray->origin.set(EYE);
1562  }
1563 
1564  ray->length = FLT_MAX;
1565  ray->depth = 1;
1566  ray->contrib = 1.0f;
1567  ray->type = PRIMARY;
1568  ray->x = x;
1569  ray->y = y;
1570  ray->hitTriangle = -1;
1571  ray->hitNormal.set(SLVec3f::ZERO);
1572  ray->hitPoint.set(SLVec3f::ZERO);
1573  ray->hitNode = nullptr;
1574  ray->hitMesh = nullptr;
1575  ray->srcTriangle = 0;
1576 }
1577 
1579 {
1580  SLVec3f LA, LU, LR;
1581 
1582  // get camera vectors eye, lookAt, lookUp from view matrix
1583  updateAndGetVM().lookAt(&EYE, &LA, &LU, &LR);
1584 
1585  W = LA * _focalDist;
1586 
1587  U.cross(W, LU);
1588  U.normalize();
1589 
1590  V.cross(U, W);
1591  V.normalize();
1592 
1593  SLfloat hh = tan(Utils::DEG2RAD * _fovV * 0.5f) * _focalDist;
1594  SLfloat hw = hh * _viewportRatio;
1595  V *= hh;
1596  U *= hw;
1597 }
1598 
1599 //-----------------------------------------------------------------------------
1600 //! Project a world position into screen coordinates
1602 {
1603  SLMat4f projectionMatrix;
1604  projectionMatrix.perspective(_fovV, _viewportRatio, _clipNear, _clipFar);
1605  SLMat4f viewMatrix = updateAndGetVM();
1606 
1607  SLVec4f eyePos = viewMatrix * worldPos;
1608  SLVec4f clipPos = projectionMatrix * eyePos;
1609 
1610  SLVec4f ndcPos = clipPos / clipPos.w;
1611 
1612  SLVec2f result = SLVec2f(ndcPos.x,
1613  ndcPos.y);
1614 
1615  return result;
1616 }
1617 //-----------------------------------------------------------------------------
1618 //! SLCamera::isInFrustum does a simple and fast frustum culling test for AABBs
1619 /*! SLCamera::isInFrustum checks if the bounding sphere of an AABB is within
1620 the view frustum defined by its 6 planes by simply testing the distance of the
1621 AABBs center minus its radius. This is faster than the AABB in frustum test but
1622 not as precise. Please refer to the nice tutorial on frustum culling on:
1623 https://cgvr.cs.uni-bremen.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/
1624 */
1626 {
1627  // check the 6 planes of the frustum
1628  for (auto& i : _plane)
1629  {
1630  SLfloat distance = i.distToPoint(aabb->centerWS());
1631  if (distance < -aabb->radiusWS())
1632  {
1633  aabb->isVisible(false);
1634  return false;
1635  }
1636  }
1637  aabb->isVisible(true);
1638 
1639  // Calculate squared dist. from AABB's center to viewer for blend sorting.
1640  SLVec3f viewToCenter(_wm.translation() - aabb->centerWS());
1641  aabb->sqrViewDist(viewToCenter.lengthSqr());
1642  return true;
1643 }
1644 //-----------------------------------------------------------------------------
1645 //! SLCamera::to_string returns important camera parameter as a string
1647 {
1648  SLMat4f vm = updateAndGetVM();
1649  std::ostringstream ss;
1650  ss << "Projection: " << projTypeStr() << endl;
1651  ss << "FOV: " << _fovV << endl;
1652  ss << "ClipNear: " << _clipNear << endl;
1653  ss << "ClipFar: " << _clipFar << endl;
1654  ss << "Animation: " << animationStr() << endl;
1655  ss << vm.toString() << endl;
1656  return ss.str();
1657 }
1658 //-----------------------------------------------------------------------------
1659 //! Returns a vector from the window center to a virtual trackball at [x,y].
1660 /*! The trackball vector is a vector from the window center to a hemisphere
1661 over the window at the specified cursor position. With two trackball vectors
1662 you can calculate a single rotation axis with the cross product. This routine
1663 is used for the trackball camera animation.
1664  */
1666 {
1667  // Calculate x & y component to the virtual unit sphere
1669 
1670  SLVec3f vec((SLfloat)((SLfloat)x - (SLfloat)_viewport.width * 0.5f) / r,
1671  -(SLfloat)((SLfloat)y - (SLfloat)_viewport.height * 0.5f) / r);
1672 
1673  // d = length of vector x,y
1674  SLfloat d = sqrt(vec.x * vec.x + vec.y * vec.y);
1675 
1676  // z component with pytagoras
1677  if (d < 1.0f)
1678  vec.z = sqrt(1.0f - d * d);
1679  else
1680  {
1681  vec.z = 0.0f;
1682  vec.normalize(); // d >= 1, so normalize
1683  }
1684  return vec;
1685 }
1686 //-----------------------------------------------------------------------------
1687 //! Pass camera parameters to the uniform variables
1689 {
1690  assert(program && "SLCamera::passToUniforms: No shader program set!");
1691 
1692  program->uniform1i("u_camProjType", _projType);
1693  program->uniform1i("u_camStereoEye", _stereoEye);
1694  program->uniformMatrix3fv("u_camStereoColors",
1695  1,
1697  // Pass fog parameters
1698  if (_fogColorIsBack)
1700  _fogStart = _clipNear;
1701  _fogEnd = _clipFar;
1702 
1703  program->uniform1i("u_camFogIsOn", _fogIsOn);
1704  program->uniform1i("u_camFogMode", _fogMode);
1705  program->uniform1f("u_camFogDensity", _fogDensity);
1706  program->uniform1f("u_camFogStart", _fogStart);
1707  program->uniform1f("u_camFogEnd", _fogEnd);
1708  program->uniform1f("u_camClipNear", _clipNear);
1709  program->uniform1f("u_camClipFar", _clipFar);
1710  program->uniform1f("u_camBkgdWidth", _background.rect().width);
1711  program->uniform1f("u_camBkgdHeight", _background.rect().height);
1712  program->uniform1f("u_camBkgdLeft", _background.rect().x);
1713  program->uniform1f("u_camBkgdBottom", _background.rect().y);
1714  program->uniform4fv("u_camFogColor", 1, (SLfloat*)&_fogColor);
1715 }
1716 //-----------------------------------------------------------------------------
float SLfloat
Definition: SL.h:173
unsigned int SLuint
Definition: SL.h:171
char SLchar
Definition: SL.h:162
#define SL_WARN_MSG(message)
Definition: SL.h:241
bool SLbool
Definition: SL.h:175
#define SL_EXIT_MSG(message)
Definition: SL.h:240
string SLstring
Definition: SL.h:158
int SLint
Definition: SL.h:170
Mobile device location class declaration.
@ LOM_twoFingerY
Mobile device rotation class declaration.
@ ROM_oneFingerX
@ ROM_oneFingerXY
SLCamAnim
Enumeration for available camera animation types.
Definition: SLEnums.h:121
@ CA_turntableYUp
Orbiting around central object w. turntable rotation around y & right axis.
Definition: SLEnums.h:122
@ CA_walkingYUp
Walk translation with AWSD and look around rotation around y & right axis.
Definition: SLEnums.h:125
@ CA_off
No camera animation.
Definition: SLEnums.h:129
@ CA_deviceRotLocYUp
The device rotation controls the camera rotation and the GPS controls the Camera Translation.
Definition: SLEnums.h:128
@ CA_trackball
Orbiting around central object w. one rotation around one axis.
Definition: SLEnums.h:124
@ CA_deviceRotYUp
The device rotation controls the camera rotation.
Definition: SLEnums.h:127
@ CA_turntableZUp
Orbiting around central object w. turntable rotation around z & right axis.
Definition: SLEnums.h:123
@ CA_walkingZUp
Walk translation with AWSD and look around rotation around z & right axis.
Definition: SLEnums.h:126
SLProjType
Enumeration for different camera projections.
Definition: SLEnums.h:134
@ P_monoPerspective
standard mono pinhole perspective projection
Definition: SLEnums.h:135
@ P_stereoSideBySideP
side-by-side proportional for mirror stereoscopes
Definition: SLEnums.h:139
@ P_monoIntrinsic
standard mono pinhole perspective projection from intrinsic calibration
Definition: SLEnums.h:136
@ P_stereoPixelByPixel
checkerboard pattern (DLP3D)
Definition: SLEnums.h:143
@ P_stereoColumnByColumn
column-by-column
Definition: SLEnums.h:142
@ P_stereoColorRG
color masking for red-green anaglyphs
Definition: SLEnums.h:145
@ P_stereoSideBySideD
side-by-side distorted for Oculus Rift like glasses
Definition: SLEnums.h:140
@ P_stereoSideBySide
side-by-side
Definition: SLEnums.h:138
@ P_stereoColorYB
color masking for yellow-blue anaglyphs (ColorCode 3D)
Definition: SLEnums.h:147
@ P_stereoLineByLine
line-by-line
Definition: SLEnums.h:141
@ P_stereoColorRB
color masking for red-blue anaglyphs
Definition: SLEnums.h:146
@ P_stereoColorRC
color masking for red-cyan anaglyphs
Definition: SLEnums.h:144
@ P_monoOrthographic
standard mono orthographic projection
Definition: SLEnums.h:137
@ TS_world
Definition: SLEnums.h:208
@ TS_object
Definition: SLEnums.h:210
SLMouseButton
Mouse button codes.
Definition: SLEnums.h:98
@ MB_left
Definition: SLEnums.h:100
@ MB_middle
Definition: SLEnums.h:101
@ FM_linear
Definition: SLEnums.h:264
SLEyeType
Enumeration for stereo eye type used for camera projection.
Definition: SLEnums.h:152
@ ET_center
Definition: SLEnums.h:154
@ ET_right
Definition: SLEnums.h:155
@ ET_left
Definition: SLEnums.h:153
SLKey
Keyboard key codes enumeration.
Definition: SLEnums.h:16
@ K_down
Definition: SLEnums.h:25
@ K_up
Definition: SLEnums.h:24
@ K_none
Definition: SLEnums.h:17
@ K_right
Definition: SLEnums.h:26
@ K_ctrl
Definition: SLEnums.h:63
@ K_alt
Definition: SLEnums.h:64
@ K_left
Definition: SLEnums.h:27
@ PT_lines
Definition: SLGLEnums.h:32
@ SP_colorAttribute
@ SP_textureOnly
#define GET_GL_ERROR
Definition: SLGLState.h:56
SLMat4< SLfloat > SLMat4f
Definition: SLMat4.h:1581
@ PRIMARY
Definition: SLRay.h:23
SLVec2< SLfloat > SLVec2f
Definition: SLVec2.h:141
vector< SLVec3f > SLVVec3f
Definition: SLVec3.h:325
SLVec3< SLfloat > SLVec3f
Definition: SLVec3.h:318
SLVec4< SLfloat > SLCol4f
Definition: SLVec4.h:237
Defines an axis aligned bounding box.
Definition: SLAABBox.h:34
SLVec3f centerWS()
Definition: SLAABBox.h:50
void fromOStoWS(const SLVec3f &minOS, const SLVec3f &maxOS, const SLMat4f &wm)
Recalculate min and max after transformation in world coords.
Definition: SLAABBox.cpp:46
void isVisible(SLbool visible)
Definition: SLAABBox.h:44
void sqrViewDist(SLfloat sqrVD)
Definition: SLAABBox.h:45
const SLRectf & rect() const
Definition: SLBackground.h:59
SLCol4f avgColor()
Definition: SLBackground.h:56
void colors(const SLCol4f &uniformColor)
Sets a uniform background color.
void renderInScene(const SLMat4f &wm, const SLVec3f &LT, const SLVec3f &LB, const SLVec3f &RT, const SLVec3f &RB)
Draws the background as a quad on the far clipping plane.
SLfloat _drag
simple constant drag that affects velocity
Definition: SLCamera.h:210
SLRaySamples2D _lensSamples
sample points for lens sampling (DOF)
Definition: SLCamera.h:220
SLFogMode _fogMode
0=LINEAR, 1=EXP, 2=EXP2
Definition: SLCamera.h:230
SLbool onTouch2Down(SLint x1, SLint y1, SLint x2, SLint y2) override
Definition: SLCamera.cpp:1280
SLDeviceLocation * _devLoc
Definition: SLCamera.h:238
SLfloat _fx
horizontal focal length
Definition: SLCamera.h:194
SLBackground _background
Colors or texture displayed in the background.
Definition: SLCamera.h:198
SLbool onKeyRelease(SLKey key, SLKey mod) override
Definition: SLCamera.cpp:1470
SLfloat _unitScaling
indicate what the current unit scale is
Definition: SLCamera.h:224
SLfloat _stereoEyeSeparation
eye separation for stereo mode
Definition: SLCamera.h:223
SLfloat _cy
sensor center in y direction
Definition: SLCamera.h:197
SLfloat maxSpeed() const
Definition: SLCamera.h:166
void buildAABB(SLAABBox &aabb, const SLMat4f &wmNode)
Definition: SLCamera.cpp:397
void setViewport(SLSceneView *sv, SLEyeType eye)
Sets the viewport transform depending on the projection.
Definition: SLCamera.cpp:459
SLfloat _cx
sensor center in x direction
Definition: SLCamera.h:196
static SLProjType currentProjection
Definition: SLCamera.h:179
SLstring toString() const
SLCamera::to_string returns important camera parameter as a string.
Definition: SLCamera.cpp:1646
static SLint currentDevRotation
Definition: SLCamera.h:181
SLfloat _fovV
Current vertical field of view (view angle) in degrees.
Definition: SLCamera.h:187
SLMat3f _enucorrRenu
Definition: SLCamera.h:246
SLbool onMouseUp(SLMouseButton button, SLint x, SLint y, SLKey mod) override
Gets called whenever the mouse button is released.
Definition: SLCamera.cpp:1207
SLRecti _viewport
framebuffer rectangle
Definition: SLCamera.h:192
SLfloat fovV() const
Vertical field of view.
Definition: SLCamera.h:135
SLfloat fovH() const
Horizontal field of view.
Definition: SLCamera.cpp:1504
SLchar _keyStates[256]
Stores for all movement keys whether they are pressed.
Definition: SLCamera.h:209
SLfloat _clipNear
Dist. to the near clipping plane.
Definition: SLCamera.h:189
SLVec2f projectWorldToNDC(const SLVec4f &worldPos) const
Project a world position into screen coordinates.
Definition: SLCamera.cpp:1601
SLstring projTypeStr() const
Definition: SLCamera.h:133
SLVec3f trackballVec(SLint x, SLint y) const
Returns a vector from the window center to a virtual trackball at [x,y].
Definition: SLCamera.cpp:1665
SLCamera(const SLstring &name="Camera")
Construct a new SLCamera::SLCamera object.
Definition: SLCamera.cpp:33
SLfloat _lensDiameter
Lens diameter.
Definition: SLCamera.h:219
SLfloat _maxSpeed
maximum speed in m/s, with high drag values this speed might not be achievable at all
Definition: SLCamera.h:211
SLfloat _fovInit
Initial vertical field of view (view angle) in degrees.
Definition: SLCamera.h:188
void passToUniforms(SLGLProgram *program)
Pass camera parameters to the uniform variables.
Definition: SLCamera.cpp:1688
SLbool _fogIsOn
Flag if fog blending is enabled.
Definition: SLCamera.h:229
SLbool onMouseMove(SLMouseButton button, SLint x, SLint y, SLKey mod) override
Gets called whenever the mouse is moved.
Definition: SLCamera.cpp:1031
SLfloat _fogDensity
Fog density for exponential modes.
Definition: SLCamera.h:231
SLVec3f focalPointWS() const
Definition: SLCamera.h:154
SLGLVertexArrayExt _vao
OpenGL Vertex array for rendering.
Definition: SLCamera.h:200
SLfloat _clipFar
Dist. to the far clipping plane.
Definition: SLCamera.h:190
void setView(SLSceneView *sv, SLEyeType eye)
Definition: SLCamera.cpp:719
SLVec2f _oldTouchPos1
Old mouse/touch position in pixels.
Definition: SLCamera.h:204
~SLCamera() override
Definition: SLCamera.cpp:90
SLPlane _plane[6]
6 frustum planes (l, r, t, b, n, f)
Definition: SLCamera.h:191
SLfloat _fogStart
Fog start distance for linear mode.
Definition: SLCamera.h:232
SLfloat focalDistScrH() const
Definition: SLCamera.cpp:444
void eyeToPixelRay(SLfloat x, SLfloat y, SLRay *ray)
eyeToPixelRay returns the a ray from the eye to the center of a pixel.
Definition: SLCamera.cpp:1514
SLfloat _focalDist
distance to lookAt point on the focal plane from lens
Definition: SLCamera.h:218
SLfloat _trackballSize
Size of trackball (0.8 = 80% of window size)
Definition: SLCamera.h:207
SLDeviceRotation * _devRot
Definition: SLCamera.h:237
static SLstring projTypeToStr(SLProjType pt)
Returns the projection type as string.
Definition: SLCamera.cpp:419
SLVec3f _acceleration
current acceleration vector
Definition: SLCamera.h:213
SLRectf _deselectRect
Mouse deselection rectangle. See SLMesh::handleRectangleSelection.
Definition: SLCamera.h:241
SLVec2f _oldTouchPos2
Old 2nd finger touch position in pixels.
Definition: SLCamera.h:205
SLfloat _moveAccel
move acceleration
Definition: SLCamera.h:215
SLstring animationStr() const
SLCamera::animationStr() returns the animation enum as string.
Definition: SLCamera.cpp:983
void statsRec(SLNodeStats &stats) override
SLCamera::statsRec updates the statistic parameters.
Definition: SLCamera.cpp:348
SLVec2f frustumSizeAtDistance(SLfloat distance)
Calculate and return frustum size at distance to camera center.
Definition: SLCamera.cpp:408
SLCamAnim _camAnim
did the camera updateRec in the last frame?
Definition: SLCamera.h:203
SLint _xOffsetPix
parameter for manual finger rotation and translation
Definition: SLCamera.h:244
SLbool _fogColorIsBack
fog color blended to the final color
Definition: SLCamera.h:235
SLVec3f _trackballStartVec
Trackball vector at mouse down.
Definition: SLCamera.h:206
virtual SLbool camUpdate(SLSceneView *sv, SLfloat timeMS)
Definition: SLCamera.cpp:98
void setFrustumPlanes()
SLCamera::setFrustumPlanes set the 6 plane from the view frustum.
Definition: SLCamera.cpp:1495
SLfloat focalDistScrW() const
Definition: SLCamera.cpp:453
SLfloat _viewportRatio
viewport.width / viewport.height = screen ratio
Definition: SLCamera.h:193
function< void(SLSceneView *sv)> _onCamUpdateCB
Definition: SLCamera.h:248
SLbool isInFrustum(SLAABBox *aabb)
SLCamera::isInFrustum does a simple and fast frustum culling test for AABBs.
Definition: SLCamera.cpp:1625
SLCol4f _fogColor
fog color blended to the final color
Definition: SLCamera.h:234
SLbool onTouch2Up(SLint x1, SLint y1, SLint x2, SLint y2) override
Definition: SLCamera.cpp:1412
void updateEnuCorrRenu(SLSceneView *sv, const SLMat3f &enuRc, float &f, SLVec3f &enuOffsetPix)
Calculate and apply correction from finger x-y-rotation.
Definition: SLCamera.cpp:641
SLint _stereoEye
-1=left, 0=center, 1=right
Definition: SLCamera.h:225
void drawMesh(SLSceneView *sv) override
SLCamera::drawMeshes draws the cameras frustum lines.
Definition: SLCamera.cpp:188
SLbool onMouseDown(SLMouseButton button, SLint x, SLint y, SLKey mod) override
Gets called whenever a mouse button gets pressed.
Definition: SLCamera.cpp:1005
void lookFrom(const SLVec3f &fromDir, const SLVec3f &upDir=SLVec3f::AXISY)
Sets the view to look from a direction towards the current focal point.
Definition: SLCamera.cpp:974
void setProjection(SLSceneView *sv, SLEyeType eye)
Definition: SLCamera.cpp:513
SLMat3f _stereoColorFilter
color filter matrix for anaglyphling is to adjust movement and stereo rendering correctly
Definition: SLCamera.h:226
static SLfloat currentFOV
Definition: SLCamera.h:180
SLfloat _brakeAccel
brake acceleration
Definition: SLCamera.h:214
SLbool onTouch2Move(SLint x1, SLint y1, SLint x2, SLint y2) override
Definition: SLCamera.cpp:1295
SLfloat _fy
vertical focal length
Definition: SLCamera.h:195
SLfloat aspect() const
Definition: SLCamera.h:139
static SLCamAnim currentAnimation
Definition: SLCamera.h:178
SLbool onKeyPress(SLKey key, SLKey mod) override
Definition: SLCamera.cpp:1425
const SLMat4f & updateAndGetVM() const
Definition: SLCamera.h:131
SLVec3f _velocity
current velocity vector
Definition: SLCamera.h:212
SLint _yOffsetPix
Definition: SLCamera.h:245
SLProjType _projType
Projection type.
Definition: SLCamera.h:186
void UVWFrame(SLVec3f &EYE, SLVec3f &U, SLVec3f &V, SLVec3f &W)
Definition: SLCamera.cpp:1578
SLbool onMouseWheel(SLint delta, SLKey mod) override
Definition: SLCamera.cpp:1243
SLRectf _selectRect
Mouse selection rectangle. See SLMesh::handleRectangleSelection.
Definition: SLCamera.h:240
void calcMinMax(SLVec3f &minV, SLVec3f &maxV) const
Definition: SLCamera.cpp:359
SLbool _movedLastFrame
Definition: SLCamera.h:202
SLfloat _fogEnd
Fog end distance for linear mode.
Definition: SLCamera.h:233
SLVec3d defaultENU() const
void offsetENU(SLVec3d offsetENU)
void isUsed(SLbool isUsed)
Setter that turns on the device rotation sensor.
SLVec3d originENU() const
void locMaxDistanceM(SLfloat maxDist)
void offsetMode(SLLocOffsetMode lom)
void hasOrigin(SLbool hasOL)
SLVec3d locENU() const
void offsetMode(SLRotOffsetMode rom)
SLMat3f rotationAveraged()
void zeroYawAtStart(SLbool zeroYaw)
void isUsed(SLbool isUsed)
Setter that turns on the device rotation sensor.
SLfloat startYawRAD() const
SLfloat _keyboardDeltaPos
Delta dist. for keyboard translation.
SLfloat _mouseRotationFactor
Mouse rotation sensibility.
static void viewToFrustumPlanes(SLPlane *planes, const SLMat4f &projectionMat, const SLMat4f &viewMat)
Definition: SLFrustum.cpp:24
SLint height()
Definition: SLGLOculusFB.h:39
SLint halfWidth()
Definition: SLGLOculusFB.h:38
SLbool isConnected()
Definition: SLGLOculus.h:65
const SLVec3f & viewAdjust(SLEyeType eye)
Definition: SLGLOculus.cpp:118
const SLQuat4f & orientation(SLEyeType eye)
Definition: SLGLOculus.cpp:205
const SLVec3f & position(SLEyeType eye)
Definition: SLGLOculus.cpp:215
const SLMat4f & projection(SLEyeType eye)
Definition: SLGLOculus.cpp:129
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
SLint uniform4fv(const SLchar *name, SLsizei count, const SLfloat *value) const
Passes 4 float values py pointer to the uniform variable "name".
SLint uniformMatrix3fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 3x3 float matrix values py pointer to the uniform variable "name".
SLint uniform1f(const SLchar *name, SLfloat v0) const
Passes the float value v0 to the uniform variable "name".
SLint uniform1i(const SLchar *name, SLint v0) const
Passes the int values v0 to the uniform variable "name".
Static container for standard shader programs.
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
void viewport(SLint x, SLint y, SLsizei width, SLsizei height)
Definition: SLGLState.cpp:378
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
SLMat4f viewMatrix
matrix for the active cameras view transform
Definition: SLGLState.h:91
void colorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
Definition: SLGLState.cpp:394
void clearDepthBuffer()
Definition: SLGLState.h:122
SLMat4f projectionMatrix
matrix for projection transform
Definition: SLGLState.h:90
void generateVertexPos(SLVVec2f *p)
Adds or updates & generates a position vertex attribute for colored line or point drawing.
void drawArrayAsColored(SLGLPrimitiveType primitiveType, SLCol4f color, SLfloat lineOrPointSize=1.0f, SLuint indexFirstVertex=0, SLuint countVertices=0)
Draws the array as the specified primitive with the color.
void rotation(const T angleDEG, const SLVec3< T > &axis)
Sets the rotation components
Definition: SLMat3.h:392
SLMat3< T > transposed() const
Returns the transposed of the matrix and leaves the itself unchanged.
Definition: SLMat3.h:346
void setMatrix(const SLMat3 &A)
Definition: SLMat3.h:299
void identity()
Definition: SLMat3.h:329
SLVec3< T > translation() const
Definition: SLMat4.h:184
void lookAt(T EyeX, T EyeY, T EyeZ, T AtX=0, T AtY=0, T AtZ=0, T UpX=0, T UpY=0, T UpZ=0)
Defines the a view matrix as the corresponding gluLookAt function.
Definition: SLMat4.h:708
SLMat3< T > mat3() const
Definition: SLMat4.h:98
void setTranslation(const SLVec3< T > &translation)
Set vector as submatrix describing the translational part.
Definition: SLMat4.h:393
void setRotation(const SLMat3< T > &rotation)
Set 3x3 submatrix describing the rotational part.
Definition: SLMat4.h:385
void perspectiveCenteredPP(T w, T h, T fx, T fy, T cx, T cy, T n, T f)
Defines a projection matrix for a calibrated camera, the principle point has to be centered (from int...
Definition: SLMat4.h:891
void setMatrix(const SLMat4 &A)
Set matrix by other 4x4 matrix.
Definition: SLMat4.h:335
void ortho(T l, T r, T b, T t, T n, T f)
Defines a orthographic projection matrix with a field of view angle.
Definition: SLMat4.h:911
void rotate(T degAng, T axisx, T axisy, T axisz)
Definition: SLMat4.h:656
SLstring toString() const
Definition: SLMat4.h:1567
SLVec3< T > multVec(SLVec3< T > v) const
Definition: SLMat4.h:576
void perspective(T fov, T aspect, T n, T f)
Defines a perspective projection matrix with a field of view angle.
Definition: SLMat4.h:874
void frustum(T l, T r, T b, T t, T n, T f)
Defines a view frustum projection matrix equivalent to glFrustum.
Definition: SLMat4.h:855
void translate(T tx, T ty, T tz=0)
Definition: SLMat4.h:601
SLNode represents a node in a hierarchical scene graph.
Definition: SLNode.h:147
void rotation(const SLQuat4f &rot, SLTransformSpace relativeTo=TS_parent)
Definition: SLNode.cpp:846
SLAABBox * aabb()
Definition: SLNode.h:301
void translation(const SLVec3f &pos, SLTransformSpace relativeTo=TS_parent)
Definition: SLNode.cpp:828
SLVec3f forwardOS() const
Definition: SLNode.h:477
void needWMUpdate()
Definition: SLNode.cpp:645
virtual void needUpdate()
Definition: SLNode.cpp:616
const SLMat4f & updateAndGetWM() const
Definition: SLNode.cpp:703
SLMat4f _om
object matrix for local transforms
Definition: SLNode.h:350
SLVec3f rightOS() const
Definition: SLNode.h:486
SLVec3f translationOS() const
Definition: SLNode.h:468
bool _castsShadows
flag if meshes of node should cast shadows
Definition: SLNode.h:357
virtual void statsRec(SLNodeStats &stats)
Definition: SLNode.cpp:479
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
SLMat4f _wm
world matrix for world transform
Definition: SLNode.h:352
void translate(const SLVec3f &vec, SLTransformSpace relativeTo=TS_object)
Definition: SLNode.cpp:906
Ray class with ray and intersection properties.
Definition: SLRay.h:40
SLint hitTriangle
Points to the intersected triangle.
Definition: SLRay.h:107
SLVec3f origin
Vector to the origin of ray in WS.
Definition: SLRay.h:75
SLRayType type
PRIMARY, REFLECTED, REFRACTED, SHADOW.
Definition: SLRay.h:92
SLint srcTriangle
Points to the triangle at ray origin.
Definition: SLRay.h:99
SLMesh * hitMesh
Points to the intersected mesh.
Definition: SLRay.h:106
SLint depth
Recursion depth for ray tracing.
Definition: SLRay.h:78
SLfloat length
length from origin to an intersection
Definition: SLRay.h:77
SLNode * hitNode
Points to the intersected node.
Definition: SLRay.h:105
SLfloat contrib
Current contribution of ray to color.
Definition: SLRay.h:79
SLVec3f hitPoint
Point of intersection.
Definition: SLRay.h:110
void setDir(const SLVec3f &Dir)
Setter for the rays direction in world space also setting the inverse direction.
Definition: SLRay.h:146
SLfloat y
Pixel position for primary rays.
Definition: SLRay.h:94
SLfloat x
Definition: SLRay.h:94
SLVec3f hitNormal
Surface normal at intersection point.
Definition: SLRay.h:111
void samples(SLuint x, SLuint y, SLbool evenlyDistributed=true)
Resets the sample point array by the sqrt of the no. of samples.
T width
Definition: SLRect.h:29
void tl(V v)
top-left corner
Definition: SLRect.h:63
T y
Definition: SLRect.h:29
void set(const T X, const T Y, const T WIDTH, const T HEIGHT)
Definition: SLRect.h:42
T x
Definition: SLRect.h:29
void setScnd(V v)
Definition: SLRect.h:67
T height
Definition: SLRect.h:29
void setZero()
Definition: SLRect.h:49
void skybox(SLSkybox *skybox)
Definition: SLScene.h:91
SLGLOculus * oculus()
Definition: SLScene.h:140
SLNode * singleNodeSelected()
Returns the node if only one is selected. See also SLMesh::selectNodeMesh.
Definition: SLScene.h:116
SceneView class represents a dynamic real time 3D view onto the scene.
Definition: SLSceneView.h:69
SLRecti viewportRect() const
Definition: SLSceneView.h:176
SLfloat scrWdivH() const
Definition: SLSceneView.h:174
void camera(SLCamera *camera)
Definition: SLSceneView.h:145
SLGLOculusFB * oculusFB()
Definition: SLSceneView.h:197
SLScene * s()
Definition: SLSceneView.h:167
void scrH(SLint scrH)
Definition: SLSceneView.h:148
static SLVec2 ZERO
Definition: SLVec2.h:135
void toPolar(T &r, T &phiRAD)
Calculates polar coords with radius & angle phi in radians (-pi < phi < pi)
Definition: SLVec2.h:97
T y
Definition: SLVec2.h:30
T x
Definition: SLVec2.h:30
void set(const T X, const T Y)
Definition: SLVec2.h:40
T length() const
Definition: SLVec2.h:87
T y
Definition: SLVec3.h:43
SLVec3 normalized() const
Definition: SLVec3.h:127
static SLVec3 AXISY
Definition: SLVec3.h:298
void cross(const SLVec3 &a, const SLVec3 &b)
Definition: SLVec3.h:118
T x
Definition: SLVec3.h:43
SLVec3 & normalize()
Definition: SLVec3.h:124
T length() const
Definition: SLVec3.h:122
static SLVec3 AXISX
Definition: SLVec3.h:297
void set(const T X, const T Y, const T Z)
Definition: SLVec3.h:59
T dot(const SLVec3 &v) const
Definition: SLVec3.h:117
T z
Definition: SLVec3.h:43
static SLVec3 AXISZ
Definition: SLVec3.h:299
static SLVec3 ZERO
Definition: SLVec3.h:285
T lengthSqr() const
Definition: SLVec3.h:123
T w
Definition: SLVec4.h:32
static SLVec4 WHITE
Definition: SLVec4.h:215
T y
Definition: SLVec4.h:32
static SLVec4 YELLOW
Definition: SLVec4.h:219
T x
Definition: SLVec4.h:32
std::vector< char > & get(std::string path)
Definition: SLIOMemory.cpp:24
static const float DEG2RAD
Definition: Utils.h:239
T sign(T a)
Definition: Utils.h:245
T abs(T a)
Definition: Utils.h:249
static const float RAD2DEG
Definition: Utils.h:238
T mod(T a, T b)
Definition: Utils.h:250
Struct for scene graph statistics.
Definition: SLNode.h:37
SLuint numTriangles
NO. of triangles in mesh.
Definition: SLNode.h:47
SLuint numBytes
NO. of bytes allocated.
Definition: SLNode.h:39