Commit 19f16973 authored by Frédéric Larue's avatar Frédéric Larue

Orthographic projection now managed by GLViewer.

parent fe7b7e83
......@@ -173,6 +173,7 @@ void GLViewer::init( DisplayDoF dof )
}
setViewRotationMatrix( rot );
m_View.isOrthographic = false;
m_View.fovY = 0.0f;
setFovY( 65.0f );
......@@ -495,8 +496,6 @@ void GLViewer::frameAll()
}
// All displayables are arranged along a grid layout. All grid row have the same height (displayables are scaled so as to fit it)
// but each column has a different width, that corresponds to the width of its largest element. Displayables are horizontaly centered
// in their respective grid cells.
......@@ -750,6 +749,23 @@ void GLViewer::mouseMotionNavigationEvent( float dx, float dy, QMouseEvent *evt
}
void GLViewer::pixelRay( int px, int py, QVector3D &rayOrig, QVector3D &rayDir ) const
{
if( isProjectionOrthographic() )
{
QVector4D clipCoord( 2.0f*px/width() - 1.0f, 2.0f*py/height() - 1.0f, -1.0f, 1.0f );
rayOrig = viewMatrixInverse().map( projectionMatrixInverse().map( clipCoord ) ).toVector3D();
rayDir = frontAxis();
}
else
{
QVector4D clipCoord( 2.0f*px/width() - 1.0f, 2.0f*py/height() - 1.0f, 0.0f, 1.0f );
rayOrig = viewpointLocation();
rayDir = viewRotationMatrixInverse().map( projectionMatrixInverse().map( clipCoord ) ).toVector3D();
}
}
QMatrix4x4 GLViewer::viewportMatrix( bool flipY ) const
{
const float xOff = 0.5f*width(), yOff = 0.5f*height();
......@@ -911,11 +927,23 @@ void GLViewer::paintGL()
if( m_MustUpdateProjectionMatrix )
{
m_ProjectionMatrix.fill( 0.0f );
m_ProjectionMatrix(0,0) = focal() * height() / width();
m_ProjectionMatrix(1,1) = focal();
m_ProjectionMatrix(2,2) = (zNear() + zFar()) / (zNear() - zFar());
m_ProjectionMatrix(2,3) = 2.0f*zNear()*zFar() / (zNear() - zFar());
m_ProjectionMatrix(3,2) = -1.0f;
if( isProjectionOrthographic() )
{
m_ProjectionMatrix(0,0) = 2.0f * height() / (distToFocusPoint() * width());
m_ProjectionMatrix(1,1) = 2.0f / distToFocusPoint();
m_ProjectionMatrix(2,2) = -2.0f / (zFar() - zNear());
m_ProjectionMatrix(2,3) = -(zFar() + zNear()) / (zFar() - zNear());
m_ProjectionMatrix(3,3) = 1.0f;
}
else
{
m_ProjectionMatrix(0,0) = focal() * height() / width();
m_ProjectionMatrix(1,1) = focal();
m_ProjectionMatrix(2,2) = (zNear() + zFar()) / (zNear() - zFar());
m_ProjectionMatrix(2,3) = 2.0f*zNear()*zFar() / (zNear() - zFar());
m_ProjectionMatrix(3,2) = -1.0f;
}
m_ProjectionMatrixInverse = m_ProjectionMatrix.inverted();
......@@ -943,8 +971,6 @@ void GLViewer::paintGL()
m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix;
m_ViewProjectionMatrixInverse = m_ViewMatrixInverse * m_ProjectionMatrixInverse;
m_PixelToRayMatrix = viewRotationMatrixInverse() * projectionMatrixInverse();
m_Frustum.UpdateFrustumPlanes( m_ViewMatrix, m_ProjectionMatrix );
}
......@@ -1532,7 +1558,7 @@ bool GLViewer::imageOfCurrentDisplay( const GenericUIData *m, QImage &renderResu
glPushMatrix();
glLoadIdentity();
glOrtho( dBox.Min().x(), dBox.Max().x(), dBox.Max().y(), dBox.Min().y(), -1.0f, 1.0f );
glMultMatrixf( m_ViewMatrixInverse.data() );
glMultMatrixf( viewMatrixInverse().data() );
glMultMatrixf( modelMatrixInverse(d).data() );
QMatrix4x4 projBackup = m_ProjectionMatrix;
......@@ -1540,7 +1566,7 @@ bool GLViewer::imageOfCurrentDisplay( const GenericUIData *m, QImage &renderResu
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadMatrixf( m_ViewMatrix.data() );
glLoadMatrixf( viewMatrix().data() );
glMultMatrixf( modelMatrix(d).data() );
d->onDisplay( *m->GetDisplayOptions() );
......@@ -1959,6 +1985,12 @@ void GLViewer::keyPressEvent( QKeyEvent *evt )
update();
break;
}
case Qt::Key_5:
{
setOrthographic( !isProjectionOrthographic() );
update();
break;
}
case Qt::Key_1:
{
QMatrix4x4 rot;
......@@ -2126,10 +2158,21 @@ QMatrix4x4 GLViewer::reframedProjection( float viewportX, float viewportY, float
{
QMatrix4x4 projMat = projectionMatrix();
double frustumL = zNear() * (projMat(0,2)-1.0f) / projMat(0,0);
double frustumR = zNear() * (projMat(0,2)+1.0f) / projMat(0,0);
double frustumB = zNear() * (projMat(1,2)-1.0f) / projMat(1,1);
double frustumT = zNear() * (projMat(1,2)+1.0f) / projMat(1,1);
double frustumL, frustumR, frustumB, frustumT;
if( isProjectionOrthographic() )
{
frustumL = -(projMat(0,3) + 1.0f) / projMat(0,0);
frustumR = -(projMat(0,3) - 1.0f) / projMat(0,0);
frustumB = -(projMat(1,3) + 1.0f) / projMat(1,1);
frustumT = -(projMat(1,3) - 1.0f) / projMat(1,1);
}
else
{
frustumL = zNear() * (projMat(0,2)-1.0f) / projMat(0,0);
frustumR = zNear() * (projMat(0,2)+1.0f) / projMat(0,0);
frustumB = zNear() * (projMat(1,2)-1.0f) / projMat(1,1);
frustumT = zNear() * (projMat(1,2)+1.0f) / projMat(1,1);
}
double newFrustumL = frustumL + (frustumR-frustumL) * (viewportX+0.5f)/width();
double newFrustumR = frustumL + (frustumR-frustumL) * (viewportX+viewportW+0.5f)/width();
......@@ -2137,13 +2180,26 @@ QMatrix4x4 GLViewer::reframedProjection( float viewportX, float viewportY, float
double newFrustumT = frustumB + (frustumT-frustumB) * (viewportY+viewportH+0.5f)/height();
projMat.fill( 0.0f );
projMat(0,0) = 2.0f * zNear() / (newFrustumR - newFrustumL);
projMat(0,2) = (newFrustumR + newFrustumL) / (newFrustumR - newFrustumL);
projMat(1,1) = 2.0f * zNear() / (newFrustumT - newFrustumB);
projMat(1,2) = (newFrustumT + newFrustumB) / (newFrustumT - newFrustumB);
projMat(2,2) = (zNear() + zFar()) / (zNear() - zFar());
projMat(2,3) = 2.0f * zNear() * zFar() / (zNear() - zFar());
projMat(3,2) = -1.0f;
if( isProjectionOrthographic() )
{
projMat(0,0) = 2.0f / (newFrustumR - newFrustumL);
projMat(0,3) = -(newFrustumR + newFrustumL) / (newFrustumR - newFrustumL);
projMat(1,1) = 2.0f / (newFrustumT - newFrustumB);
projMat(1,3) = -(newFrustumT + newFrustumB) / (newFrustumT - newFrustumB);
projMat(2,2) = -2.0f / (zFar() - zNear());
projMat(2,3) = -(zFar() + zNear()) / (zFar() - zNear());
projMat(3,3) = 1.0f;
}
else
{
projMat(0,0) = 2.0f * zNear() / (newFrustumR - newFrustumL);
projMat(0,2) = (newFrustumR + newFrustumL) / (newFrustumR - newFrustumL);
projMat(1,1) = 2.0f * zNear() / (newFrustumT - newFrustumB);
projMat(1,2) = (newFrustumT + newFrustumB) / (newFrustumT - newFrustumB);
projMat(2,2) = (zNear() + zFar()) / (zNear() - zFar());
projMat(2,3) = 2.0f * zNear() * zFar() / (zNear() - zFar());
projMat(3,2) = -1.0f;
}
return projMat;
}
......@@ -2203,8 +2259,9 @@ bool GLViewer::getPickedPoint( const float x,
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
QVector3D rayOrig = viewpointLocation();
QVector3D rayDir = pixelRay( x, y ).normalized();
QVector3D rayOrig, rayDir;
pixelRay( x, y, rayOrig, rayDir );
rayDir.normalized();
DisplayableInfo *closestBoxObject = NULL;
float closestBoxDist = std::numeric_limits<float>::max();
......@@ -2323,7 +2380,7 @@ bool GLViewer::getPickedPoint( const float x,
void GLViewer::centerView()
{
setFocusPoint( QVector3D(0.0,0.0,0.0) );
setFocusPoint( QVector3D(0.0f, 0.0f, 0.0f) );
}
......@@ -2443,6 +2500,20 @@ void GLViewer::setFovY( float fovY )
}
void GLViewer::setOrthographic( bool ortho )
{
if( ortho != m_View.isOrthographic )
{
m_View.isOrthographic = ortho;
m_MustUpdateFocal = true;
m_MustUpdateProjectionMatrix = true;
update();
}
}
void GLViewer::setSelectionAllowed( bool allowed )
{
m_IsSelectionAllowed = allowed;
......
......@@ -46,6 +46,7 @@ public:
QMatrix4x4 viewRotationMatrix;
QMatrix4x4 lightRotationMatrix;
bool isOrthographic;
bool isWireframeEnabled;
bool isLightingEnabled;
bool isLightTrackingEnabled;
......@@ -168,7 +169,6 @@ protected:
QMatrix4x4 m_ViewProjectionMatrix;
QMatrix4x4 m_ViewProjectionMatrixInverse;
QMatrix4x4 m_PixelToRayMatrix;
Frustum m_Frustum;
......@@ -256,6 +256,7 @@ public:
inline const QVector3D& focusPoint() const { return m_View.focusPoint; }
inline float distToFocusPoint() const { return m_View.distToFocusPoint; }
inline float fovY() const { return m_View.fovY; }
inline bool isProjectionOrthographic() const { return m_View.isOrthographic; }
inline double focal() const { return m_Focal; }
inline float zNear() const { return m_View.zNear; }
inline float zFar() const { return m_View.zFar; }
......@@ -278,18 +279,14 @@ public:
inline QMatrix4x4 MVPMatrix( const DisplayableInterface *d ) const { return viewProjectionMatrix() * modelMatrix(d); }
inline QMatrix4x4 MVPMatrixInverse( const DisplayableInterface *d ) const { return MVPMatrix(d).inverted(); }
inline QVector3D rightAxis() const { return viewMatrix().row(0).toVector3D(); }
inline QVector3D topAxis() const { return viewMatrix().row(1).toVector3D(); }
inline QVector3D frontAxis() const { return -viewMatrix().row(2).toVector3D(); }
inline const Frustum& frustum() const { return m_Frustum; }
inline QVector3D viewpointLocation() const
{
const QMatrix4x4& R = viewMatrix();
return R.transposed().mapVector( -R.column(3).toVector3D() );
}
inline QVector3D pixelRay( int px, int py ) const
{
QVector4D clipCoord( 2.0f*px/width() - 1.0f, 2.0f*py/height() - 1.0f, 0.0f, 1.0f );
return m_PixelToRayMatrix.map( clipCoord ).toVector3D();
}
inline QVector3D viewpointLocation() const { auto& R = viewMatrix(); return R.transposed().mapVector( -R.column(3).toVector3D() ); }
void pixelRay( int px, int py, QVector3D &rayOrig, QVector3D &rayDir ) const;
QMatrix4x4 viewportMatrix( bool flipY = false ) const;
inline QMatrix4x4 normalMatrix( const DisplayableInterface *d ) const { QMatrix4x4 m = modelViewMatrix(d); m(0,3) = m(1,3) = m(2,3) = 0.0f; return m; }
inline const QMatrix4x4& lightRotationMatrix() const { return m_View.lightRotationMatrix; }
......@@ -381,6 +378,7 @@ public slots:
void setDistToFocusPoint( const float d );
void setViewRotationMatrix( const QMatrix4x4& m );
void setFovY( float fovY );
void setOrthographic( bool ortho );
void setSelectionEnabled( bool enabled );
void setSelectionDisabled( bool disabled );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment