camera.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  Copyright (C) 2002-2013 Gilles Debunne. All rights reserved.
4 
5  This file is part of the QGLViewer library version 2.4.0.
6 
7  http://www.libqglviewer.com - contact@libqglviewer.com
8 
9  This file may be used under the terms of the GNU General Public License
10  versions 2.0 or 3.0 as published by the Free Software Foundation and
11  appearing in the LICENSE file included in the packaging of this file.
12  In addition, as a special exception, Gilles Debunne gives you certain
13  additional rights, described in the file GPL_EXCEPTION in this package.
14 
15  libQGLViewer uses dual licensing. Commercial/proprietary software must
16  purchase a libQGLViewer Commercial License.
17 
18  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
19  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 
21 *****************************************************************************/
22 
23 #include "domUtils.h"
24 #include "camera.h"
25 #include "qglviewer.h"
26 
27 using namespace std;
28 using namespace qglviewer;
29 
37 Camera::Camera()
38  : fieldOfView_(M_PI/4.0f)
39 {
40  // #CONNECTION# Camera copy constructor
42  // Requires the interpolationKfi_
44 
45  // #CONNECTION# All these default values identical in initFromDOMElement.
46 
47  // Requires fieldOfView() to define focusDistance()
48  setSceneRadius(1.0);
49 
50  // Initial value (only scaled after this)
51  orthoCoef_ = tan(fieldOfView()/2.0);
52 
53  // Also defines the revolveAroundPoint(), which changes orthoCoef_. Requires a frame().
54  setSceneCenter(Vec(0.0, 0.0, 0.0));
55 
56  // Requires fieldOfView() when called with ORTHOGRAPHIC. Attention to projectionMatrix_ below.
58 
59  // #CONNECTION# initFromDOMElement default values
60  setZNearCoefficient(0.005f);
61  setZClippingCoefficient(sqrt(3.0));
62 
63  // Dummy values
64  setScreenWidthAndHeight(600, 400);
65 
66  // Stereo parameters
67  setIODistance(0.062f);
69  // focusDistance is set from setFieldOfView()
70 
71  // #CONNECTION# Camera copy constructor
72  for (unsigned short j=0; j<16; ++j)
73  {
74  modelViewMatrix_[j] = ((j%5 == 0) ? 1.0 : 0.0);
75  // #CONNECTION# computeProjectionMatrix() is lazy and assumes 0.0 almost everywhere.
76  projectionMatrix_[j] = 0.0;
77  }
79 }
80 
86 {
87  delete frame_;
88  delete interpolationKfi_;
89 }
90 
91 
93 Camera::Camera(const Camera& camera)
94  : QObject()
95 {
96  // #CONNECTION# Camera constructor
98  // Requires the interpolationKfi_
100 
101  for (unsigned short j=0; j<16; ++j)
102  {
103  modelViewMatrix_[j] = ((j%5 == 0) ? 1.0 : 0.0);
104  // #CONNECTION# computeProjectionMatrix() is lazy and assumes 0.0 almost everywhere.
105  projectionMatrix_[j] = 0.0;
106  }
107 
108  (*this)=camera;
109 }
110 
124 {
126  setFieldOfView(camera.fieldOfView());
127  setSceneRadius(camera.sceneRadius());
128  setSceneCenter(camera.sceneCenter());
131  setType(camera.type());
132 
133  // Stereo parameters
134  setIODistance(camera.IODistance());
137 
138  orthoCoef_ = camera.orthoCoef_;
139 
140  // frame_ and interpolationKfi_ pointers are not shared.
141  frame_->setReferenceFrame(NULL);
142  frame_->setPosition(camera.position());
143  frame_->setOrientation(camera.orientation());
144 
146 
147  kfi_ = camera.kfi_;
148 
151 
152  return *this;
153 }
154 
164 void Camera::setScreenWidthAndHeight(int width, int height)
165 {
166  // Prevent negative and zero dimensions that would cause divisions by zero.
167  screenWidth_ = width > 0 ? width : 1;
168  screenHeight_ = height > 0 ? height : 1;
169 }
170 
208 float Camera::zNear() const
209 {
211 
212  // Prevents negative or null zNear values.
213  const float zMin = zNearCoefficient() * zClippingCoefficient() * sceneRadius();
214  if (z < zMin)
215  switch (type())
216  {
217  case Camera::PERSPECTIVE : z = zMin; break;
218  case Camera::ORTHOGRAPHIC : z = 0.0; break;
219  }
220  return z;
221 }
222 
232 float Camera::zFar() const
233 {
235 }
236 
247 {
248  // make ORTHOGRAPHIC frustum fit PERSPECTIVE (at least in plane normal to viewDirection(), passing
249  // through RAP). Done only when CHANGING type since orthoCoef_ may have been changed with a
250  // setRevolveAroundPoint() in the meantime.
251  if ( (type == Camera::ORTHOGRAPHIC) && (type_ == Camera::PERSPECTIVE) )
252  orthoCoef_ = tan(fieldOfView()/2.0);
253  type_ = type;
254 }
255 
270 {
271  if (!mcf)
272  return;
273 
274  frame_ = mcf;
276 }
277 
281 {
282  return fabs((frame()->coordinatesOf(sceneCenter())).z);
283 }
284 
285 
301 void Camera::getOrthoWidthHeight(GLdouble& halfWidth, GLdouble& halfHeight) const
302 {
303  const float dist = orthoCoef_ * fabs(cameraCoordinatesOf(revolveAroundPoint()).z);
304  //#CONNECTION# fitScreenRegion
305  halfWidth = dist * ((aspectRatio() < 1.0) ? 1.0 : aspectRatio());
306  halfHeight = dist * ((aspectRatio() < 1.0) ? 1.0/aspectRatio() : 1.0);
307 }
308 
309 
328 {
329  const float ZNear = zNear();
330  const float ZFar = zFar();
331 
332  switch (type())
333  {
334  case Camera::PERSPECTIVE:
335  {
336  // #CONNECTION# all non null coefficients were set to 0.0 in constructor.
337  const float f = 1.0/tan(fieldOfView()/2.0);
339  projectionMatrix_[5] = f;
340  projectionMatrix_[10] = (ZNear + ZFar) / (ZNear - ZFar);
341  projectionMatrix_[11] = -1.0;
342  projectionMatrix_[14] = 2.0 * ZNear * ZFar / (ZNear - ZFar);
343  projectionMatrix_[15] = 0.0;
344  // same as gluPerspective( 180.0*fieldOfView()/M_PI, aspectRatio(), zNear(), zFar() );
345  break;
346  }
348  {
349  GLdouble w, h;
350  getOrthoWidthHeight(w,h);
351  projectionMatrix_[0] = 1.0/w;
352  projectionMatrix_[5] = 1.0/h;
353  projectionMatrix_[10] = -2.0/(ZFar - ZNear);
354  projectionMatrix_[11] = 0.0;
355  projectionMatrix_[14] = -(ZFar + ZNear)/(ZFar - ZNear);
356  projectionMatrix_[15] = 1.0;
357  // same as glOrtho( -w, w, -h, h, zNear(), zFar() );
358  break;
359  }
360  }
361 }
362 
374 {
375  const Quaternion q = frame()->orientation();
376 
377  const double q00 = 2.0l * q[0] * q[0];
378  const double q11 = 2.0l * q[1] * q[1];
379  const double q22 = 2.0l * q[2] * q[2];
380 
381  const double q01 = 2.0l * q[0] * q[1];
382  const double q02 = 2.0l * q[0] * q[2];
383  const double q03 = 2.0l * q[0] * q[3];
384 
385  const double q12 = 2.0l * q[1] * q[2];
386  const double q13 = 2.0l * q[1] * q[3];
387 
388  const double q23 = 2.0l * q[2] * q[3];
389 
390  modelViewMatrix_[0] = 1.0l - q11 - q22;
391  modelViewMatrix_[1] = q01 - q23;
392  modelViewMatrix_[2] = q02 + q13;
393  modelViewMatrix_[3] = 0.0l;
394 
395  modelViewMatrix_[4] = q01 + q23;
396  modelViewMatrix_[5] = 1.0l - q22 - q00;
397  modelViewMatrix_[6] = q12 - q03;
398  modelViewMatrix_[7] = 0.0l;
399 
400  modelViewMatrix_[8] = q02 - q13;
401  modelViewMatrix_[9] = q12 + q03;
402  modelViewMatrix_[10] = 1.0l - q11 - q00;
403  modelViewMatrix_[11] = 0.0l;
404 
405  const Vec t = q.inverseRotate(frame()->position());
406 
407  modelViewMatrix_[12] = -t.x;
408  modelViewMatrix_[13] = -t.y;
409  modelViewMatrix_[14] = -t.z;
410  modelViewMatrix_[15] = 1.0l;
411 }
412 
413 
432 void Camera::loadProjectionMatrix(bool reset) const
433 {
434  // WARNING: makeCurrent must be called by every calling method
435  glMatrixMode(GL_PROJECTION);
436 
437  if (reset)
438  glLoadIdentity();
439 
441 
442  glMultMatrixd(projectionMatrix_);
443 }
444 
469 void Camera::loadModelViewMatrix(bool reset) const
470 {
471  // WARNING: makeCurrent must be called by every calling method
472  glMatrixMode(GL_MODELVIEW);
474  if (reset)
475  glLoadMatrixd(modelViewMatrix_);
476  else
477  glMultMatrixd(modelViewMatrix_);
478 }
479 
505 void Camera::loadProjectionMatrixStereo(bool leftBuffer) const
506 {
507  float left, right, bottom, top;
508  float screenHalfWidth, halfWidth, side, shift, delta;
509 
510  glMatrixMode(GL_PROJECTION);
511  glLoadIdentity();
512 
513  switch (type())
514  {
515  case Camera::PERSPECTIVE:
516  // compute half width of screen,
517  // corresponding to zero parallax plane to deduce decay of cameras
518  screenHalfWidth = focusDistance() * tan(horizontalFieldOfView() / 2.0);
519  shift = screenHalfWidth * IODistance() / physicalScreenWidth();
520  // should be * current y / y total
521  // to take into account that the window doesn't cover the entire screen
522 
523  // compute half width of "view" at znear and the delta corresponding to
524  // the shifted camera to deduce what to set for asymmetric frustums
525  halfWidth = zNear() * tan(horizontalFieldOfView() / 2.0);
526  delta = shift * zNear() / focusDistance();
527  side = leftBuffer ? -1.0 : 1.0;
528 
529  left = -halfWidth + side * delta;
530  right = halfWidth + side * delta;
531  top = halfWidth / aspectRatio();
532  bottom = -top;
533  glFrustum(left, right, bottom, top, zNear(), zFar() );
534  break;
535 
537  qWarning("Camera::setProjectionMatrixStereo: Stereo not available with Ortho mode");
538  break;
539  }
540 }
541 
560 void Camera::loadModelViewMatrixStereo(bool leftBuffer) const
561 {
562  // WARNING: makeCurrent must be called by every calling method
563  glMatrixMode(GL_MODELVIEW);
564 
565  float halfWidth = focusDistance() * tan(horizontalFieldOfView() / 2.0);
566  float shift = halfWidth * IODistance() / physicalScreenWidth(); // * current window width / full screen width
567 
569  if (leftBuffer)
570  modelViewMatrix_[12] -= shift;
571  else
572  modelViewMatrix_[12] += shift;
573  glLoadMatrixd(modelViewMatrix_);
574 }
575 
590 void Camera::getProjectionMatrix(GLdouble m[16]) const
591 {
592  // May not be needed, but easier and more robust like this.
594  for (unsigned short i=0; i<16; ++i)
595  m[i] = projectionMatrix_[i];
596 }
597 
612 void Camera::getModelViewMatrix(GLdouble m[16]) const
613 {
614  // May not be needed, but easier like this.
615  // Prevents from retrieving matrix in stereo mode -> overwrites shifted value.
617  for (unsigned short i=0; i<16; ++i)
618  m[i] = modelViewMatrix_[i];
619 }
620 
624 void Camera::getModelViewProjectionMatrix(GLdouble m[16]) const
625 {
626  GLdouble mv[16];
627  GLdouble proj[16];
628  getModelViewMatrix(mv);
629  getProjectionMatrix(proj);
630 
631  for (unsigned short i=0; i<4; ++i)
632  {
633  for (unsigned short j=0; j<4; ++j)
634  {
635  double sum = 0.0;
636  for (unsigned short k=0; k<4; ++k)
637  sum += proj[i+4*k]*mv[k+4*j];
638  m[i+4*j] = sum;
639  }
640  }
641 }
642 
643 #ifndef DOXYGEN
644 void Camera::getProjectionMatrix(GLfloat m[16]) const
645 {
646  qWarning("Warning : Camera::getProjectionMatrix requires a GLdouble matrix array");
647  static GLdouble mat[16];
648  getProjectionMatrix(mat);
649  for (int i=0; i<16; ++i)
650  m[i] = float(mat[i]);
651 }
652 
653 void Camera::getModelViewMatrix(GLfloat m[16]) const
654 {
655  qWarning("Warning : Camera::getModelViewMatrix requires a GLdouble matrix array");
656  static GLdouble mat[16];
657  getModelViewMatrix(mat);
658  for (int i=0; i<16; ++i)
659  m[i] = float(mat[i]);
660 }
661 #endif
662 
667 void Camera::setSceneRadius(float radius)
668 {
669  if (radius <= 0.0)
670  {
671  qWarning("Scene radius must be positive - Ignoring value");
672  return;
673  }
674 
675  sceneRadius_ = radius;
676 
677  setFocusDistance(sceneRadius() / tan(fieldOfView()/2.0));
678 
679  frame()->setFlySpeed(0.01*sceneRadius());
680 }
681 
684 void Camera::setSceneBoundingBox(const Vec& min, const Vec& max)
685 {
686  setSceneCenter((min+max)/2.0);
687  setSceneRadius(0.5*(max-min).norm());
688 }
689 
690 
694 void Camera::setSceneCenter(const Vec& center)
695 {
696  sceneCenter_ = center;
698 }
699 
705 bool Camera::setSceneCenterFromPixel(const QPoint& pixel)
706 {
707  bool found;
708  Vec point = pointUnderPixel(pixel, found);
709  if (found)
710  setSceneCenter(point);
711  return found;
712 }
713 
716 {
717  const float prevDist = fabs(cameraCoordinatesOf(revolveAroundPoint()).z);
718 
720 
721  // orthoCoef_ is used to compensate for changes of the revolveAroundPoint, so that the image does
722  // not change when the revolveAroundPoint is changed in ORTHOGRAPHIC mode.
723  const float newDist = fabs(cameraCoordinatesOf(revolveAroundPoint()).z);
724  // Prevents division by zero when rap is set to camera position
725  if ((prevDist > 1E-9) && (newDist > 1E-9))
726  orthoCoef_ *= prevDist / newDist;
727 }
728 
738 bool Camera::setRevolveAroundPointFromPixel(const QPoint& pixel)
739 {
740  bool found;
741  Vec point = pointUnderPixel(pixel, found);
742  if (found)
743  setRevolveAroundPoint(point);
744  return found;
745 }
746 
761 float Camera::pixelGLRatio(const Vec& position) const
762 {
763  switch (type())
764  {
765  case Camera::PERSPECTIVE :
766  return 2.0 * fabs((frame()->coordinatesOf(position)).z) * tan(fieldOfView()/2.0) / screenHeight();
767  case Camera::ORTHOGRAPHIC :
768  {
769  GLdouble w, h;
770  getOrthoWidthHeight(w,h);
771  return 2.0 * h / screenHeight();
772  }
773  }
774  // Bad compilers complain
775  return 1.0;
776 }
777 
804 {
805  if (distanceToSceneCenter() > sqrt(2.0)*sceneRadius())
807  else
808  setFieldOfView(M_PI / 2.0f);
809 }
810 
817 void Camera::interpolateToZoomOnPixel(const QPoint& pixel)
818 {
819  const float coef = 0.1f;
820 
821  bool found;
822  Vec target = pointUnderPixel(pixel, found);
823 
824  if (!found)
825  return;
826 
829 
832 
833  interpolationKfi_->addKeyFrame(Frame(0.3f*frame()->position() + 0.7f*target, frame()->orientation()), 0.4f);
834 
835  // Small hack: attach a temporary frame to take advantage of lookAt without modifying frame
836  static ManipulatedCameraFrame* tempFrame = new ManipulatedCameraFrame();
837  ManipulatedCameraFrame* const originalFrame = frame();
838  tempFrame->setPosition(coef*frame()->position() + (1.0-coef)*target);
839  tempFrame->setOrientation(frame()->orientation());
840  setFrame(tempFrame);
841  lookAt(target);
842  setFrame(originalFrame);
843 
844  interpolationKfi_->addKeyFrame(*(tempFrame), 1.0);
845 
847 }
848 
856 {
859 
862 
863  // Small hack: attach a temporary frame to take advantage of lookAt without modifying frame
864  static ManipulatedCameraFrame* tempFrame = new ManipulatedCameraFrame();
865  ManipulatedCameraFrame* const originalFrame = frame();
866  tempFrame->setPosition(frame()->position());
867  tempFrame->setOrientation(frame()->orientation());
868  setFrame(tempFrame);
869  showEntireScene();
870  setFrame(originalFrame);
871 
872  interpolationKfi_->addKeyFrame(*(tempFrame));
873 
875 }
876 
877 
884 void Camera::interpolateTo(const Frame& fr, float duration)
885 {
888 
891  interpolationKfi_->addKeyFrame(fr, duration);
892 
894 }
895 
896 
913 Vec Camera::pointUnderPixel(const QPoint& pixel, bool& found) const
914 {
915  float depth;
916  // Qt uses upper corner for its origin while GL uses the lower corner.
917  glReadPixels(pixel.x(), screenHeight()-1-pixel.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
918  found = depth < 1.0;
919  Vec point(pixel.x(), pixel.y(), depth);
920  point = unprojectedCoordinatesOf(point);
921  return point;
922 }
923 
930 {
932 }
933 
940 {
942 }
943 
950 void Camera::lookAt(const Vec& target)
951 {
952  setViewDirection(target - position());
953 }
954 
962 void Camera::fitSphere(const Vec& center, float radius)
963 {
964  float distance = 0.0f;
965  switch (type())
966  {
967  case Camera::PERSPECTIVE :
968  {
969  const float yview = radius / sin(fieldOfView()/2.0);
970  const float xview = radius / sin(horizontalFieldOfView()/2.0);
971  distance = qMax(xview,yview);
972  break;
973  }
974  case Camera::ORTHOGRAPHIC :
975  {
976  distance = ((center-revolveAroundPoint()) * viewDirection()) + (radius / orthoCoef_);
977  break;
978  }
979  }
980  Vec newPos(center - distance * viewDirection());
981  frame()->setPositionWithConstraint(newPos);
982 }
983 
986 void Camera::fitBoundingBox(const Vec& min, const Vec& max)
987 {
988  float diameter = qMax(fabs(max[1]-min[1]), fabs(max[0]-min[0]));
989  diameter = qMax(fabsf(max[2]-min[2]), diameter);
990  fitSphere(0.5*(min+max), 0.5*diameter);
991 }
992 
1000 void Camera::fitScreenRegion(const QRect& rectangle)
1001 {
1002  const Vec vd = viewDirection();
1003  const float distToPlane = distanceToSceneCenter();
1004  const QPoint center = rectangle.center();
1005 
1006  Vec orig, dir;
1007  convertClickToLine( center, orig, dir );
1008  Vec newCenter = orig + distToPlane / (dir*vd) * dir;
1009 
1010  convertClickToLine( QPoint(rectangle.x(), center.y()), orig, dir );
1011  const Vec pointX = orig + distToPlane / (dir*vd) * dir;
1012 
1013  convertClickToLine( QPoint(center.x(), rectangle.y()), orig, dir );
1014  const Vec pointY = orig + distToPlane / (dir*vd) * dir;
1015 
1016  float distance = 0.0f;
1017  switch (type())
1018  {
1019  case Camera::PERSPECTIVE :
1020  {
1021  const float distX = (pointX-newCenter).norm() / sin(horizontalFieldOfView()/2.0);
1022  const float distY = (pointY-newCenter).norm() / sin(fieldOfView()/2.0);
1023  distance = qMax(distX, distY);
1024  break;
1025  }
1026  case Camera::ORTHOGRAPHIC :
1027  {
1028  const float dist = ((newCenter-revolveAroundPoint()) * vd);
1029  //#CONNECTION# getOrthoWidthHeight
1030  const float distX = (pointX-newCenter).norm() / orthoCoef_ / ((aspectRatio() < 1.0) ? 1.0 : aspectRatio());
1031  const float distY = (pointY-newCenter).norm() / orthoCoef_ / ((aspectRatio() < 1.0) ? 1.0/aspectRatio() : 1.0);
1032  distance = dist + qMax(distX, distY);
1033  break;
1034  }
1035  }
1036 
1037  Vec newPos(newCenter - distance * vd);
1038  frame()->setPositionWithConstraint(newPos);
1039 }
1040 
1056 void Camera::setUpVector(const Vec& up, bool noMove)
1057 {
1058  Quaternion q(Vec(0.0, 1.0, 0.0), frame()->transformOf(up));
1059 
1060  if (!noMove)
1061  frame()->setPosition(revolveAroundPoint() - (frame()->orientation()*q).rotate(frame()->coordinatesOf(revolveAroundPoint())));
1062 
1063  frame()->rotate(q);
1064 
1065  // Useful in fly mode to keep the horizontal direction.
1066  frame()->updateFlyUpVector();
1067 }
1068 
1080 void Camera::setOrientation(float theta, float phi)
1081 {
1082  Vec axis(0.0, 1.0, 0.0);
1083  const Quaternion rot1(axis, theta);
1084  axis = Vec(-cos(theta), 0., sin(theta));
1085  const Quaternion rot2(axis, phi);
1086  setOrientation(rot1 * rot2);
1087 }
1088 
1091 {
1092  frame()->setOrientation(q);
1093  frame()->updateFlyUpVector();
1094 }
1095 
1101 void Camera::setViewDirection(const Vec& direction)
1102 {
1103  if (direction.squaredNorm() < 1E-10)
1104  return;
1105 
1106  Vec xAxis = direction ^ upVector();
1107  if (xAxis.squaredNorm() < 1E-10)
1108  {
1109  // target is aligned with upVector, this means a rotation around X axis
1110  // X axis is then unchanged, let's keep it !
1111  xAxis = frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0));
1112  }
1113 
1114  Quaternion q;
1115  q.setFromRotatedBasis(xAxis, xAxis^direction, -direction);
1117 }
1118 
1119 // Compute a 3 by 3 determinant.
1120 static float det(float m00,float m01,float m02,
1121  float m10,float m11,float m12,
1122  float m20,float m21,float m22)
1123 {
1124  return m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m10*m01*m22 - m00*m21*m12;
1125 }
1126 
1127 // Computes the index of element [i][j] in a \c float matrix[3][4].
1128 static inline unsigned int ind(unsigned int i, unsigned int j)
1129 {
1130  return (i*4+j);
1131 }
1132 
1133 
1151 void Camera::setFromModelViewMatrix(const GLdouble* const modelViewMatrix)
1152 {
1153  // Get upper left (rotation) matrix
1154  double upperLeft[3][3];
1155  for (int i=0; i<3; ++i)
1156  for (int j=0; j<3; ++j)
1157  upperLeft[i][j] = modelViewMatrix[i*4+j];
1158 
1159  // Transform upperLeft into the associated Quaternion
1160  Quaternion q;
1161  q.setFromRotationMatrix(upperLeft);
1162 
1163  setOrientation(q);
1164  setPosition(-q.rotate(Vec(modelViewMatrix[12], modelViewMatrix[13], modelViewMatrix[14])));
1165 }
1166 
1189 void Camera::setFromProjectionMatrix(const float matrix[12])
1190 {
1191  // The 3 lines of the matrix are the normals to the planes x=0, y=0, z=0
1192  // in the camera CS. As we normalize them, we do not need the 4th coordinate.
1193  Vec line_0(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,2)]);
1194  Vec line_1(matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,2)]);
1195  Vec line_2(matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,2)]);
1196 
1197  line_0.normalize();
1198  line_1.normalize();
1199  line_2.normalize();
1200 
1201  // The camera position is at (0,0,0) in the camera CS so it is the
1202  // intersection of the 3 planes. It can be seen as the kernel
1203  // of the 3x4 projection matrix. We calculate it through 4 dimensional
1204  // vectorial product. We go directly into 3D that is to say we directly
1205  // divide the first 3 coordinates by the 4th one.
1206 
1207  // We derive the 4 dimensional vectorial product formula from the
1208  // computation of a 4x4 determinant that is developped according to
1209  // its 4th column. This implies some 3x3 determinants.
1210  const Vec cam_pos = Vec(det(matrix[ind(0,1)],matrix[ind(0,2)],matrix[ind(0,3)],
1211  matrix[ind(1,1)],matrix[ind(1,2)],matrix[ind(1,3)],
1212  matrix[ind(2,1)],matrix[ind(2,2)],matrix[ind(2,3)]),
1213 
1214  -det(matrix[ind(0,0)],matrix[ind(0,2)],matrix[ind(0,3)],
1215  matrix[ind(1,0)],matrix[ind(1,2)],matrix[ind(1,3)],
1216  matrix[ind(2,0)],matrix[ind(2,2)],matrix[ind(2,3)]),
1217 
1218  det(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,3)],
1219  matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,3)],
1220  matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,3)])) /
1221 
1222  (-det(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,2)],
1223  matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,2)],
1224  matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,2)]));
1225 
1226  // We compute the rotation matrix column by column.
1227 
1228  // GL Z axis is front facing.
1229  Vec column_2 = -line_2;
1230 
1231  // X-axis is almost like line_0 but should be orthogonal to the Z axis.
1232  Vec column_0 = ((column_2^line_0)^column_2);
1233  column_0.normalize();
1234 
1235  // Y-axis is almost like line_1 but should be orthogonal to the Z axis.
1236  // Moreover line_1 is downward oriented as the screen CS.
1237  Vec column_1 = -((column_2^line_1)^column_2);
1238  column_1.normalize();
1239 
1240  double rot[3][3];
1241  rot[0][0] = column_0[0];
1242  rot[1][0] = column_0[1];
1243  rot[2][0] = column_0[2];
1244 
1245  rot[0][1] = column_1[0];
1246  rot[1][1] = column_1[1];
1247  rot[2][1] = column_1[2];
1248 
1249  rot[0][2] = column_2[0];
1250  rot[1][2] = column_2[1];
1251  rot[2][2] = column_2[2];
1252 
1253  // We compute the field of view
1254 
1255  // line_1^column_0 -> vector of intersection line between
1256  // y_screen=0 and x_camera=0 plane.
1257  // column_2*(...) -> cos of the angle between Z vector et y_screen=0 plane
1258  // * 2 -> field of view = 2 * half angle
1259 
1260  // We need some intermediate values.
1261  Vec dummy = line_1^column_0;
1262  dummy.normalize();
1263  float fov = acos(column_2*dummy) * 2.0;
1264 
1265  // We set the camera.
1266  Quaternion q;
1267  q.setFromRotationMatrix(rot);
1268  setOrientation(q);
1269  setPosition(cam_pos);
1270  setFieldOfView(fov);
1271 }
1272 
1273 
1274 /*
1275  // persp : projectionMatrix_[0] = f/aspectRatio();
1276 void Camera::setFromProjectionMatrix(const GLdouble* projectionMatrix)
1277 {
1278  QString message;
1279  if ((fabs(projectionMatrix[1]) > 1E-3) ||
1280  (fabs(projectionMatrix[2]) > 1E-3) ||
1281  (fabs(projectionMatrix[3]) > 1E-3) ||
1282  (fabs(projectionMatrix[4]) > 1E-3) ||
1283  (fabs(projectionMatrix[6]) > 1E-3) ||
1284  (fabs(projectionMatrix[7]) > 1E-3) ||
1285  (fabs(projectionMatrix[8]) > 1E-3) ||
1286  (fabs(projectionMatrix[9]) > 1E-3))
1287  message = "Non null coefficient in projection matrix - Aborting";
1288  else
1289  if ((fabs(projectionMatrix[11]+1.0) < 1E-5) && (fabs(projectionMatrix[15]) < 1E-5))
1290  {
1291  if (projectionMatrix[5] < 1E-4)
1292  message="Negative field of view in Camera::setFromProjectionMatrix";
1293  else
1294  setType(Camera::PERSPECTIVE);
1295  }
1296  else
1297  if ((fabs(projectionMatrix[11]) < 1E-5) && (fabs(projectionMatrix[15]-1.0) < 1E-5))
1298  setType(Camera::ORTHOGRAPHIC);
1299  else
1300  message = "Unable to determine camera type in setFromProjectionMatrix - Aborting";
1301 
1302  if (!message.isEmpty())
1303  {
1304  qWarning(message);
1305  return;
1306  }
1307 
1308  switch (type())
1309  {
1310  case Camera::PERSPECTIVE:
1311  {
1312  setFieldOfView(2.0 * atan(1.0/projectionMatrix[5]));
1313  const float far = projectionMatrix[14] / (2.0 * (1.0 + projectionMatrix[10]));
1314  const float near = (projectionMatrix[10]+1.0) / (projectionMatrix[10]-1.0) * far;
1315  setSceneRadius((far-near)/2.0);
1316  setSceneCenter(position() + (near + sceneRadius())*viewDirection());
1317  break;
1318  }
1319  case Camera::ORTHOGRAPHIC:
1320  {
1321  GLdouble w, h;
1322  getOrthoWidthHeight(w,h);
1323  projectionMatrix_[0] = 1.0/w;
1324  projectionMatrix_[5] = 1.0/h;
1325  projectionMatrix_[10] = -2.0/(ZFar - ZNear);
1326  projectionMatrix_[11] = 0.0;
1327  projectionMatrix_[14] = -(ZFar + ZNear)/(ZFar - ZNear);
1328  projectionMatrix_[15] = 1.0;
1329  // same as glOrtho( -w, w, -h, h, zNear(), zFar() );
1330  break;
1331  }
1332  }
1333 }
1334 */
1335 
1337 
1339 void Camera::getCameraCoordinatesOf(const float src[3], float res[3]) const
1340 {
1341  Vec r = cameraCoordinatesOf(Vec(src));
1342  for (int i=0; i<3; ++i)
1343  res[i] = r[i];
1344 }
1345 
1347 void Camera::getWorldCoordinatesOf(const float src[3], float res[3]) const
1348 {
1349  Vec r = worldCoordinatesOf(Vec(src));
1350  for (int i=0; i<3; ++i)
1351  res[i] = r[i];
1352 }
1353 
1359 void Camera::getViewport(GLint viewport[4]) const
1360 {
1361  viewport[0] = 0;
1362  viewport[1] = screenHeight();
1363  viewport[2] = screenWidth();
1364  viewport[3] = -screenHeight();
1365 }
1366 
1442 {
1443  GLdouble x,y,z;
1444  static GLint viewport[4];
1445  getViewport(viewport);
1446 
1447  if (frame)
1448  {
1449  const Vec tmp = frame->inverseCoordinatesOf(src);
1450  gluProject(tmp.x,tmp.y,tmp.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z);
1451  }
1452  else
1453  gluProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z);
1454 
1455  return Vec(x,y,z);
1456 }
1457 
1484 {
1485  GLdouble x,y,z;
1486  static GLint viewport[4];
1487  getViewport(viewport);
1488  gluUnProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z);
1489  if (frame)
1490  return frame->coordinatesOf(Vec(x,y,z));
1491  else
1492  return Vec(x,y,z);
1493 }
1494 
1496 void Camera::getProjectedCoordinatesOf(const float src[3], float res[3], const Frame* frame) const
1497 {
1498  Vec r = projectedCoordinatesOf(Vec(src), frame);
1499  for (int i=0; i<3; ++i)
1500  res[i] = r[i];
1501 }
1502 
1504 void Camera::getUnprojectedCoordinatesOf(const float src[3], float res[3], const Frame* frame) const
1505 {
1506  Vec r = unprojectedCoordinatesOf(Vec(src), frame);
1507  for (int i=0; i<3; ++i)
1508  res[i] = r[i];
1509 }
1510 
1512 
1517 {
1518  if (kfi_.contains(i))
1519  return kfi_[i];
1520  else
1521  return NULL;
1522 }
1523 
1543 {
1544  if (kfi)
1545  kfi_[i] = kfi;
1546  else
1547  kfi_.remove(i);
1548 }
1549 
1563 {
1564  if (!kfi_.contains(i))
1566 
1567  kfi_[i]->addKeyFrame(*(frame()));
1568 }
1569 
1578 void Camera::playPath(int i)
1579 {
1580  if (kfi_.contains(i)) {
1581  if (kfi_[i]->interpolationIsStarted())
1582  kfi_[i]->stopInterpolation();
1583  else
1584  kfi_[i]->startInterpolation();
1585  }
1586 }
1587 
1594 {
1595  if (kfi_.contains(i)) {
1596  if ((kfi_[i]->interpolationIsStarted()))
1597  kfi_[i]->stopInterpolation();
1598  else
1599  {
1600  kfi_[i]->resetInterpolation();
1601  kfi_[i]->interpolateAtTime(kfi_[i]->interpolationTime());
1602  }
1603  }
1604 }
1605 
1615 {
1616  if (kfi_.contains(i))
1617  {
1618  kfi_[i]->stopInterpolation();
1619  delete kfi_[i];
1620  kfi_.remove(i);
1621  }
1622 }
1623 
1631 {
1632  for (QMap<int, KeyFrameInterpolator*>::ConstIterator it = kfi_.begin(), end=kfi_.end(); it != end; ++it)
1633 #if QT_VERSION >= 0x040000
1634  (it.value())->drawPath(3, 5, sceneRadius());
1635 #else
1636  (it.data())->drawPath(3, 5, sceneRadius());
1637 #endif
1638 }
1639 
1641 
1667 QDomElement Camera::domElement(const QString& name, QDomDocument& document) const
1668 {
1669  QDomElement de = document.createElement(name);
1670  QDomElement paramNode = document.createElement("Parameters");
1671  paramNode.setAttribute("fieldOfView", QString::number(fieldOfView()));
1672  paramNode.setAttribute("zNearCoefficient", QString::number(zNearCoefficient()));
1673  paramNode.setAttribute("zClippingCoefficient", QString::number(zClippingCoefficient()));
1674  paramNode.setAttribute("orthoCoef", QString::number(orthoCoef_));
1675  paramNode.setAttribute("sceneRadius", QString::number(sceneRadius()));
1676  paramNode.appendChild(sceneCenter().domElement("SceneCenter", document));
1677 
1678  switch (type())
1679  {
1680  case Camera::PERSPECTIVE : paramNode.setAttribute("Type", "PERSPECTIVE"); break;
1681  case Camera::ORTHOGRAPHIC : paramNode.setAttribute("Type", "ORTHOGRAPHIC"); break;
1682  }
1683  de.appendChild(paramNode);
1684 
1685  QDomElement stereoNode = document.createElement("Stereo");
1686  stereoNode.setAttribute("IODist", QString::number(IODistance()));
1687  stereoNode.setAttribute("focusDistance", QString::number(focusDistance()));
1688  stereoNode.setAttribute("physScreenWidth", QString::number(physicalScreenWidth()));
1689  de.appendChild(stereoNode);
1690 
1691  de.appendChild(frame()->domElement("ManipulatedCameraFrame", document));
1692 
1693  // KeyFrame paths
1694  for (QMap<int, KeyFrameInterpolator*>::ConstIterator it = kfi_.begin(), end=kfi_.end(); it != end; ++it)
1695  {
1696 #if QT_VERSION >= 0x040000
1697  QDomElement kfNode = (it.value())->domElement("KeyFrameInterpolator", document);
1698 #else
1699  QDomElement kfNode = (it.data())->domElement("KeyFrameInterpolator", document);
1700 #endif
1701  kfNode.setAttribute("index", QString::number(it.key()));
1702  de.appendChild(kfNode);
1703  }
1704 
1705  return de;
1706 }
1707 
1729 void Camera::initFromDOMElement(const QDomElement& element)
1730 {
1731  QDomElement child=element.firstChild().toElement();
1732 
1733 #if QT_VERSION >= 0x040000
1734  QMutableMapIterator<int, KeyFrameInterpolator*> it(kfi_);
1735  while (it.hasNext()) {
1736  it.next();
1737 #else
1738  for (QMap<int, KeyFrameInterpolator*>::Iterator it = kfi_.begin(), end=kfi_.end(); it != end; ++it) {
1739 #endif
1740  deletePath(it.key());
1741  }
1742 
1743  while (!child.isNull())
1744  {
1745  if (child.tagName() == "Parameters")
1746  {
1747  // #CONNECTION# Default values set in constructor
1748  setFieldOfView(DomUtils::floatFromDom(child, "fieldOfView", M_PI/4.0f));
1749  setZNearCoefficient(DomUtils::floatFromDom(child, "zNearCoefficient", 0.005f));
1750  setZClippingCoefficient(DomUtils::floatFromDom(child, "zClippingCoefficient", sqrt(3.0)));
1751  orthoCoef_ = DomUtils::floatFromDom(child, "orthoCoef", tan(fieldOfView()/2.0));
1752  setSceneRadius(DomUtils::floatFromDom(child, "sceneRadius", sceneRadius()));
1753 
1755  QString type = child.attribute("Type", "PERSPECTIVE");
1756  if (type == "PERSPECTIVE") setType(Camera::PERSPECTIVE);
1757  if (type == "ORTHOGRAPHIC") setType(Camera::ORTHOGRAPHIC);
1758 
1759  QDomElement child2=child.firstChild().toElement();
1760  while (!child2.isNull())
1761  {
1762  /* Although the scene does not change when a camera is loaded, restore the saved center and radius values.
1763  Mainly useful when a the viewer is restored on startup, with possible additional cameras. */
1764  if (child2.tagName() == "SceneCenter")
1765  setSceneCenter(Vec(child2));
1766 
1767  child2 = child2.nextSibling().toElement();
1768  }
1769  }
1770 
1771  if (child.tagName() == "ManipulatedCameraFrame")
1772  frame()->initFromDOMElement(child);
1773 
1774  if (child.tagName() == "Stereo")
1775  {
1776  setIODistance(DomUtils::floatFromDom(child, "IODist", 0.062f));
1777  setFocusDistance(DomUtils::floatFromDom(child, "focusDistance", focusDistance()));
1778  setPhysicalScreenWidth(DomUtils::floatFromDom(child, "physScreenWidth", 0.5f));
1779  }
1780 
1781  if (child.tagName() == "KeyFrameInterpolator")
1782  {
1783  int index = DomUtils::intFromDom(child, "index", 0);
1785  if (keyFrameInterpolator(index))
1787  }
1788 
1789  child = child.nextSibling().toElement();
1790  }
1791 }
1792 
1804 void Camera::convertClickToLine(const QPoint& pixel, Vec& orig, Vec& dir) const
1805 {
1806  switch (type())
1807  {
1808  case Camera::PERSPECTIVE:
1809  orig = position();
1810  dir = Vec( ((2.0 * pixel.x() / screenWidth()) - 1.0) * tan(fieldOfView()/2.0) * aspectRatio(),
1811  ((2.0 * (screenHeight()-pixel.y()) / screenHeight()) - 1.0) * tan(fieldOfView()/2.0),
1812  -1.0 );
1813  dir = worldCoordinatesOf(dir) - orig;
1814  dir.normalize();
1815  break;
1816 
1817  case Camera::ORTHOGRAPHIC:
1818  {
1819  GLdouble w,h;
1820  getOrthoWidthHeight(w,h);
1821  orig = Vec((2.0 * pixel.x() / screenWidth() - 1.0)*w, -(2.0 * pixel.y() / screenHeight() - 1.0)*h, 0.0);
1822  orig = worldCoordinatesOf(orig);
1823  dir = viewDirection();
1824  break;
1825  }
1826  }
1827 }
1828 
1829 #ifndef DOXYGEN
1830 
1831 void Camera::drawCamera(float, float, float)
1832 {
1833  qWarning("drawCamera is deprecated. Use Camera::draw() instead.");
1834 }
1835 #endif
1836 
1857 void Camera::draw(bool drawFarPlane, float scale) const
1858 {
1859  glPushMatrix();
1860  glMultMatrixd(frame()->worldMatrix());
1861 
1862  // 0 is the upper left coordinates of the near corner, 1 for the far one
1863  Vec points[2];
1864 
1865  points[0].z = scale * zNear();
1866  points[1].z = scale * zFar();
1867 
1868  switch (type())
1869  {
1870  case Camera::PERSPECTIVE:
1871  {
1872  points[0].y = points[0].z * tan(fieldOfView()/2.0);
1873  points[0].x = points[0].y * aspectRatio();
1874 
1875  const float ratio = points[1].z / points[0].z;
1876 
1877  points[1].y = ratio * points[0].y;
1878  points[1].x = ratio * points[0].x;
1879  break;
1880  }
1881  case Camera::ORTHOGRAPHIC:
1882  {
1883  GLdouble hw, hh;
1884  getOrthoWidthHeight(hw, hh);
1885  points[0].x = points[1].x = scale * float(hw);
1886  points[0].y = points[1].y = scale * float(hh);
1887  break;
1888  }
1889  }
1890 
1891  const int farIndex = drawFarPlane?1:0;
1892 
1893  // Near and (optionally) far plane(s)
1894  glBegin(GL_QUADS);
1895  for (int i=farIndex; i>=0; --i)
1896  {
1897  glNormal3f(0.0, 0.0, (i==0)?1.0:-1.0);
1898  glVertex3f( points[i].x, points[i].y, -points[i].z);
1899  glVertex3f(-points[i].x, points[i].y, -points[i].z);
1900  glVertex3f(-points[i].x, -points[i].y, -points[i].z);
1901  glVertex3f( points[i].x, -points[i].y, -points[i].z);
1902  }
1903  glEnd();
1904 
1905  // Up arrow
1906  const float arrowHeight = 1.5f * points[0].y;
1907  const float baseHeight = 1.2f * points[0].y;
1908  const float arrowHalfWidth = 0.5f * points[0].x;
1909  const float baseHalfWidth = 0.3f * points[0].x;
1910 
1911  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1912  // Base
1913  glBegin(GL_QUADS);
1914  glVertex3f(-baseHalfWidth, points[0].y, -points[0].z);
1915  glVertex3f( baseHalfWidth, points[0].y, -points[0].z);
1916  glVertex3f( baseHalfWidth, baseHeight, -points[0].z);
1917  glVertex3f(-baseHalfWidth, baseHeight, -points[0].z);
1918  glEnd();
1919 
1920  // Arrow
1921  glBegin(GL_TRIANGLES);
1922  glVertex3f( 0.0f, arrowHeight, -points[0].z);
1923  glVertex3f(-arrowHalfWidth, baseHeight, -points[0].z);
1924  glVertex3f( arrowHalfWidth, baseHeight, -points[0].z);
1925  glEnd();
1926 
1927  // Frustum lines
1928  switch (type())
1929  {
1930  case Camera::PERSPECTIVE :
1931  glBegin(GL_LINES);
1932  glVertex3f(0.0f, 0.0f, 0.0f);
1933  glVertex3f( points[farIndex].x, points[farIndex].y, -points[farIndex].z);
1934  glVertex3f(0.0f, 0.0f, 0.0f);
1935  glVertex3f(-points[farIndex].x, points[farIndex].y, -points[farIndex].z);
1936  glVertex3f(0.0f, 0.0f, 0.0f);
1937  glVertex3f(-points[farIndex].x, -points[farIndex].y, -points[farIndex].z);
1938  glVertex3f(0.0f, 0.0f, 0.0f);
1939  glVertex3f( points[farIndex].x, -points[farIndex].y, -points[farIndex].z);
1940  glEnd();
1941  break;
1942  case Camera::ORTHOGRAPHIC :
1943  if (drawFarPlane)
1944  {
1945  glBegin(GL_LINES);
1946  glVertex3f( points[0].x, points[0].y, -points[0].z);
1947  glVertex3f( points[1].x, points[1].y, -points[1].z);
1948  glVertex3f(-points[0].x, points[0].y, -points[0].z);
1949  glVertex3f(-points[1].x, points[1].y, -points[1].z);
1950  glVertex3f(-points[0].x, -points[0].y, -points[0].z);
1951  glVertex3f(-points[1].x, -points[1].y, -points[1].z);
1952  glVertex3f( points[0].x, -points[0].y, -points[0].z);
1953  glVertex3f( points[1].x, -points[1].y, -points[1].z);
1954  glEnd();
1955  }
1956  }
1957 
1958  glPopMatrix();
1959 }
1960 
1961 
1985 void Camera::getFrustumPlanesCoefficients(GLdouble coef[6][4]) const
1986 {
1987  // Computed once and for all
1988  const Vec pos = position();
1989  const Vec viewDir = viewDirection();
1990  const Vec up = upVector();
1991  const Vec right = rightVector();
1992  const float posViewDir = pos * viewDir;
1993 
1994  static Vec normal[6];
1995  static GLdouble dist[6];
1996 
1997  switch (type())
1998  {
1999  case Camera::PERSPECTIVE :
2000  {
2001  const float hhfov = horizontalFieldOfView() / 2.0;
2002  const float chhfov = cos(hhfov);
2003  const float shhfov = sin(hhfov);
2004  normal[0] = - shhfov * viewDir;
2005  normal[1] = normal[0] + chhfov * right;
2006  normal[0] = normal[0] - chhfov * right;
2007 
2008  normal[2] = -viewDir;
2009  normal[3] = viewDir;
2010 
2011  const float hfov = fieldOfView() / 2.0;
2012  const float chfov = cos(hfov);
2013  const float shfov = sin(hfov);
2014  normal[4] = - shfov * viewDir;
2015  normal[5] = normal[4] - chfov * up;
2016  normal[4] = normal[4] + chfov * up;
2017 
2018  for (int i=0; i<2; ++i)
2019  dist[i] = pos * normal[i];
2020  for (int j=4; j<6; ++j)
2021  dist[j] = pos * normal[j];
2022 
2023  // Natural equations are:
2024  // dist[0,1,4,5] = pos * normal[0,1,4,5];
2025  // dist[2] = (pos + zNear() * viewDir) * normal[2];
2026  // dist[3] = (pos + zFar() * viewDir) * normal[3];
2027 
2028  // 2 times less computations using expanded/merged equations. Dir vectors are normalized.
2029  const float posRightCosHH = chhfov * pos * right;
2030  dist[0] = -shhfov * posViewDir;
2031  dist[1] = dist[0] + posRightCosHH;
2032  dist[0] = dist[0] - posRightCosHH;
2033  const float posUpCosH = chfov * pos * up;
2034  dist[4] = - shfov * posViewDir;
2035  dist[5] = dist[4] - posUpCosH;
2036  dist[4] = dist[4] + posUpCosH;
2037 
2038  break;
2039  }
2040  case Camera::ORTHOGRAPHIC :
2041  normal[0] = -right;
2042  normal[1] = right;
2043  normal[4] = up;
2044  normal[5] = -up;
2045 
2046  GLdouble hw, hh;
2047  getOrthoWidthHeight(hw, hh);
2048  dist[0] = (pos - hw * right) * normal[0];
2049  dist[1] = (pos + hw * right) * normal[1];
2050  dist[4] = (pos + hh * up) * normal[4];
2051  dist[5] = (pos - hh * up) * normal[5];
2052  break;
2053  }
2054 
2055  // Front and far planes are identical for both camera types.
2056  normal[2] = -viewDir;
2057  normal[3] = viewDir;
2058  dist[2] = -posViewDir - zNear();
2059  dist[3] = posViewDir + zFar();
2060 
2061  for (int i=0; i<6; ++i)
2062  {
2063  coef[i][0] = GLdouble(normal[i].x);
2064  coef[i][1] = GLdouble(normal[i].y);
2065  coef[i][2] = GLdouble(normal[i].z);
2066  coef[i][3] = dist[i];
2067  }
2068 }
float sceneRadius_
Definition: camera.h:546
void setScreenWidthAndHeight(int width, int height)
Definition: camera.cpp:164
A keyFrame Catmull-Rom Frame interpolator.
virtual QDomElement domElement(const QString &name, QDomDocument &document) const
Definition: camera.cpp:1667
float horizontalFieldOfView() const
Definition: camera.h:217
The ManipulatedCameraFrame class represents a ManipulatedFrame with Camera specific mouse bindings...
virtual void drawAllPaths()
Definition: camera.cpp:1630
Vec inverseTransformOf(const Vec &src) const
Definition: frame.cpp:847
float zClippingCoefficient() const
Definition: camera.h:267
virtual void loadProjectionMatrixStereo(bool leftBuffer=true) const
Definition: camera.cpp:505
void convertClickToLine(const QPoint &pixel, Vec &orig, Vec &dir) const
Definition: camera.cpp:1804
Camera & operator=(const Camera &camera)
Definition: camera.cpp:123
static float det(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22)
Definition: camera.cpp:1120
void interpolateToFitScene()
Definition: camera.cpp:855
void getProjectionMatrix(GLdouble m[16]) const
Definition: camera.cpp:590
void setOrientation(const Quaternion &q)
Definition: camera.cpp:1090
bool setRevolveAroundPointFromPixel(const QPoint &pixel)
Definition: camera.cpp:738
virtual ~Camera()
Definition: camera.cpp:85
void addKeyFrame(const Frame &frame)
void lookAt(const Vec &target)
Definition: camera.cpp:950
virtual void loadProjectionMatrix(bool reset=true) const
Definition: camera.cpp:432
float focusDistance() const
Definition: camera.h:511
void computeModelViewMatrix() const
Definition: camera.cpp:373
float distanceToSceneCenter() const
Definition: camera.cpp:280
void setSceneCenter(const Vec &center)
Definition: camera.cpp:694
void setPhysicalScreenWidth(float width)
Definition: camera.h:522
virtual void addKeyFrameToPath(int i)
Definition: camera.cpp:1562
Vec projectedCoordinatesOf(const Vec &src, const Frame *frame=NULL) const
Definition: camera.cpp:1441
void setSceneBoundingBox(const Vec &min, const Vec &max)
Definition: camera.cpp:684
void setPositionWithConstraint(Vec &position)
Definition: frame.cpp:612
GLdouble projectionMatrix_[16]
Definition: camera.h:552
static void drawCamera(float scale=1.0, float aspectRatio=1.33, float fieldOfView=M_PI/4.0)
Definition: camera.cpp:1831
virtual void loadModelViewMatrix(bool reset=true) const
Definition: camera.cpp:469
QMap< int, KeyFrameInterpolator * > kfi_
Definition: camera.h:560
void setRevolveAroundPoint(const Vec &rap)
Definition: camera.cpp:715
virtual void loadModelViewMatrixStereo(bool leftBuffer=true) const
Definition: camera.cpp:560
virtual void deletePath(int i)
Definition: camera.cpp:1614
Vec rotate(const Vec &v) const
Definition: quaternion.cpp:76
void showEntireScene()
Definition: camera.cpp:929
#define M_PI
void setZClippingCoefficient(float coef)
Definition: camera.h:309
void getViewport(GLint viewport[4]) const
Definition: camera.cpp:1359
void setType(Type type)
Definition: camera.cpp:246
void centerScene()
Definition: camera.cpp:939
void getModelViewMatrix(GLdouble m[16]) const
Definition: camera.cpp:612
int screenWidth() const
Definition: camera.h:228
Vec pointUnderPixel(const QPoint &pixel, bool &found) const
Definition: camera.cpp:913
void fitSphere(const Vec &center, float radius)
Definition: camera.cpp:962
virtual void draw(bool drawFarPlane=true, float scale=1.0) const
Definition: camera.cpp:1857
bool setSceneCenterFromPixel(const QPoint &pixel)
Definition: camera.cpp:705
void getFrustumPlanesCoefficients(GLdouble coef[6][4]) const
Definition: camera.cpp:1985
virtual void initFromDOMElement(const QDomElement &element)
Definition: camera.cpp:1729
void setFromRotationMatrix(const float m[3][3])
Definition: quaternion.cpp:151
void setReferenceFrame(const Frame *const refFrame)
Definition: frame.cpp:656
void computeProjectionMatrix() const
Definition: camera.cpp:327
float IODistance() const
Definition: camera.h:484
Type type() const
Definition: camera.h:196
ManipulatedCameraFrame * frame() const
Definition: camera.h:372
void setFOVToFitScene()
Definition: camera.cpp:803
void fitScreenRegion(const QRect &rectangle)
Definition: camera.cpp:1000
void rotate(Quaternion &q)
Definition: frame.cpp:376
void setFocusDistance(float distance)
Definition: camera.h:525
The Vec class represents 3D positions and 3D vectors.
Definition: vec.h:69
double z
Definition: vec.h:85
void setViewDirection(const Vec &direction)
Definition: camera.cpp:1101
void setKeyFrameInterpolator(int i, KeyFrameInterpolator *const kfi)
Definition: camera.cpp:1542
float sceneRadius() const
Definition: camera.h:325
virtual void getOrthoWidthHeight(GLdouble &halfWidth, GLdouble &halfHeight) const
Definition: camera.cpp:301
ManipulatedCameraFrame * frame_
Definition: camera.h:540
void setZNearCoefficient(float coef)
Definition: camera.h:307
void getWorldCoordinatesOf(const float src[3], float res[3]) const
Definition: camera.cpp:1347
float physicalScreenWidth() const
Definition: camera.h:499
void fitBoundingBox(const Vec &min, const Vec &max)
Definition: camera.cpp:986
KeyFrameInterpolator * interpolationKfi_
Definition: camera.h:561
void projectOnLine(const Vec &origin, const Vec &direction)
Definition: frame.cpp:1126
void setFromProjectionMatrix(const float matrix[12])
Definition: camera.cpp:1189
void getModelViewProjectionMatrix(GLdouble m[16]) const
Definition: camera.cpp:624
Vec revolveAroundPoint() const
Definition: camera.h:361
double normalize()
Definition: vec.h:344
void interpolateToZoomOnPixel(const QPoint &pixel)
Definition: camera.cpp:817
void setRevolveAroundPoint(const Vec &revolveAroundPoint)
Vec upVector() const
Definition: camera.h:123
float zNearCoefficient() const
Definition: camera.h:248
int screenHeight() const
Definition: camera.h:233
KeyFrameInterpolator * keyFrameInterpolator(int i) const
Definition: camera.cpp:1516
double squaredNorm() const
Definition: vec.h:336
Vec coordinatesOf(const Vec &src) const
Definition: frame.cpp:693
Quaternion orientation() const
Definition: camera.h:151
#define qMax(a, b)
Definition: config.h:112
A perspective or orthographic camera.
Definition: camera.h:81
void getProjectedCoordinatesOf(const float src[3], float res[3], const Frame *frame=NULL) const
Definition: camera.cpp:1496
void setFrame(ManipulatedCameraFrame *const mcf)
Definition: camera.cpp:269
virtual void initFromDOMElement(const QDomElement &element)
virtual void playPath(int i)
Definition: camera.cpp:1578
The Quaternion class represents 3D rotations and orientations.
Definition: quaternion.h:66
void setFromRotatedBasis(const Vec &X, const Vec &Y, const Vec &Z)
Definition: quaternion.cpp:182
Quaternion orientation() const
Definition: frame.cpp:537
void setOrientationWithConstraint(Quaternion &orientation)
Definition: frame.cpp:622
void getUnprojectedCoordinatesOf(const float src[3], float res[3], const Frame *frame=NULL) const
Definition: camera.cpp:1504
void setPosition(const Vec &pos)
Definition: camera.h:158
void setPosition(const Vec &position)
Definition: frame.cpp:443
virtual float zNear() const
Definition: camera.cpp:208
float orthoCoef_
Definition: camera.h:549
virtual void resetPath(int i)
Definition: camera.cpp:1593
void setSceneRadius(float radius)
Definition: camera.cpp:667
virtual void initFromDOMElement(const QDomElement &element)
Vec rightVector() const
Definition: camera.h:142
The Frame class represents a coordinate system, defined by a position and an orientation.
Definition: frame.h:126
void setFromModelViewMatrix(const GLdouble *const modelViewMatrix)
Definition: camera.cpp:1151
static unsigned int ind(unsigned int i, unsigned int j)
Definition: camera.cpp:1128
static int intFromDom(const QDomElement &e, const QString &attribute, int defValue)
Definition: domUtils.h:104
float fieldOfView() const
Definition: camera.h:208
void setOrientation(const Quaternion &orientation)
Definition: frame.cpp:505
Vec worldCoordinatesOf(const Vec &src) const
Definition: camera.h:440
void setUpVector(const Vec &up, bool noMove=true)
Definition: camera.cpp:1056
GLdouble modelViewMatrix_[16]
Definition: camera.h:551
void setIODistance(float distance)
Definition: camera.h:514
virtual float zFar() const
Definition: camera.cpp:232
void getCameraCoordinatesOf(const float src[3], float res[3]) const
Definition: camera.cpp:1339
Vec inverseCoordinatesOf(const Vec &src) const
Definition: frame.cpp:706
double y
Definition: vec.h:85
Vec cameraCoordinatesOf(const Vec &src) const
Definition: camera.h:435
Vec unprojectedCoordinatesOf(const Vec &src, const Frame *frame=NULL) const
Definition: camera.cpp:1483
float aspectRatio() const
Definition: camera.h:223
Vec viewDirection() const
Definition: camera.h:134
Vec position() const
Definition: camera.h:114
void interpolateTo(const Frame &fr, float duration)
Definition: camera.cpp:884
static float floatFromDom(const QDomElement &e, const QString &attribute, float defValue)
Definition: domUtils.h:56
Vec sceneCenter() const
Definition: camera.h:338
void setFieldOfView(float fov)
Definition: camera.h:280
float pixelGLRatio(const Vec &position) const
Definition: camera.cpp:761
double x
Definition: vec.h:85


octovis
Author(s): Kai M. Wurm , Armin Hornung
autogenerated on Mon Jun 10 2019 14:00:24