Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2015-11-11 17:07:22 +0300
committerDaria Volvenkova <d.volvenkova@corp.mail.ru>2015-12-29 16:36:04 +0300
commit45f3a712dab482a95bfe2a7b88627c4ed86c3447 (patch)
tree7540fdc97184c3b932f61757fa99d31d76270548 /geometry
parentfa15cdfd0457c6b8c56fb28d9d536a02321245c3 (diff)
Perspective animation.
Conflicts: drape_frontend/drape_engine.hpp drape_frontend/frontend_renderer.cpp drape_frontend/message.hpp drape_frontend/message_subclasses.hpp Conflicts: drape_frontend/message.hpp
Diffstat (limited to 'geometry')
-rw-r--r--geometry/screenbase.cpp86
-rw-r--r--geometry/screenbase.hpp10
2 files changed, 65 insertions, 31 deletions
diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp
index a948c21428..1ae9dfd428 100644
--- a/geometry/screenbase.cpp
+++ b/geometry/screenbase.cpp
@@ -17,6 +17,7 @@ ScreenBase::ScreenBase() :
m_3dNearZ(0.0),
m_3dFarZ(0.0),
m_3dAngleX(0.0),
+ m_3dMaxAngleX(0.0),
m_3dScaleX(1.0),
m_3dScaleY(1.0),
m_isPerspective(false),
@@ -254,27 +255,57 @@ void ScreenBase::ExtractGtoPParams(MatrixT const & m,
}
// 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)
+// orthogonal projection does. Calculate the expanded area of the visible map plane
+// after rotation through maxRotationAngle around its near horizontal side.
+void ScreenBase::ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV)
{
- // TODO: Handle the case when rotationAngle == 0.0.
- ASSERT_NOT_EQUAL(rotationAngle, 0.0, ());
ASSERT_NOT_EQUAL(angleFOV, 0.0, ());
+ if (m_isPerspective)
+ ResetPerspective();
+
m_isPerspective = true;
- m_3dAngleX = rotationAngle;
+ m_3dMaxAngleX = maxRotationAngle;
m_3dFOV = angleFOV;
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_3dScaleY = cos(m_3dMaxAngleX) + sin(m_3dMaxAngleX) * tan(halfFOV + m_3dMaxAngleX);
+ m_3dScaleX = 1.0 + 2 * sin(m_3dMaxAngleX) * cos(halfFOV) / (cameraZ * cos(halfFOV + m_3dMaxAngleX));
m_3dScaleX = m_3dScaleY = max(m_3dScaleX, m_3dScaleY);
+ double const dy = m_PixelRect.SizeY() * (m_3dScaleX - 1.0);
+
+ Scale(1.0 / m_3dScaleX);
+
+ m_PixelRect.setMaxX(m_PixelRect.maxX() * m_3dScaleX);
+ m_PixelRect.setMaxY(m_PixelRect.maxY() * m_3dScaleY);
+
+ Scale(m_3dScaleX);
+
+ Move(0.0, dy / 2.0);
+
+ SetRotationAngle(currentRotationAngle);
+}
+
+// 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.
+void ScreenBase::SetRotationAngle(double rotationAngle)
+{
+ ASSERT(m_isPerspective, ());
+ ASSERT_LESS_OR_EQUAL(rotationAngle, m_3dMaxAngleX, ());
+
+ if (rotationAngle > m_3dMaxAngleX)
+ rotationAngle = m_3dMaxAngleX;
+
+ m_3dAngleX = rotationAngle;
+
+ double const halfFOV = m_3dFOV / 2.0;
+ double const cameraZ = 1.0 / tan(halfFOV);
+
double const offsetZ = cameraZ + sin(m_3dAngleX) * m_3dScaleY;
double const offsetY = cos(m_3dAngleX) * m_3dScaleX - 1.0;
@@ -296,38 +327,33 @@ void ScreenBase::ApplyPerspective(double rotationAngle, double angleFOV)
m_3dNearZ = cameraZ;
m_3dFarZ = cameraZ + 2.0 * sin(m_3dAngleX) * m_3dScaleY;
projectionM(0, 0) = projectionM(1, 1) = m_3dNearZ;
- projectionM(2, 2) = (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ);
+ projectionM(2, 2) = m_3dAngleX != 0.0 ? (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ)
+ : 0.0;
projectionM(2, 3) = 1.0;
- projectionM(3, 2) = -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ);
+ projectionM(3, 2) = m_3dAngleX != 0.0 ? -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ)
+ : 0.0;
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);
-
- MoveG(m2::PointD(0, -dyG / 2.0));
- m_PixelRect.setMaxX(m_PixelRect.maxX() * m_3dScaleX);
- m_PixelRect.setMaxY(m_PixelRect.maxY() * m_3dScaleY);
-
- Scale(m_3dScaleX);
}
void ScreenBase::ResetPerspective()
{
m_isPerspective = false;
- double const dyG = m_GlobalRect.GetLocalRect().SizeY() * (1.0 - 1.0 / m_3dScaleX);
+ double const dy = m_PixelRect.SizeY() * (1.0 - 1.0 / m_3dScaleX);
Scale(m_3dScaleX);
- MoveG(m2::PointD(0, dyG / 2.0));
m_PixelRect.setMaxX(m_PixelRect.maxX() / m_3dScaleX);
m_PixelRect.setMaxY(m_PixelRect.maxY() / m_3dScaleY);
Scale(1.0 / m_3dScaleX);
+ Move(0, -dy / 2.0);
+
m_3dScaleX = m_3dScaleY = 1.0;
m_3dAngleX = 0.0;
+ m_3dMaxAngleX = 0.0;
m_3dFOV = 0.0;
}
@@ -357,13 +383,17 @@ m2::PointD ScreenBase::P3dToP(m2::PointD const & pt) const
double const normalizedX = 2.0 * pt.x / PixelRectIn3d().SizeX() - 1.0;
double const normalizedY = -2.0 * pt.y / PixelRectIn3d().SizeY() + 1.0;
- double const tanX = tan(m_3dAngleX);
- double const cameraDistanceZ =
- m_3dNearZ * (1.0 + (normalizedY + 1.0) * tanX / (m_3dNearZ - normalizedY * tanX));
-
- double const a = (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ);
- double const b = -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ);
- double const normalizedZ = (a * cameraDistanceZ + b) / cameraDistanceZ;
+ double normalizedZ = 0.0;
+ if (m_3dAngleX != 0.0)
+ {
+ double const tanX = tan(m_3dAngleX);
+ double const cameraDistanceZ =
+ m_3dNearZ * (1.0 + (normalizedY + 1.0) * tanX / (m_3dNearZ - normalizedY * tanX));
+
+ double const a = (m_3dFarZ + m_3dNearZ) / (m_3dFarZ - m_3dNearZ);
+ double const b = -2.0 * m_3dFarZ * m_3dNearZ / (m_3dFarZ - m_3dNearZ);
+ normalizedZ = (a * cameraDistanceZ + b) / cameraDistanceZ;
+ }
Vector3dT const normalizedPoint{normalizedX, normalizedY, normalizedZ, 1.0};
diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp
index 0a627d6c91..2afdd726a8 100644
--- a/geometry/screenbase.hpp
+++ b/geometry/screenbase.hpp
@@ -25,6 +25,7 @@ private:
double m_3dNearZ;
double m_3dFarZ;
double m_3dAngleX;
+ double m_3dMaxAngleX;
double m_3dScaleX;
double m_3dScaleY;
bool m_isPerspective;
@@ -125,9 +126,14 @@ public:
m2::AnyRectD const & GlobalRect() const { return m_GlobalRect; }
m2::RectD const & ClipRect() const { return m_ClipRect; }
- void ApplyPerspective(double rotationAngle, double angleFOV);
+ void ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV);
void ResetPerspective();
+ void SetRotationAngle(double rotationAngle);
+ double GetRotationAngle() const { return m_3dAngleX; }
+
+ double GetAngleFOV() const { return m_3dFOV; }
+
m2::PointD P3dToP(m2::PointD const & pt) const;
Matrix3dT const & PTo3dMatrix() const { return m_Pto3d; }
@@ -139,8 +145,6 @@ public:
{
return m2::RectD(0.0, 0.0, m_PixelRect.maxX() / m_3dScaleX, m_PixelRect.maxY() / m_3dScaleY);
}
- double GetRotationAngle() const { return m_3dAngleX; }
- double GetAngleFOV() const { return m_3dFOV; }
double GetMinPixelRectSize() const;