void MultitouchNavigation::moveZ(TouchContact c)
{
    // calculate ModelView - Projection - Window Matrix to transform screen position to world position:
    osg::Camera *cam = coVRConfig::instance()->channels[0].camera;
    osg::Matrix MVPW(cam->getViewMatrix() * cam->getProjectionMatrix() * cam->getViewport()->computeWindowMatrix());
    osg::Matrixd inverseMVPW = osg::Matrixd::inverse(MVPW);

    // determine z plane of Xform in screen coordinates
    if (_counter == 0)
        _initial = cover->getXformMat().getTrans() * MVPW;
    // transform y-center to 3D world coordinate system (x chosen randomly)
    osg::Vec3d currentVector3D(cover->frontWindowHorizontalSize / 2, c.y, _initial.z());

    if (_counter > 0)
    {
        //rotate y to z and apply transformation
        osg::Vec3d yMov = _previousVector3D * inverseMVPW - currentVector3D * inverseMVPW;

        osg::Matrixd trans, M;
        osg::Vec3d viewerAxis = cover->getViewerMat().getTrans();
        double angle = angleBetween3DVectors(yMov, viewerAxis);
        osg::Vec3d axis = yMov ^ viewerAxis;
        axis.normalize();
        M.makeRotate(angle, axis);

        yMov.x() = sqrt(yMov.x() * yMov.x());
        yMov.y() = sqrt(yMov.y() * yMov.y());
        yMov.z() = sqrt(yMov.z() * yMov.z());
        yMov = yMov * M;
        trans.makeTranslate(yMov);
        cover->setXformMat(cover->getXformMat() * trans);
    }
    _previousVector3D = currentVector3D;
    _counter++;
}
示例#2
0
osg::Matrixd NodePathUtils::getWindowToLocalTransform(const osg::NodePath& path, bool ignorecameras) 
{
	osg::Matrixd MVPW(getLocalToWindowTransform(path, ignorecameras));	
	osg::Matrixd inverseMVPW;
	inverseMVPW.invert(MVPW);
	
	return inverseMVPW;
}
void MultitouchNavigation::rotateZ(const std::list<TouchContact> &contacts)
{
    // get current screen position of finger
    osg::Vec3d curr3DVec1(contacts.front().x, cover->frontWindowVerticalSize - contacts.front().y, 0.);
    osg::Vec3d curr3DVec2(contacts.back().x, cover->frontWindowVerticalSize - contacts.back().y, 0.);

    if (_counter > 0)
    {
        // figure out rotation
        osg::Vec3d lineCurrCurr = osg::Vec3d(curr3DVec1.x(), curr3DVec1.y(), 1.0) ^ osg::Vec3d(curr3DVec2.x(), curr3DVec2.y(), 1.0);
        osg::Vec3d linePrevPrev = osg::Vec3d(_prev3DVec1.x(), _prev3DVec1.y(), 1.0) ^ osg::Vec3d(_prev3DVec2.x(), _prev3DVec2.y(), 1.0);
        osg::Vec3d interception = lineCurrCurr ^ linePrevPrev;
        if (interception.z() != 0.)
        {
            double x = interception.x() / interception.z();
            double y = interception.y() / interception.z();

            // calculate ModelView - Projection - Window Transformation
            osg::Camera *cam = coVRConfig::instance()->channels[0].camera;
            osg::Matrix MVPW(cam->getViewMatrix() * cam->getProjectionMatrix() * cam->getViewport()->computeWindowMatrix());
            osg::Matrixd inverseMVPW = osg::Matrixd::inverse(MVPW);
            // determine z-plane of Xform in screen coordinates
            osg::Vec3d XformTranslation2D = cover->getXformMat().getTrans() * MVPW;
            // rotation center in Xform coordinates
            osg::Vec3d currentVector3D(x, y, XformTranslation2D.z());
            currentVector3D = currentVector3D * inverseMVPW;

            // calculate angle & axis
            double angle = angleBetween3DVectors((_prev3DVec1 - _prev3DVec2), (curr3DVec1 - curr3DVec2));
            osg::Vec3d axis = cover->getViewerMat().getTrans() - currentVector3D;
            osg::Vec3d sign = (_prev3DVec1 - _prev3DVec2) ^ (curr3DVec1 - curr3DVec2);
            sign.normalize();
            axis.x() = axis.x() * sign.z();
            axis.y() = axis.y() * sign.z();
            axis.z() = axis.z() * sign.z();
            osg::Quat delta = osg::Quat(angle, axis);

            // create copy of XformMat for calculation
            osg::Matrixd Xform = cover->getXformMat();
            // translate coordinate system to center of line
            Xform.postMultTranslate(-currentVector3D);
            // rotate
            Xform.postMultRotate(delta);
            // translate back to origin
            Xform.postMultTranslate(currentVector3D);
            // set XformMat to copy
            cover->setXformMat(Xform);
        }
    }

    _prev3DVec1 = curr3DVec1;
    _prev3DVec2 = curr3DVec2;
    _counter++;
}
void MultitouchNavigation::continuousScaleXYZ(const std::list<TouchContact> &contacts)
{
    // convert contact coordinates to current vectors
    osg::Vec2d currentPosition2DFinger1(contacts.front().x, cover->frontWindowVerticalSize - contacts.front().y);
    osg::Vec2d currentPosition2DFinger2(contacts.back().x, cover->frontWindowVerticalSize - contacts.back().y);

    // calculate center of line between finger1 and finger2
    osg::Vec2d scaleCenter = (currentPosition2DFinger1 + currentPosition2DFinger2) / 2.;
    // calculate ModelView - Projection - Window Transformation
    osg::Camera *cam = coVRConfig::instance()->channels[0].camera;
    osg::Matrix MVPW(cam->getViewMatrix() * cam->getProjectionMatrix() * cam->getViewport()->computeWindowMatrix());
    osg::Matrixd inverseMVPW = osg::Matrixd::inverse(MVPW);
    // determine z-plane of Xform in screen coordinates
    osg::Vec3d XformTranslation2D = cover->getXformMat().getTrans() * MVPW;
    // scaleCenter in Xform coordinates
    osg::Vec3d currentVector3D(scaleCenter.x(), scaleCenter.y(), XformTranslation2D.z());
    currentVector3D = currentVector3D * inverseMVPW;

    // get length of difference
    double currentDistance = osg::Vec2d(currentPosition2DFinger1 - currentPosition2DFinger2).length();
    // set _initialValue
    if (_counter == 0)
        _initialValue = currentDistance;

    // divide by _initialValue if != 0
    if (_counter > 0 && _initialValue != 0.)
    {
        // create copy of XformMat for calculation
        osg::Matrixd Xform = cover->getXformMat();
        // translate coordinate system to center of line
        Xform.postMultTranslate(-currentVector3D);
        // scale
        double scaleFactor = currentDistance / _initialValue;
        if (scaleFactor >= 1.)
        {
            scaleFactor--;
            scaleFactor *= 0.15;
            scaleFactor++;
        }
        else
        {
            scaleFactor = 1 - scaleFactor;
            scaleFactor *= 0.15;
            scaleFactor = 1 - scaleFactor;
        }
        Xform.postMultScale(osg::Vec3d(scaleFactor, scaleFactor, scaleFactor));
        // translate back to origin
        Xform.postMultTranslate(currentVector3D);
        // set XformMat to copy
        cover->setXformMat(Xform);
        //cover->setScale(cover->getScale() * scaleFactor);
    }
    _counter++;
}
void MultitouchNavigation::continuousMoveXY(TouchContact c)
{
    // calculate ModelView - Projection - Window Transformation
    osg::Camera *cam = coVRConfig::instance()->channels[0].camera;
    osg::Matrix MVPW(cam->getViewMatrix() * cam->getProjectionMatrix() * cam->getViewport()->computeWindowMatrix());
    osg::Matrixd inverseMVPW = osg::Matrixd::inverse(MVPW);

    // determine z plane of Xform in screen coordinates
    osg::Vec3d XformTranslation2D = cover->getXformMat().getTrans() * MVPW;
    // determine center of both fingers
    osg::Vec3d currentVector3D(c.x, c.y, XformTranslation2D.z());

    if (_counter > 0)
    {
        double xDistance, yDistance, xValue, yValue;
        int xSign, ySign;
        xSign = ySign = 1;
        xDistance = currentVector3D.x() - _previousVector3D.x();
        xValue = sqrt(xDistance * xDistance);
        yDistance = currentVector3D.y() - _previousVector3D.y();
        yValue = sqrt(yDistance * yDistance);
        if (xDistance != 0.)
        {
            xSign = xDistance / xValue;
        }
        if (yDistance != 0.)
        {
            ySign = yDistance / yValue;
        }
        osg::Vec3d trans(xSign * exp(xValue / 50.), ySign * exp(yValue / 50.), 0.);
        osg::Camera *cam = coVRConfig::instance()->channels[0].camera;
        osg::Matrixd M;
        M.makeRotate(osg::Matrixd::inverse(cam->getViewMatrix()).getRotate());
        trans = trans * M;
        osg::Matrixd temp;
        temp.makeTranslate(trans);

        cover->setXformMat(cover->getXformMat() * temp);
    }

    if (_counter == 0)
        _previousVector3D = currentVector3D;
    _counter++;
}
void MultitouchNavigation::moveXY(TouchContact c)
{
    // calculate ModelView - Projection - Window Transformation
    osg::Camera *cam = coVRConfig::instance()->channels[0].camera;
    osg::Matrix MVPW(cam->getViewMatrix() * cam->getProjectionMatrix() * cam->getViewport()->computeWindowMatrix());
    osg::Matrixd inverseMVPW = osg::Matrixd::inverse(MVPW);

    // determine z plane of Xform in screen coordinates
    osg::Vec3d XformTranslation2D = cover->getXformMat().getTrans() * MVPW;
    // determine center of both fingers
    osg::Vec3d currentVector3D(c.x, c.y, XformTranslation2D.z());

    if (_counter > 0)
    {
        osg::Matrixd temp;
        temp.makeTranslate(currentVector3D * inverseMVPW - _previousVector3D * inverseMVPW);
        cover->setXformMat(cover->getXformMat() * temp);
    }

    _previousVector3D = currentVector3D;
    _counter++;
}