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++; }
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++; }