25 #include "qglviewer.h"
28 using namespace qglviewer;
38 : fieldOfView_(M_PI/4.0f)
73 for (
unsigned short j=0; j<16; ++j)
75 modelViewMatrix_[j] = ((j%5 == 0) ? 1.0 : 0.0);
77 projectionMatrix_[j] = 0.0;
89 delete interpolationKfi_;
102 for (
unsigned short j=0; j<16; ++j)
104 modelViewMatrix_[j] = ((j%5 == 0) ? 1.0 : 0.0);
106 projectionMatrix_[j] = 0.0;
140 orthoCoef_ = camera.orthoCoef_;
169 screenWidth_ = width > 0 ? width : 1;
170 screenHeight_ = height > 0 ? height : 1;
219 case Camera::PERSPECTIVE : z = zMin;
break;
220 case Camera::ORTHOGRAPHIC : z = 0.0;
break;
253 if ( (type == Camera::ORTHOGRAPHIC) && (type_ == Camera::PERSPECTIVE) )
331 const float ZNear =
zNear();
332 const float ZFar =
zFar();
336 case Camera::PERSPECTIVE:
341 projectionMatrix_[5] = f;
342 projectionMatrix_[10] = (ZNear + ZFar) / (ZNear - ZFar);
343 projectionMatrix_[11] = -1.0;
344 projectionMatrix_[14] = 2.0 * ZNear * ZFar / (ZNear - ZFar);
345 projectionMatrix_[15] = 0.0;
349 case Camera::ORTHOGRAPHIC:
353 projectionMatrix_[0] = 1.0/w;
354 projectionMatrix_[5] = 1.0/h;
355 projectionMatrix_[10] = -2.0/(ZFar - ZNear);
356 projectionMatrix_[11] = 0.0;
357 projectionMatrix_[14] = -(ZFar + ZNear)/(ZFar - ZNear);
358 projectionMatrix_[15] = 1.0;
379 const double q00 = 2.0l * q[0] * q[0];
380 const double q11 = 2.0l * q[1] * q[1];
381 const double q22 = 2.0l * q[2] * q[2];
383 const double q01 = 2.0l * q[0] * q[1];
384 const double q02 = 2.0l * q[0] * q[2];
385 const double q03 = 2.0l * q[0] * q[3];
387 const double q12 = 2.0l * q[1] * q[2];
388 const double q13 = 2.0l * q[1] * q[3];
390 const double q23 = 2.0l * q[2] * q[3];
392 modelViewMatrix_[0] = 1.0l - q11 - q22;
393 modelViewMatrix_[1] = q01 - q23;
394 modelViewMatrix_[2] = q02 + q13;
395 modelViewMatrix_[3] = 0.0l;
397 modelViewMatrix_[4] = q01 + q23;
398 modelViewMatrix_[5] = 1.0l - q22 - q00;
399 modelViewMatrix_[6] = q12 - q03;
400 modelViewMatrix_[7] = 0.0l;
402 modelViewMatrix_[8] = q02 - q13;
403 modelViewMatrix_[9] = q12 + q03;
404 modelViewMatrix_[10] = 1.0l - q11 - q00;
405 modelViewMatrix_[11] = 0.0l;
409 modelViewMatrix_[12] = -t.x;
410 modelViewMatrix_[13] = -t.y;
411 modelViewMatrix_[14] = -t.z;
412 modelViewMatrix_[15] = 1.0l;
437 glMatrixMode(GL_PROJECTION);
444 glMultMatrixd(projectionMatrix_);
474 glMatrixMode(GL_MODELVIEW);
477 glLoadMatrixd(modelViewMatrix_);
479 glMultMatrixd(modelViewMatrix_);
509 float left, right, bottom, top;
510 float screenHalfWidth, halfWidth, side, shift, delta;
512 glMatrixMode(GL_PROJECTION);
517 case Camera::PERSPECTIVE:
529 side = leftBuffer ? -1.0 : 1.0;
531 left = -halfWidth + side * delta;
532 right = halfWidth + side * delta;
535 glFrustum(left, right, bottom, top,
zNear(),
zFar() );
538 case Camera::ORTHOGRAPHIC:
539 qWarning(
"Camera::setProjectionMatrixStereo: Stereo not available with Ortho mode");
565 glMatrixMode(GL_MODELVIEW);
572 modelViewMatrix_[12] -= shift;
574 modelViewMatrix_[12] += shift;
575 glLoadMatrixd(modelViewMatrix_);
596 for (
unsigned short i=0; i<16; ++i)
597 m[i] = projectionMatrix_[i];
619 for (
unsigned short i=0; i<16; ++i)
620 m[i] = modelViewMatrix_[i];
633 for (
unsigned short i=0; i<4; ++i)
635 for (
unsigned short j=0; j<4; ++j)
638 for (
unsigned short k=0; k<4; ++k)
639 sum += proj[i+4*k]*mv[k+4*j];
648 qWarning(
"Warning : Camera::getProjectionMatrix requires a GLdouble matrix array");
649 static GLdouble mat[16];
651 for (
int i=0; i<16; ++i)
652 m[i] =
float(mat[i]);
657 qWarning(
"Warning : Camera::getModelViewMatrix requires a GLdouble matrix array");
658 static GLdouble mat[16];
660 for (
int i=0; i<16; ++i)
661 m[i] =
float(mat[i]);
673 qWarning(
"Scene radius must be positive - Ignoring value");
677 sceneRadius_ = radius;
698 sceneCenter_ = center;
727 if ((prevDist > 1E-9) && (newDist > 1E-9))
728 orthoCoef_ *= prevDist / newDist;
767 case Camera::PERSPECTIVE :
769 case Camera::ORTHOGRAPHIC :
821 const float coef = 0.1f;
919 glReadPixels(pixel.x(),
screenHeight()-1-pixel.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
921 Vec point(pixel.x(), pixel.y(), depth);
966 float distance = 0.0f;
969 case Camera::PERSPECTIVE :
971 const float yview = radius / sin(
fieldOfView()/2.0);
973 distance = qMax(xview,yview);
976 case Camera::ORTHOGRAPHIC :
990 float diameter = qMax(fabs(max[1]-min[1]), fabs(max[0]-min[0]));
991 diameter = qMax(fabsf(max[2]-min[2]), diameter);
1006 const QPoint center = rectangle.center();
1010 Vec newCenter = orig + distToPlane / (dir*vd) * dir;
1013 const Vec pointX = orig + distToPlane / (dir*vd) * dir;
1016 const Vec pointY = orig + distToPlane / (dir*vd) * dir;
1018 float distance = 0.0f;
1021 case Camera::PERSPECTIVE :
1024 const float distY = (pointY-newCenter).norm() / sin(
fieldOfView()/2.0);
1025 distance = qMax(distX, distY);
1028 case Camera::ORTHOGRAPHIC :
1032 const float distX = (pointX-newCenter).norm() / orthoCoef_ / ((
aspectRatio() < 1.0) ? 1.0 :
aspectRatio());
1033 const float distY = (pointY-newCenter).norm() / orthoCoef_ / ((
aspectRatio() < 1.0) ? 1.0/
aspectRatio() : 1.0);
1034 distance = dist + qMax(distX, distY);
1039 Vec newPos(newCenter - distance * vd);
1068 frame()->updateFlyUpVector();
1084 Vec axis(0.0, 1.0, 0.0);
1086 axis =
Vec(-cos(theta), 0., sin(theta));
1095 frame()->updateFlyUpVector();
1122 static float det(
float m00,
float m01,
float m02,
1123 float m10,
float m11,
float m12,
1124 float m20,
float m21,
float m22)
1126 return m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m10*m01*m22 - m00*m21*m12;
1130 static inline unsigned int ind(
unsigned int i,
unsigned int j)
1156 double upperLeft[3][3];
1157 for (
int i=0; i<3; ++i)
1158 for (
int j=0; j<3; ++j)
1159 upperLeft[i][j] = modelViewMatrix[i*4+j];
1163 q.setFromRotationMatrix(upperLeft);
1195 Vec line_0(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,2)]);
1196 Vec line_1(matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,2)]);
1197 Vec line_2(matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,2)]);
1212 const Vec cam_pos =
Vec(det(matrix[ind(0,1)],matrix[ind(0,2)],matrix[ind(0,3)],
1213 matrix[ind(1,1)],matrix[ind(1,2)],matrix[ind(1,3)],
1214 matrix[ind(2,1)],matrix[ind(2,2)],matrix[ind(2,3)]),
1216 -det(matrix[ind(0,0)],matrix[ind(0,2)],matrix[ind(0,3)],
1217 matrix[ind(1,0)],matrix[ind(1,2)],matrix[ind(1,3)],
1218 matrix[ind(2,0)],matrix[ind(2,2)],matrix[ind(2,3)]),
1220 det(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,3)],
1221 matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,3)],
1222 matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,3)])) /
1224 (-det(matrix[ind(0,0)],matrix[ind(0,1)],matrix[ind(0,2)],
1225 matrix[ind(1,0)],matrix[ind(1,1)],matrix[ind(1,2)],
1226 matrix[ind(2,0)],matrix[ind(2,1)],matrix[ind(2,2)]));
1231 Vec column_2 = -line_2;
1234 Vec column_0 = ((column_2^line_0)^column_2);
1239 Vec column_1 = -((column_2^line_1)^column_2);
1243 rot[0][0] = column_0[0];
1244 rot[1][0] = column_0[1];
1245 rot[2][0] = column_0[2];
1247 rot[0][1] = column_1[0];
1248 rot[1][1] = column_1[1];
1249 rot[2][1] = column_1[2];
1251 rot[0][2] = column_2[0];
1252 rot[1][2] = column_2[1];
1253 rot[2][2] = column_2[2];
1263 Vec dummy = line_1^column_0;
1265 float fov = acos(column_2*dummy) * 2.0;
1269 q.setFromRotationMatrix(rot);
1344 for (
int i=0; i<3; ++i)
1352 for (
int i=0; i<3; ++i)
1446 static GLint viewport[4];
1452 gluProject(tmp.x,tmp.y,tmp.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z);
1455 gluProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z);
1488 static GLint viewport[4];
1490 gluUnProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z);
1501 for (
int i=0; i<3; ++i)
1509 for (
int i=0; i<3; ++i)
1520 if (kfi_.contains(i))
1566 if (!kfi_.contains(i))
1569 kfi_[i]->addKeyFrame(*(
frame()));
1582 if (kfi_.contains(i)) {
1583 if (kfi_[i]->interpolationIsStarted())
1584 kfi_[i]->stopInterpolation();
1586 kfi_[i]->startInterpolation();
1597 if (kfi_.contains(i)) {
1598 if ((kfi_[i]->interpolationIsStarted()))
1599 kfi_[i]->stopInterpolation();
1602 kfi_[i]->resetInterpolation();
1603 kfi_[i]->interpolateAtTime(kfi_[i]->interpolationTime());
1618 if (kfi_.contains(i))
1620 kfi_[i]->stopInterpolation();
1634 for (QMap<int, KeyFrameInterpolator*>::ConstIterator it = kfi_.begin(), end=kfi_.end(); it != end; ++it)
1635 #
if QT_VERSION >= 0x040000
1671 QDomElement de = document.createElement(name);
1672 QDomElement paramNode = document.createElement(
"Parameters");
1673 paramNode.setAttribute(
"fieldOfView", QString::number(
fieldOfView()));
1674 paramNode.setAttribute(
"zNearCoefficient", QString::number(
zNearCoefficient()));
1676 paramNode.setAttribute(
"orthoCoef", QString::number(orthoCoef_));
1677 paramNode.setAttribute(
"sceneRadius", QString::number(
sceneRadius()));
1682 case Camera::PERSPECTIVE : paramNode.setAttribute(
"Type",
"PERSPECTIVE");
break;
1683 case Camera::ORTHOGRAPHIC : paramNode.setAttribute(
"Type",
"ORTHOGRAPHIC");
break;
1685 de.appendChild(paramNode);
1687 QDomElement stereoNode = document.createElement(
"Stereo");
1688 stereoNode.setAttribute(
"IODist", QString::number(
IODistance()));
1690 stereoNode.setAttribute(
"focusDistance", QString::number(
focusDistance()));
1692 de.appendChild(stereoNode);
1694 de.appendChild(
frame()->
domElement(
"ManipulatedCameraFrame", document));
1697 for (QMap<int, KeyFrameInterpolator*>::ConstIterator it = kfi_.begin(), end=kfi_.end(); it != end; ++it)
1699 #if QT_VERSION >= 0x040000
1700 QDomElement kfNode = (it.value())->
domElement(
"KeyFrameInterpolator", document);
1702 QDomElement kfNode = (it.data())->
domElement(
"KeyFrameInterpolator", document);
1704 kfNode.setAttribute(
"index", QString::number(it.key()));
1705 de.appendChild(kfNode);
1734 QDomElement child=element.firstChild().toElement();
1736 #if QT_VERSION >= 0x040000
1737 QMutableMapIterator<int, KeyFrameInterpolator*> it(kfi_);
1738 while (it.hasNext()) {
1741 for (QMap<int, KeyFrameInterpolator*>::Iterator it = kfi_.begin(), end=kfi_.end(); it != end; ++it) {
1746 while (!child.isNull())
1748 if (child.tagName() ==
"Parameters")
1751 setFieldOfView(DomUtils::floatFromDom(child,
"fieldOfView", M_PI/4.0f));
1754 orthoCoef_ = DomUtils::floatFromDom(child,
"orthoCoef", tan(
fieldOfView()/2.0));
1758 QString
type = child.attribute(
"Type",
"PERSPECTIVE");
1759 if (type ==
"PERSPECTIVE")
setType(Camera::PERSPECTIVE);
1760 if (type ==
"ORTHOGRAPHIC")
setType(Camera::ORTHOGRAPHIC);
1762 QDomElement child2=child.firstChild().toElement();
1763 while (!child2.isNull())
1767 if (child2.tagName() ==
"SceneCenter")
1770 child2 = child2.nextSibling().toElement();
1774 if (child.tagName() ==
"ManipulatedCameraFrame")
1777 if (child.tagName() ==
"Stereo")
1779 setIODistance(DomUtils::floatFromDom(child,
"IODist", 0.062f));
1785 if (child.tagName() ==
"KeyFrameInterpolator")
1787 int index = DomUtils::intFromDom(child,
"index", 0);
1793 child = child.nextSibling().toElement();
1812 case Camera::PERSPECTIVE:
1821 case Camera::ORTHOGRAPHIC:
1837 qWarning(
"drawCamera is deprecated. Use Camera::draw() instead.");
1864 glMultMatrixd(
frame()->worldMatrix());
1869 points[0].z = scale *
zNear();
1870 points[1].z = scale *
zFar();
1874 case Camera::PERSPECTIVE:
1876 points[0].y = points[0].z * tan(
fieldOfView()/2.0);
1879 const float ratio = points[1].z / points[0].z;
1881 points[1].y = ratio * points[0].y;
1882 points[1].x = ratio * points[0].x;
1885 case Camera::ORTHOGRAPHIC:
1889 points[0].x = points[1].x = scale * float(hw);
1890 points[0].y = points[1].y = scale * float(hh);
1895 const int farIndex = drawFarPlane?1:0;
1899 for (
int i=farIndex; i>=0; --i)
1901 glNormal3f(0.0, 0.0, (i==0)?1.0:-1.0);
1902 glVertex3f( points[i].x, points[i].y, -points[i].z);
1903 glVertex3f(-points[i].x, points[i].y, -points[i].z);
1904 glVertex3f(-points[i].x, -points[i].y, -points[i].z);
1905 glVertex3f( points[i].x, -points[i].y, -points[i].z);
1910 const float arrowHeight = 1.5f * points[0].y;
1911 const float baseHeight = 1.2f * points[0].y;
1912 const float arrowHalfWidth = 0.5f * points[0].x;
1913 const float baseHalfWidth = 0.3f * points[0].x;
1915 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1918 glVertex3f(-baseHalfWidth, points[0].y, -points[0].z);
1919 glVertex3f( baseHalfWidth, points[0].y, -points[0].z);
1920 glVertex3f( baseHalfWidth, baseHeight, -points[0].z);
1921 glVertex3f(-baseHalfWidth, baseHeight, -points[0].z);
1925 glBegin(GL_TRIANGLES);
1926 glVertex3f( 0.0f, arrowHeight, -points[0].z);
1927 glVertex3f(-arrowHalfWidth, baseHeight, -points[0].z);
1928 glVertex3f( arrowHalfWidth, baseHeight, -points[0].z);
1934 case Camera::PERSPECTIVE :
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 glVertex3f(0.0f, 0.0f, 0.0f);
1941 glVertex3f(-points[farIndex].x, -points[farIndex].y, -points[farIndex].z);
1942 glVertex3f(0.0f, 0.0f, 0.0f);
1943 glVertex3f( points[farIndex].x, -points[farIndex].y, -points[farIndex].z);
1946 case Camera::ORTHOGRAPHIC :
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 glVertex3f(-points[0].x, -points[0].y, -points[0].z);
1955 glVertex3f(-points[1].x, -points[1].y, -points[1].z);
1956 glVertex3f( points[0].x, -points[0].y, -points[0].z);
1957 glVertex3f( points[1].x, -points[1].y, -points[1].z);
1996 const float posViewDir = pos * viewDir;
1998 static Vec normal[6];
1999 static GLdouble dist[6];
2003 case Camera::PERSPECTIVE :
2006 const float chhfov = cos(hhfov);
2007 const float shhfov = sin(hhfov);
2008 normal[0] = - shhfov * viewDir;
2009 normal[1] = normal[0] + chhfov * right;
2010 normal[0] = normal[0] - chhfov * right;
2012 normal[2] = -viewDir;
2013 normal[3] = viewDir;
2016 const float chfov = cos(hfov);
2017 const float shfov = sin(hfov);
2018 normal[4] = - shfov * viewDir;
2019 normal[5] = normal[4] - chfov * up;
2020 normal[4] = normal[4] + chfov * up;
2022 for (
int i=0; i<2; ++i)
2023 dist[i] = pos * normal[i];
2024 for (
int j=4; j<6; ++j)
2025 dist[j] = pos * normal[j];
2033 const float posRightCosHH = chhfov * pos * right;
2034 dist[0] = -shhfov * posViewDir;
2035 dist[1] = dist[0] + posRightCosHH;
2036 dist[0] = dist[0] - posRightCosHH;
2037 const float posUpCosH = chfov * pos * up;
2038 dist[4] = - shfov * posViewDir;
2039 dist[5] = dist[4] - posUpCosH;
2040 dist[4] = dist[4] + posUpCosH;
2044 case Camera::ORTHOGRAPHIC :
2052 dist[0] = (pos - hw * right) * normal[0];
2053 dist[1] = (pos + hw * right) * normal[1];
2054 dist[4] = (pos + hh * up) * normal[4];
2055 dist[5] = (pos - hh * up) * normal[5];
2060 normal[2] = -viewDir;
2061 normal[3] = viewDir;
2062 dist[2] = -posViewDir -
zNear();
2063 dist[3] = posViewDir +
zFar();
2065 for (
int i=0; i<6; ++i)
2067 coef[i][0] = GLdouble(normal[i].x);
2068 coef[i][1] = GLdouble(normal[i].y);
2069 coef[i][2] = GLdouble(normal[i].z);
2070 coef[i][3] = dist[i];