Commit 40c61924 authored by Frédéric Larue's avatar Frédéric Larue
Browse files

NavigationControl class added to GLViewer in order to give the possibility to...

NavigationControl class added to GLViewer in order to give the possibility to change the way the navigation is controlled by input devices.
parent 40a9e2a2
......@@ -21,6 +21,261 @@
void GLViewer::NavigationControl::mouseMoveEvent( double dx, double dy, QMouseEvent *evt )
{
GLViewer &v = *GetViewer();
if( v.dof() == DISPLAY_DOF_2D )
{
if( evt->buttons() & Qt::MidButton )
{
double proj[16];
glGetDoublev( GL_PROJECTION_MATRIX, proj );
double scaleFactor = 2.0*v.distToFocusPoint() / (v.width()*proj[0]);
double scaledDX = dx * scaleFactor;
double scaledDY = dy * scaleFactor;
QVector3D fpoint = v.focusPoint();
fpoint[0] += scaledDY*v.viewRotationMatrix()(1,0) - scaledDX*v.viewRotationMatrix()(0,0);
fpoint[1] += scaledDY*v.viewRotationMatrix()(1,1) - scaledDX*v.viewRotationMatrix()(0,1);
v.setFocusPoint( fpoint );
}
#if 0
else if( evt->buttons() & Qt::LeftButton )
{
const double orientation = (evt->x()-0.5*width())*dy - (evt->y()-0.5*height())*dx;
Matrix4Dd deltaRot;
if( orientation > 0.0 )
deltaRot.SetRotation( Vector3Dd(0,0,1), -0.5*M_PI/180.0*std::sqrt(dx*dx+dy*dy) );
else
deltaRot.SetRotation( Vector3Dd(0,0,1), 0.5*M_PI/180.0*std::sqrt(dx*dx+dy*dy) );
setViewRotationMatrix( viewRotationMatrix() * deltaRot );
update();
}
#endif
}
else
{
if( evt->buttons() & Qt::LeftButton && evt->buttons() & Qt::RightButton )
{
QVector3D axis( dy, dx, 0.0f );
double axisLen = axis.length();
QMatrix4x4 deltaRot;
deltaRot.rotate( 0.5f*axisLen, axis/axisLen );
if( v.isLightTrackingEye() )
v.setLightRotationMatrix( deltaRot * v.lightRotationMatrix() );
else
v.setLightRotationMatrix( v.viewRotationMatrix() * deltaRot * v.viewRotationMatrixInverse() * v.lightRotationMatrix() );
}
else if( evt->buttons() & Qt::MidButton )
{
double proj[16];
glGetDoublev( GL_PROJECTION_MATRIX, proj );
double scaleFactor = 2.0*v.distToFocusPoint() / (v.width()*proj[0]);
double scaledDX = dx * scaleFactor;
double scaledDY = dy * scaleFactor;
QVector3D fpoint = v.focusPoint();
fpoint[0] += scaledDY*v.viewRotationMatrix()(1,0) - scaledDX*v.viewRotationMatrix()(0,0);
fpoint[1] += scaledDY*v.viewRotationMatrix()(1,1) - scaledDX*v.viewRotationMatrix()(0,1);
fpoint[2] += scaledDY*v.viewRotationMatrix()(1,2) - scaledDX*v.viewRotationMatrix()(0,2);
v.setFocusPoint( fpoint );
v.emitScreenSpaceTranslation( QVector2D(-scaledDX,scaledDY) );
}
else if( evt->buttons() & Qt::LeftButton )
{
QMatrix4x4 deltaRot;
if( evt->pos().x() < 0.15f*v.width() )
deltaRot.rotate( 0.5f*dy, 0,0,1 );
else if( evt->pos().x() > 0.85f*v.width() )
deltaRot.rotate( -0.5f*dy, 0,0,1 );
else
{
QVector3D axis( dy, dx, 0.0f );
double axisLen = axis.length();
deltaRot.rotate( 0.5f*axisLen, axis/axisLen );
}
v.emitViewRotationMatrixUpdated( deltaRot );
v.setViewRotationMatrix( deltaRot * v.viewRotationMatrix() );
}
}
}
void GLViewer::NavigationControl::wheelEvent( double delta, QWheelEvent* evt )
{
GLViewer &v = *GetViewer();
delta *= -0.0005 * v.distToFocusPoint();
if( v.distToFocusPoint() + delta > 0.0 )
v.setDistToFocusPoint( v.distToFocusPoint() + delta );
}
void GLViewer::NavigationControl::mouseDoubleClickEvent( QMouseEvent *evt )
{
GLViewer &v = *GetViewer();
PickedPoint point;
if( v.getPickedPoint( evt->x(), v.height()-evt->y(), point, false ) )
{
if( evt->modifiers() & Qt::ControlModifier )
v.frameItem( point.srcObject );
else
v.setFocusPoint( point.global );
}
}
bool GLViewer::NavigationControl::keyPressEvent( QKeyEvent *evt )
{
GLViewer &v = *GetViewer();
if( evt->key() == Qt::Key_Space )
{
v.centerView();
return true;
}
bool keyGrabbed = true;
QMatrix4x4 rot;
if( v.dof() == DISPLAY_DOF_2D )
{
switch( evt->key() )
{
case Qt::Key_4:
{
rot.rotate( -15.0f, 0,0,1 );
v.setViewRotationMatrix( rot * v.viewRotationMatrix() );
break;
}
case Qt::Key_5:
{
v.setViewRotationMatrix( rot );
break;
}
case Qt::Key_6:
{
rot.rotate( 15.0f, 0,0,1 );
v.setViewRotationMatrix( rot * v.viewRotationMatrix() );
break;
}
default: keyGrabbed = false;
}
}
else // if( v.dof() == DISPLAY_DOF_3D )
{
switch( evt->key() )
{
case Qt::Key_5:
{
v.setOrthographic( !v.isProjectionOrthographic() );
break;
}
case Qt::Key_1:
{
if( evt->modifiers() & Qt::CTRL )
rot.rotate( 180.0f, 0,1,0 );
v.setViewRotationMatrix( rot );
break;
}
case Qt::Key_3:
{
rot.rotate( -90.0f, 0,1,0 );
if( evt->modifiers() & Qt::CTRL )
rot.rotate( 180.0f, 0,1,0 );
v.setViewRotationMatrix( rot );
break;
}
case Qt::Key_7:
{
rot.rotate( 90.0f, 1,0,0 );
if( evt->modifiers() & Qt::CTRL )
rot.rotate( 180.0f, 1,0,0 );
v.setViewRotationMatrix( rot );
break;
}
case Qt::Key_4:
{
rot.rotate( 15.0f, 0,1,0 );
v.setViewRotationMatrix( v.viewRotationMatrix() * rot );
break;
}
case Qt::Key_6:
{
rot.rotate( -15.0f, 0,1,0 );
v.setViewRotationMatrix( v.viewRotationMatrix() * rot );
break;
}
case Qt::Key_2:
{
rot.rotate( -15.0f, 1,0,0 );
v.setViewRotationMatrix( rot * v.viewRotationMatrix() );
break;
}
case Qt::Key_8:
{
rot.rotate( 15.0f, 1,0,0 );
v.setViewRotationMatrix( rot * v.viewRotationMatrix() );
break;
}
default: keyGrabbed = false;
}
}
return keyGrabbed;
}
void GLViewer::NavigationControl::updateProjectionMatrix( QMatrix4x4 &m )
{
GLViewer &v = *GetViewer();
m.fill( 0.0f );
if( v.isProjectionOrthographic() )
{
m(0,0) = 2.0f * v.height() / (v.distToFocusPoint() * v.width());
m(1,1) = 2.0f / v.distToFocusPoint();
m(2,2) = -2.0f / (v.zFar() - v.zNear());
m(2,3) = -(v.zFar() + v.zNear()) / (v.zFar() - v.zNear());
m(3,3) = 1.0f;
}
else
{
m(0,0) = v.focal() * v.height() / v.width();
m(1,1) = v.focal();
m(2,2) = (v.zNear() + v.zFar()) / (v.zNear() - v.zFar());
m(2,3) = 2.0f*v.zNear()*v.zFar() / (v.zNear() - v.zFar());
m(3,2) = -1.0f;
}
}
void GLViewer::NavigationControl::updateViewMatrix( QMatrix4x4 &m )
{
GLViewer &v = *GetViewer();
m.setToIdentity();
m.translate( 0.0, 0.0, -v.distToFocusPoint() );
m *= v.viewRotationMatrix();
m.translate( -v.focusPoint() );
}
void GLViewer::DisplayableInfo::Initialize( DisplayableInterface *displayable,
DisplayableList::iterator priorityPos,
UIParamSet &params )
......@@ -129,6 +384,8 @@ GLViewer::~GLViewer()
{
removeAllDisplayables();
clearNavigationControlStack();
for( std::vector<SelectionTool*>::iterator tool=m_SelectionTools.begin(); tool!=m_SelectionTools.end(); ++tool )
delete *tool;
......@@ -155,9 +412,7 @@ void GLViewer::init( DisplayDoF dof )
m_MustUpdateProjectionMatrix = true;
m_MustUpdateViewMatrix = true;
m_SpeedFactor = 1.0;
m_CtrlSpeedFactor = 4.0;
m_ShiftSpeedFactor = 0.25;
setSpeedFactor( 1.0f, 4.0f, 0.25f );
m_View.focusPoint = QVector3D(-1.0f,-1.0f,-1.0f);
setFocusPoint( QVector3D(0.0f,0.0f,0.0f) );
......@@ -195,6 +450,16 @@ void GLViewer::init( DisplayDoF dof )
}
if( m_NavigationCtrl.empty() )
{
m_NavigationCtrl.push_front( new NavigationControl(this) );
}
else
{
while( m_NavigationCtrl.size() > 1 )
popNavigationControl();
}
// Initialize selection tools.
m_IsSelectionAllowed = true;
......@@ -655,102 +920,6 @@ void GLViewer::initializeGL()
}
void GLViewer::mouseMotionNavigationEvent( float dx, float dy, QMouseEvent *evt )
{
if( dof() == DISPLAY_DOF_2D )
{
if( evt->buttons() & Qt::MidButton )
{
double proj[16];
glGetDoublev( GL_PROJECTION_MATRIX, proj );
double scaleFactor = 2.0*distToFocusPoint() / (width()*proj[0]);
double scaledDX = dx * scaleFactor;
double scaledDY = dy * scaleFactor;
QVector3D fpoint = focusPoint();
fpoint[0] += scaledDY*viewRotationMatrix()(1,0) - scaledDX*viewRotationMatrix()(0,0);
fpoint[1] += scaledDY*viewRotationMatrix()(1,1) - scaledDX*viewRotationMatrix()(0,1);
setFocusPoint( fpoint );
update();
}
#if 0
else if( evt->buttons() & Qt::LeftButton )
{
const double orientation = (evt->x()-0.5*width())*dy - (evt->y()-0.5*height())*dx;
Matrix4Dd deltaRot;
if( orientation > 0.0 )
deltaRot.SetRotation( Vector3Dd(0,0,1), -0.5*M_PI/180.0*std::sqrt(dx*dx+dy*dy) );
else
deltaRot.SetRotation( Vector3Dd(0,0,1), 0.5*M_PI/180.0*std::sqrt(dx*dx+dy*dy) );
setViewRotationMatrix( viewRotationMatrix() * deltaRot );
update();
}
#endif
}
else
{
if( evt->buttons() & Qt::LeftButton && evt->buttons() & Qt::RightButton )
{
QVector3D axis( dy, dx, 0.0f );
double axisLen = axis.length();
QMatrix4x4 deltaRot;
deltaRot.rotate( 0.5f*axisLen, axis/axisLen );
if( m_View.isLightTrackingEnabled )
m_View.lightRotationMatrix = deltaRot * m_View.lightRotationMatrix;
else
m_View.lightRotationMatrix = viewRotationMatrix() * deltaRot * viewRotationMatrix().inverted() * m_View.lightRotationMatrix;
update();
}
else if( evt->buttons() & Qt::MidButton )
{
double proj[16];
glGetDoublev( GL_PROJECTION_MATRIX, proj );
double scaleFactor = 2.0*distToFocusPoint() / (width()*proj[0]);
double scaledDX = dx * scaleFactor;
double scaledDY = dy * scaleFactor;
QVector3D fpoint = focusPoint();
fpoint[0] += scaledDY*viewRotationMatrix()(1,0) - scaledDX*viewRotationMatrix()(0,0);
fpoint[1] += scaledDY*viewRotationMatrix()(1,1) - scaledDX*viewRotationMatrix()(0,1);
fpoint[2] += scaledDY*viewRotationMatrix()(1,2) - scaledDX*viewRotationMatrix()(0,2);
setFocusPoint( fpoint );
emit screenSpaceTranslation( QVector2D(-scaledDX,scaledDY) );
update();
}
else if( evt->buttons() & Qt::LeftButton )
{
QMatrix4x4 deltaRot;
if( evt->pos().x() < 0.15f*width() )
deltaRot.rotate( 0.5f*dy, 0,0,1 );
else if( evt->pos().x() > 0.85f*width() )
deltaRot.rotate( -0.5f*dy, 0,0,1 );
else
{
QVector3D axis( dy, dx, 0.0f );
double axisLen = axis.length();
deltaRot.rotate( 0.5f*axisLen, axis/axisLen );
}
emit viewRotationMatrixUpdated( deltaRot );
setViewRotationMatrix( deltaRot * viewRotationMatrix() );
update();
}
}
}
void GLViewer::pixelRay( int px, int py, QVector3D &rayOrig, QVector3D &rayDir ) const
{
if( isProjectionOrthographic() )
......@@ -928,24 +1097,7 @@ void GLViewer::paintGL()
if( m_MustUpdateProjectionMatrix )
{
m_ProjectionMatrix.fill( 0.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;
}
navigationControl()->updateProjectionMatrix( m_ProjectionMatrix );
m_ProjectionMatrixInverse = m_ProjectionMatrix.inverted();
......@@ -955,10 +1107,7 @@ void GLViewer::paintGL()
if( m_MustUpdateViewMatrix )
{
m_ViewMatrix.setToIdentity();
m_ViewMatrix.translate( 0.0, 0.0, -distToFocusPoint() );
m_ViewMatrix *= viewRotationMatrix();
m_ViewMatrix.translate( -focusPoint() );
navigationControl()->updateViewMatrix( m_ViewMatrix );
m_ViewMatrixInverse = m_ViewMatrix.inverted();
......@@ -1758,7 +1907,7 @@ void GLViewer::mouseMoveEvent( QMouseEvent *evt )
dy *= m_SpeedFactor;
}
mouseMotionNavigationEvent( dx, dy, evt );
navigationControl()->mouseMoveEvent( dx, dy, evt );
}
else if( !isSelectionEnabled() )
findObjectUnderCursor( evt->pos() );
......@@ -1791,15 +1940,16 @@ void GLViewer::wheelEvent( QWheelEvent* evt )
}
else
{
double deltaD = -0.0005 * m_SpeedFactor * distToFocusPoint() * evt->delta();
double deltaD = evt->delta();
if( evt->modifiers() & Qt::ShiftModifier )
deltaD *= m_ShiftSpeedFactor;
else if( evt->modifiers() & Qt::ControlModifier )
deltaD *= m_CtrlSpeedFactor;
else
deltaD *= m_SpeedFactor;
if( distToFocusPoint() + deltaD > 0.0 )
setDistToFocusPoint( distToFocusPoint() + deltaD );
navigationControl()->wheelEvent( deltaD, evt );
}
}
else
......@@ -1821,16 +1971,7 @@ void GLViewer::mouseDoubleClickEvent( QMouseEvent *evt )
m_SelectionCurrentTool->mouseDoubleClickEvent( evt );
}
else if( evt->buttons() == Qt::LeftButton )
{
PickedPoint point;
if( getPickedPoint( evt->x(), height()-evt->y(), point, false ) )
{
if( evt->modifiers() & Qt::ControlModifier )
frameItem( point.srcObject );
else
setFocusPoint( point.global );
}
}
navigationControl()->mouseDoubleClickEvent( evt );
}
......@@ -1913,39 +2054,16 @@ bool GLViewer::event( QEvent *evt )
void GLViewer::keyPressEvent( QKeyEvent *evt )
{
bool defaultBehaviour = false;
if( navigationControl()->keyPressEvent(evt) )
return;
bool defaultBehaviour = false;
if( dof() == DISPLAY_DOF_2D )
{
switch( evt->key() )
{
case Qt::Key_4:
{
QMatrix4x4 rot;
rot.setToIdentity();
rot.rotate( -15.0f, 0,0,1 );
setViewRotationMatrix( rot * viewRotationMatrix() );
update();
break;
}
case Qt::Key_5:
{
QMatrix4x4 rot;
rot.setToIdentity();
setViewRotationMatrix( rot );
update();
break;
}
case Qt::Key_6:
{
QMatrix4x4 rot;
rot.setToIdentity();
rot.rotate( 15.0f, 0,0,1 );
setViewRotationMatrix( rot * viewRotationMatrix() );
update();
break;
}
case Qt::Key_G:
{
if( m_View.metricGrid2D.isGridEnabled(MetricGrid::XY) )
......@@ -1964,9 +2082,7 @@ void GLViewer::keyPressEvent( QKeyEvent *evt )
default: defaultBehaviour = true;
}
}
else
else // if( dof() == DISPLAY_DOF_3D )
{
switch( evt->key() )
{
......@@ -1986,97 +2102,26 @@ void GLViewer::keyPressEvent( QKeyEvent *evt )
}
update();
break;
}
case Qt::Key_5:
{
setOrthographic( !isProjectionOrthographic() );
update();
break;
}
case Qt::Key_1:
{
QMatrix4x4 rot;
if( evt->modifiers() & Qt::CTRL )
rot.rotate( 180.0f, 0,1,0 );
setViewRotationMatrix( rot );
update();
break;
}
case Qt::Key_3:
{
QMatrix4x4 rot;
rot.rotate( -90.0f, 0,1,0 );
if( evt->modifiers() & Qt::CTRL )
rot.rotate( 180.0f, 0,1,0 );
setViewRotationMatrix( rot );
update();
break;
}
case Qt::Key_7:
{
QMatrix4x4 rot;
rot.rotate( 90.0f, 1,0,0 );
if( evt->modifiers() & Qt::CTRL )
rot.rotate( 180.0f, 1,0,0 );
setViewRotationMatrix( rot );
update();
break;
}
case Qt::Key_4:
{
QMatrix4x4 rot;
rot.rotate( 15.0f, 0,1,0 );
setViewRotationMatrix( viewRotationMatrix() * rot );
update();
break;
}
case Qt::Key_6:
{
QMatrix4x4 rot;
rot.rotate( -15.0f, 0,1,0 );
setViewRotationMatrix( viewRotationMatrix() * rot );
update();
break;
}
case Qt::Key_2:
{
QMatrix4x4 rot;
rot.rotate( -15.0f, 1,0,0 );
setViewRotationMatrix( rot * viewRotationMatrix() );
update();
break;
}
case Qt::Key_8:
{
QMatrix4x4 rot;
rot.rotate( 15.0f, 1,0,0 );
setViewRotationMatrix( rot * viewRotationMatrix() );
update();
break;
}
case Qt::Key_Plus:
{
increasePointSize();
update();