diff options
author | Daria Volvenkova <d.volvenkova@corp.mail.ru> | 2015-10-27 17:35:23 +0300 |
---|---|---|
committer | Daria Volvenkova <d.volvenkova@corp.mail.ru> | 2015-12-29 16:36:01 +0300 |
commit | 17fa5f6924d942435a229e2cabf891fa540b4c12 (patch) | |
tree | 6726029ef3564e186718ab16790021328234bcef /geometry | |
parent | 8ffa36a5c6b292227e694062f7cb0a4eae2794aa (diff) |
Review fixes.
Conflicts:
drape/overlay_handle.cpp
drape/overlay_handle.hpp
drape/overlay_tree.cpp
drape/shaders/text_billboard_vertex_shader.vsh
drape_frontend/gui/shape.cpp
drape_frontend/path_text_shape.cpp
Diffstat (limited to 'geometry')
-rw-r--r-- | geometry/screenbase.cpp | 49 | ||||
-rw-r--r-- | geometry/screenbase.hpp | 12 |
2 files changed, 41 insertions, 20 deletions
diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index f9d928149e..7b1cad54d6 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -250,41 +250,46 @@ void ScreenBase::ExtractGtoPParams(MatrixT const & m, dy = m(2, 1); } -void ScreenBase::ApplyPerspective(double angleX, double fov) +// Place the camera at the distance, where it gives the same view of plane as the +// orthogonal projection does and rotate the map plane around its near horizontal side. +// Calculate expanded area of visible map plane. +void ScreenBase::ApplyPerspective(double rotationAngle, double angleFOV) { m_isPerspective = true; - m_3dAngleX = -angleX; - m_3dFOV = fov; + m_3dAngleX = rotationAngle; + m_3dFOV = angleFOV; - double halfFOV = m_3dFOV / 2.0; - double cameraZ = 1.0 / tan(halfFOV); + double const halfFOV = m_3dFOV / 2.0; + double const cameraZ = 1.0 / tan(halfFOV); + // Ratio of the expanded plane's size to the original size. m_3dScaleY = cos(m_3dAngleX) + sin(m_3dAngleX) * tan(halfFOV + m_3dAngleX); m_3dScaleX = 1.0 + 2 * sin(m_3dAngleX) * cos(halfFOV) / (cameraZ * cos(halfFOV + m_3dAngleX)); m_3dScaleX = m_3dScaleY = max(m_3dScaleX, m_3dScaleY); - double offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScaleY; - double offsetY = cos(m_3dAngleX) * m_3dScaleX - 1.0; + double const offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScaleY; + double const offsetY = cos(m_3dAngleX) * m_3dScaleX - 1.0; Matrix3dT scaleM = math::Identity<double, 4>(); scaleM(0, 0) = m_3dScaleX; scaleM(1, 1) = m_3dScaleY; Matrix3dT rotateM = math::Identity<double, 4>(); - rotateM(1, 1) = cos(angleX); - rotateM(1, 2) = -sin(angleX); - rotateM(2, 1) = sin(angleX); - rotateM(2, 2) = cos(angleX); + rotateM(1, 1) = cos(m_3dAngleX); + rotateM(1, 2) = sin(m_3dAngleX); + rotateM(2, 1) = -sin(m_3dAngleX); + rotateM(2, 2) = cos(m_3dAngleX); Matrix3dT translateM = math::Identity<double, 4>(); translateM(3, 1) = offsetY; translateM(3, 2) = offsetZ; Matrix3dT projectionM = math::Zero<double, 4>(); - double near = 0.1; - double far = 100.0; + // TODO: Calculate near and far values. + double const near = 0.1; + double const far = 100.0; projectionM(0, 0) = projectionM(1, 1) = cameraZ; projectionM(2, 2) = (far + near) / (far - near); projectionM(2, 3) = 1.0; @@ -292,7 +297,7 @@ void ScreenBase::ApplyPerspective(double angleX, double fov) m_Pto3d = scaleM * rotateM * translateM * projectionM; - double dyG = m_GlobalRect.GetLocalRect().SizeY() * (m_3dScaleX - 1.0); + double const dyG = m_GlobalRect.GetLocalRect().SizeY() * (m_3dScaleX - 1.0); Scale(1.0 / m_3dScaleX); MoveG(m2::PointD(0, -dyG / 2.0)); @@ -306,7 +311,7 @@ void ScreenBase::ResetPerspective() { m_isPerspective = false; - double dyG = m_GlobalRect.GetLocalRect().SizeY() * (1.0 - 1.0 / m_3dScaleX); + double const dyG = m_GlobalRect.GetLocalRect().SizeY() * (1.0 - 1.0 / m_3dScaleX); Scale(m_3dScaleX); MoveG(m2::PointD(0, dyG / 2.0)); @@ -315,3 +320,17 @@ void ScreenBase::ResetPerspective() Scale(1.0 / m_3dScaleX); } + +m2::PointD ScreenBase::PtoP3d(m2::PointD const & pt) const +{ + Vector3dT const normalizedPoint{float(2.0 * pt.x / m_PixelRect.SizeX() - 1.0), + -float(2.0 * pt.y / m_PixelRect.SizeY() - 1.0), 0.0, 1.0}; + Vector3dT const perspectivePoint = normalizedPoint * m_Pto3d; + + m2::RectD const viewport = PixelRectIn3d(); + m2::PointD const pixelPointPerspective( + (perspectivePoint(0, 0) / perspectivePoint(0, 3) + 1.0) * viewport.SizeX() / 2.0, + (perspectivePoint(0, 1) / perspectivePoint(0, 3) + 1.0) * viewport.SizeY() / 2.0); + + return pixelPointPerspective; +} diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index d666c25922..49a9462206 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -10,8 +10,9 @@ class ScreenBase { public: - typedef math::Matrix<double, 3, 3> MatrixT; - typedef math::Matrix<double, 4, 4> Matrix3dT; + using MatrixT = math::Matrix<double, 3, 3>; + using Matrix3dT = math::Matrix<double, 4, 4>; + using Vector3dT = math::Matrix<double, 1, 4>; private: m2::RectD m_PixelRect; @@ -121,14 +122,15 @@ public: m2::AnyRectD const & GlobalRect() const { return m_GlobalRect; } m2::RectD const & ClipRect() const { return m_ClipRect; } - void ApplyPerspective(double angleX, double fov); + void ApplyPerspective(double rotationAngle, double angleFOV); void ResetPerspective(); Matrix3dT const & PTo3dMatrix() const { return m_Pto3d; } bool isPerspective() const { return m_isPerspective; } - // TODO: temporary function - m2::RectD PixelRect3d() const + m2::PointD PtoP3d(m2::PointD const & pt) const; + + m2::RectD PixelRectIn3d() const { return m2::RectD(0.0, 0.0, m_PixelRect.maxX() / m_3dScaleX, m_PixelRect.maxY() / m_3dScaleY); } |