hfut-cuihao
hfut-cuihao

Reputation: 1

How to zoom in centre of mouse position in OSG(OpenSceneGraph)

have a Qt application with an integrated OSG scene. The problem is that How to zoom in centre of mouse position in OSG(OpenSceneGraph). Normally, in OSG, when we scroll, we zoom around the center of the window, and now I want to zoom around the center of the mouse.

The method of scaling under perspective projection is the original handleMouseWheel(ea, us) method, which is to modify the value of distance. Therefore, if the mouse is the center, the distance before and after scaling should be recorded, and the vector that needs to be shifted to the center should be calculated together with the Angle. The following is a schematic drawing of the calculation, and the backward scaling is similar:

enter image description here

void QOSGViewerWidget::wheelEvent(QWheelEvent* event)
{
    setKeyboardModifiers(event);

    /* get mouse、eye、center position */
    // The mouse point on the screen is converted to a three-dimensional point in world coordinates by     
        // a transformation matrix
    osg::Camera* camera = this->getCamera();
    osg::Matrix mvpw = camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
    osg::Matrix inverseMVPW = osg::Matrix::inverse(mvpw);
    osg::Vec3d mouseToWorld = osg::Vec3d(event->x(), event->y(), 0) * inverseMVPW;
    osg::Vec3d eye, center, up;
    camera->getViewMatrixAsLookAt(eye, center, up);

    /* computing direction */
    osg::Vec3d V1 = mouseToWorld - eye; 
    V1.normalize();
    osg::Vec3d V2 = center - eye;
    V2.normalize();


    // distance before zooming
    double d1 = (center - eye).length();
    //记录缩放后的
    double ZoomRatio = event->delta() > 0 ? 1.1 : 0.9;
    double d2 = d1 * ZoomRatio;
    if (d1 == d2) return;
    double d3 = d1 - d2;


    // cos
    double costheta = V1 * V2;

    // Distance from viewpoint along mouse point direction
    double d5 = d3 / costheta; 
    double d4 = std::sqrt(d5 * d5 - d3 * d3);


    // Move the position of the back point
    osg::Vec3d eye1 = eye + V2 * d3;
    osg::Vec3d eye2 = eye + V1 * d5;
    osg::Vec3d d4_direction = eye2 - eye1;
    d4_direction.normalize();
    osg::Vec3d center1 = center + d4_direction * d4;


    this->getCameraManipulator()->setHomePosition(eye2, center1, up);
    this->home();

}

Upvotes: 0

Views: 63

Answers (0)

Related Questions