Example #1
0
void Navigation::scaleAtMouse(
    const QPoint & mouse
,   float scale)
{
    const QVector3D ln = m_camera.eye();
    const QVector3D lf = m_camera.center();

    bool intersects;

    QVector3D i = mouseRayPlaneIntersection(intersects, mouse);

    if(!intersects && !NavigationMath::validDepth(m_coordsProvider->depthAt(mouse)))
        return;

    // scale the distance between the pointed position in the scene and the 
    // camera position - using ray constraints, the center is scaled appropriately.

    if (scale > 0.0)
        scale = 1.0 / (1.0 - scale) - 1.0; // ensure that scaling consistent in both direction

    // enforceScaleConstraints(scale, i);

    const QVector3D eye = ln + scale * (ln - i);
    m_camera.setEye(eye);

    // the center needs to be constrained to the ground plane, so calc the new
    // center based on the intersection with the scene and use this to obtain 
    // the new viewray-groundplane intersection as new center.
    const QVector3D center = lf + scale * (lf - i);

    m_camera.setCenter(NavigationMath::rayPlaneIntersection(intersects, eye, center));
    m_camera.update();
}
Example #2
0
void Navigation::panningProcess(const QPoint & mouse)
{
    assert(PanInteraction == m_mode);

    // The first click of the interaction yields a object space position m_i0.
    // this point is our constraint for panning, that means for every mouse 
    // position there has to be an appropriate positioning for the scene, so
    // that the point under the mouse remains m_i0.
    // With this point and the up normal we build a plane, that defines the 
    // panning space. For panning, a ray is created, pointing from the screen
    // pixel into the view frustum. This ray then is converted to object space
    // and used to intersect with the plane at p. 
    // The delta of m_i0 and p is the translation required for panning.

    // constrain mouse interaction to viewport (if disabled, could lead to mishaps)
    const QPoint clamped(
        clamp(0, m_camera.viewport().width(), mouse.x())
    ,   clamp(0, m_camera.viewport().height(), mouse.y()));

    bool intersects;
    m_i1 = mouseRayPlaneIntersection(intersects, clamped, m_i0, m_viewProjectionInverted);

    if (intersects)
        pan(m_i0 - m_i1);
}
void WorldInHandNavigation::scaleAtMouse(
    const glm::ivec2 & mouse
    , float scaleDelta)
{
    const glm::vec3 eye = m_cameraCapability.eye();
    const glm::vec3 center = m_cameraCapability.center();

    bool intersects = false;

    glm::vec3 intersectPoint = mouseRayPlaneIntersection(intersects, mouse);

    if (!intersects && !DepthExtractor::isValidDepth(m_coordProvider.depthAt(mouse)))
        return;

    // scale the distance between the pointed position in the scene and the 
    // camera position - using ray constraints, the center is scaled appropriately.

    float scale = glm::clamp(scaleDelta, - 1.f, 1.f);

    if (scale > 0.f)
        scale = 1.f / (1.f - scale) - 1.f; // ensure that scaling consistent in both direction
    
    // enforceScaleConstraints(scale, i);

    const glm::vec3 newEye = eye + scale * (intersectPoint - eye);
    m_cameraCapability.setEye(newEye);

    // the center needs to be constrained to the ground plane, so calc the new
    // center based on the intersection with the scene and use this to obtain 
    // the new viewray-groundplane intersection as new center.
    const glm::vec3 newCenter = center + scale * (intersectPoint - center);

    m_cameraCapability.setCenter(navigationmath::rayPlaneIntersection(intersects, newEye, newCenter));
}
void WorldInHandNavigation::panProcess(const glm::ivec2 & mouse)
{
    if (PanInteraction != m_mode || !m_refPositionValid)
        return;

    // The first click of the interaction yields an object space position m_referencePosition.
    // this point is our constraint for panning, that means for every mouse 
    // position there has to be an appropriate positioning for the scene, so
    // that the point under the mouse remains m_referencePosition.
    // With this point and the up normal we build a plane, that defines the 
    // panning space. For panning, a ray is created, pointing from the screen
    // pixel into the view frustum. This ray then is converted to object space
    // and used to intersect with the plane at p. 
    // The delta of m_referencePosition and p is the translation required for panning.

    // constrain mouse interaction to viewport (if disabled, could lead to mishaps)
    const glm::ivec2 clamped(
        glm::clamp(mouse.x, 0, m_viewportCapability.width()),
        glm::clamp(mouse.y, 0, m_viewportCapability.height()));

    bool intersects = false;
    m_modifiedPosition = mouseRayPlaneIntersection(intersects, clamped, m_referencePosition, glm::vec3(0.f, 1.f, 0.f));

    if (intersects)
        pan(m_referencePosition - m_modifiedPosition);
}
Example #5
0
const QVector3D Navigation::mouseRayPlaneIntersection(
    bool & intersects
,   const QPoint & mouse) const
{
    const float depth = m_coordsProvider->depthAt(mouse);

    // no scene object was picked - simulate picking on xz-plane
    if (depth >= 1.0 - std::numeric_limits<float>::epsilon())
        return mouseRayPlaneIntersection(intersects, mouse, QVector3D());

    return m_coordsProvider->objAt(mouse, depth);
}
Example #6
0
void Navigation::rotatingBegin(const QPoint & mouse)
{
    assert(NoInteraction == m_mode);
    m_mode = RotateInteraction;

    bool intersects;
    m_i0 = mouseRayPlaneIntersection(intersects, mouse);
    m_i0Valid = intersects && NavigationMath::validDepth(m_coordsProvider->depthAt(mouse));

    m_m0 = mouse;

    m_eye = m_camera.eye();
    m_center = m_camera.center();
}
Example #7
0
void Navigation::panningBegin(const QPoint & mouse)
{
    assert(NoInteraction == m_mode);
    m_mode = PanInteraction;

    m_viewProjectionInverted = m_camera.viewProjectionInverted();
    
    bool intersects;
    m_i0 = mouseRayPlaneIntersection(intersects, mouse);
    m_i0Valid = intersects && NavigationMath::validDepth(m_coordsProvider->depthAt(mouse));

    m_eye = m_camera.eye();
    m_center = m_camera.center();
}
const glm::vec3 WorldInHandNavigation::mouseRayPlaneIntersection(
    bool & intersects
    , const glm::ivec2 & mouse) const
{
    const float depth = m_coordProvider.depthAt(mouse);

    // no scene object was picked - simulate picking on xz-plane
    if (depth >= 1.0 - std::numeric_limits<float>::epsilon())
        // use current center to construct reference plane
        return mouseRayPlaneIntersection(intersects, mouse, m_cameraCapability.center(), glm::vec3(0.f, 1.f, 0.f));

    intersects = true;
    return m_coordProvider.unproject(mouse, depth);
}
void WorldInHandNavigation::rotateBegin(const glm::ivec2 & mouse)
{
    if (NoInteraction != m_mode)
        return;

    m_mode = RotateInteraction;

    bool intersects = false;
    m_referencePosition = mouseRayPlaneIntersection(intersects, mouse);

    const float depth = m_coordProvider.depthAt(mouse);
    m_refPositionValid = intersects && DepthExtractor::isValidDepth(depth);

    m_m0 = mouse;

    m_eye = m_cameraCapability.eye();
    m_center = m_cameraCapability.center();
}
void WorldInHandNavigation::resetScaleAtMouse(const glm::ivec2 & mouse)
{
    const glm::vec3 ln = m_cameraCapability.eye();
    const glm::vec3 lf = m_cameraCapability.center();

    // set the distance between pointed position in the scene and camera to 
    // default distance
    bool intersects = false;
    glm::vec3 i = mouseRayPlaneIntersection(intersects, mouse);
    if (!intersects && !DepthExtractor::isValidDepth(m_coordProvider.depthAt(mouse)))
        return;

    float scale = (DEFAULT_DISTANCE / static_cast<float>((ln - i).length()));

    //enforceScaleConstraints(scale, i);

    m_cameraCapability.setEye(i - scale * (i - ln));
    m_cameraCapability.setCenter(i - scale * (i - lf));
}
Example #11
0
void Navigation::resetScaleAtMouse(const QPoint & mouse)
{
    const QVector3D ln = m_camera.eye();
    const QVector3D lf = m_camera.center();

    // set the distance between pointed position in the scene and camera to 
    // default distance
    bool intersects;
    QVector3D i = mouseRayPlaneIntersection(intersects, mouse);
    if (!intersects && !NavigationMath::validDepth(m_coordsProvider->depthAt(mouse)))
        return;

    float scale = (DEFAULT_DISTANCE / (ln - i).length());

    //enforceScaleConstraints(scale, i);

    m_camera.setEye(i - scale * (i - ln));
    m_camera.setCenter(i - scale * (i - lf));

    m_camera.update();
}