diff --git a/drape/overlay_tree.cpp b/drape/overlay_tree.cpp index e0f7dc06a7..17c2f1c7f6 100644 --- a/drape/overlay_tree.cpp +++ b/drape/overlay_tree.cpp @@ -249,7 +249,7 @@ void OverlayTree::Select(m2::RectD const & rect, TSelectResult & result) const if (info.m_handle->IsVisible() && info.m_handle->GetFeatureID().IsValid()) { OverlayHandle::Rects shape; - info.m_handle->GetPixelShape(screen, shape, false); + info.m_handle->GetPixelShape(screen, shape, screen.isPerspective()); for (m2::RectF const & rShape : shape) { if (rShape.IsIntersect(m2::RectF(rect))) diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 666fdb29bf..e455b37cef 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -649,7 +649,7 @@ FeatureID FrontendRenderer::GetVisiblePOI(m2::RectD const & pixelRect) const ScreenBase const & screen = m_userEventStream.GetCurrentScreen(); for (ref_ptr handle : selectResult) { - double const curDist = pt.SquareLength(handle->GetPivot(screen, false)); + double const curDist = pt.SquareLength(handle->GetPivot(screen, screen.isPerspective())); if (curDist < dist) { dist = curDist; @@ -911,10 +911,12 @@ void FrontendRenderer::OnTap(m2::PointD const & pt, bool isLongTap) { double halfSize = VisualParams::Instance().GetTouchRectRadius(); m2::PointD sizePoint(halfSize, halfSize); - m2::RectD selectRect(pt - sizePoint, pt + sizePoint); ScreenBase const & screen = m_userEventStream.GetCurrentScreen(); bool isMyPosition = false; + + m2::RectD selectRect(pt - sizePoint, pt + sizePoint); + if (m_myPositionController->IsModeHasPosition()) isMyPosition = selectRect.IsPointInside(screen.GtoP(m_myPositionController->Position())); diff --git a/drape_frontend/navigator.cpp b/drape_frontend/navigator.cpp index 809023829e..4a60257301 100644 --- a/drape_frontend/navigator.cpp +++ b/drape_frontend/navigator.cpp @@ -417,8 +417,10 @@ bool Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, ScreenBase & screen) { math::Matrix const newM = - screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1, oldPt2, - newPt1, newPt2, doRotateScreen); + screen.GtoPMatrix() * ScreenBase::CalcTransform(screen.P3dToP(oldPt1), screen.P3dToP(oldPt2), + screen.P3dToP(newPt1), screen.P3dToP(newPt2), + doRotateScreen); + ScreenBase tmp = screen; tmp.SetGtoPMatrix(newM); diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index 7b1cad54d6..12c92b170b 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -287,15 +287,15 @@ void ScreenBase::ApplyPerspective(double rotationAngle, double angleFOV) translateM(3, 2) = offsetZ; Matrix3dT projectionM = math::Zero(); - // TODO: Calculate near and far values. - double const near = 0.1; - double const far = 100.0; + double const near = cameraZ; + double const far = cameraZ + 2.0 * m_3dScaleY * cos(m_3dAngleX); projectionM(0, 0) = projectionM(1, 1) = cameraZ; projectionM(2, 2) = (far + near) / (far - near); projectionM(2, 3) = 1.0; projectionM(3, 2) = -2.0 * far * near / (far - near); m_Pto3d = scaleM * rotateM * translateM * projectionM; + m_3dtoP = math::Inverse(m_Pto3d); double const dyG = m_GlobalRect.GetLocalRect().SizeY() * (m_3dScaleX - 1.0); Scale(1.0 / m_3dScaleX); @@ -334,3 +334,19 @@ m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const return pixelPointPerspective; } + +m2::PointD ScreenBase::P3dToP(m2::PointD const & pt) const +{ + if (!m_isPerspective) + return pt; + + m2::PointD nPt(pt.x * 2.0 / PixelRectIn3d().SizeX() - 1.0, - pt.y * 2.0 / PixelRectIn3d().SizeY() + 1.0); + math::Matrix pt3d{ nPt.x, nPt.y, nPt.y * tan(m_3dAngleX), 1.0 }; + math::Matrix ptScreen = pt3d * m_3dtoP; + ptScreen(0, 0) /= ptScreen(0, 3); + ptScreen(0, 1) /= ptScreen(0, 3); + + m2::PointD res = m2::PointD((ptScreen(0, 0) / 2.0 + 0.5) * PixelRect().SizeX(), + (0.5 - ptScreen(0, 1) / 2.0) * PixelRect().SizeY()); + return res; +} diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index 49a9462206..066a348f4d 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -48,6 +48,7 @@ protected: /// @} Matrix3dT m_Pto3d; + Matrix3dT m_3dtoP; // Update dependent parameters from base parameters. // Must be called when base parameters changed. @@ -125,6 +126,8 @@ public: void ApplyPerspective(double rotationAngle, double angleFOV); void ResetPerspective(); + m2::PointD P3dToP(m2::PointD const & pt) const; + Matrix3dT const & PTo3dMatrix() const { return m_Pto3d; } bool isPerspective() const { return m_isPerspective; } diff --git a/map/framework.cpp b/map/framework.cpp index 270f02f4ce..935c610376 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1639,6 +1639,8 @@ void Framework::InvalidateRendering() UserMark const * Framework::OnTapEventImpl(m2::PointD pxPoint, bool isLong, bool isMyPosition, FeatureID const & feature) { + pxPoint = m_currentMovelView.P3dToP(pxPoint); + if (isMyPosition) { search::AddressInfo info;