/// update of the rotation matrix 'mat_cur', using the position /// of the beginning of the dragging and the current position. /// both coordinates mapped to the surface of the virtual trackball. inline void update(void) { math::vec3 v_from = map_sphere(v_down, center, radius); math::vec3 v_to = map_sphere(v_cur, center, radius); if (drag) q_cur = from_ball_points(v_from, v_to) * q_end; to_matrix(mat_cur, q_cur); }
/// indicates the beginning of the dragging. void ArcBall::click( int x, int y ) { m_lastRot = m_currentRot; v_mouse_down.setX( x ); v_mouse_down.setY( y ); v_mouse_down.setZ( 0.0 ); v_from = map_sphere( x, y ); }
/// sets the current position and calculates the current /// rotation matrix. void ArcBall::drag( int x, int y ) { QVector3D v_to = map_sphere( x, y ); QVector3D perp = QVector3D::crossProduct( v_from, v_to); if ( perp.length() > Epsilon ) { q_current_rotation.setX( perp.x() ); q_current_rotation.setY( perp.y() ); q_current_rotation.setZ( perp.z() );; q_current_rotation.setScalar( ( v_from.x() * v_to.x() ) + ( v_from.y() * v_to.y() ) + ( v_from.z() * v_to.z() ) ); } else { q_current_rotation.setX( 0.0 ); q_current_rotation.setY( 0.0 ); q_current_rotation.setZ( 0.0 ); q_current_rotation.setScalar( 0.0 ); } m_currentRot.setToIdentity(); m_currentRot.rotate( q_current_rotation ); m_currentRot = m_currentRot * m_lastRot ; }