From feda627f30fd97b62f904c43ca3c8f3f1e608ca0 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Thu, 1 Sep 2016 18:13:15 +0300 Subject: Added tile-based model-view --- drape_frontend/apply_feature_functors.cpp | 43 ++++++++++++------ drape_frontend/apply_feature_functors.hpp | 26 +++++++---- drape_frontend/area_shape.cpp | 34 +++++++------- drape_frontend/area_shape.hpp | 4 +- drape_frontend/arrow3d.cpp | 4 +- drape_frontend/arrow3d.hpp | 2 +- drape_frontend/circle_shape.cpp | 7 +-- drape_frontend/frontend_renderer.cpp | 34 +++++--------- drape_frontend/frontend_renderer.hpp | 2 +- drape_frontend/gps_track_renderer.cpp | 15 +++++-- drape_frontend/gps_track_renderer.hpp | 1 + drape_frontend/line_shape.cpp | 73 ++++++------------------------- drape_frontend/map_shape.hpp | 7 +++ drape_frontend/my_position.cpp | 27 +++++++++--- drape_frontend/my_position.hpp | 4 +- drape_frontend/my_position_controller.cpp | 7 +-- drape_frontend/my_position_controller.hpp | 2 +- drape_frontend/path_symbol_shape.cpp | 2 +- drape_frontend/path_text_shape.cpp | 4 +- drape_frontend/poi_symbol_shape.cpp | 3 +- drape_frontend/render_group.cpp | 12 ++++- drape_frontend/route_builder.cpp | 2 + drape_frontend/route_renderer.cpp | 8 +++- drape_frontend/route_shape.cpp | 57 ++++++++++++++---------- drape_frontend/route_shape.hpp | 10 +++-- drape_frontend/rule_drawer.cpp | 18 +++++--- drape_frontend/selection_shape.cpp | 12 ++++- drape_frontend/selection_shape.hpp | 3 +- drape_frontend/shape_view_params.hpp | 3 ++ drape_frontend/text_layout.cpp | 11 ++--- drape_frontend/text_layout.hpp | 8 ++-- drape_frontend/text_shape.cpp | 6 ++- drape_frontend/tile_key.cpp | 7 +++ drape_frontend/tile_key.hpp | 5 +++ drape_frontend/tile_utils.cpp | 9 ++++ drape_frontend/tile_utils.hpp | 3 ++ 36 files changed, 274 insertions(+), 201 deletions(-) (limited to 'drape_frontend') diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index 3091f10cb1..f3c38b68da 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -222,13 +222,15 @@ uint16_t CalculateHotelOverlayPriority(BaseApplyFeature::HotelData const & data) } // namespace -BaseApplyFeature::BaseApplyFeature(TInsertShapeFn const & insertShape, FeatureID const & id, - int minVisibleScale, uint8_t rank, CaptionDescription const & caption) +BaseApplyFeature::BaseApplyFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, + int minVisibleScale, uint8_t rank, CaptionDescription const & captions) : m_insertShape(insertShape) , m_id(id) - , m_captions(caption) + , m_captions(captions) , m_minVisibleScale(minVisibleScale) , m_rank(rank) + , m_tileCenter(tileCenter) { ASSERT(m_insertShape != nullptr, ()); } @@ -283,10 +285,11 @@ void BaseApplyFeature::SetHotelData(HotelData && hotelData) m_hotelData = move(hotelData); } -ApplyPointFeature::ApplyPointFeature(TInsertShapeFn const & insertShape, FeatureID const & id, +ApplyPointFeature::ApplyPointFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, int minVisibleScale, uint8_t rank, CaptionDescription const & captions, float posZ) - : TBase(insertShape, id, minVisibleScale, rank, captions) + : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions) , m_posZ(posZ) , m_hasPoint(false) , m_hasArea(false) @@ -338,6 +341,7 @@ void ApplyPointFeature::ProcessRule(Stylist::TRuleWrapper const & rule) if (capRule && isNode) { TextViewParams params; + params.m_tileCenter = m_tileCenter; ExtractCaptionParams(capRule, pRule->GetCaption(1), depth, params); params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -381,6 +385,7 @@ void ApplyPointFeature::Finish() else if (m_circleRule) { CircleViewParams params(m_id); + params.m_tileCenter = m_tileCenter; params.m_depth = m_circleDepth; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -393,6 +398,7 @@ void ApplyPointFeature::Finish() else if (m_symbolRule) { PoiSymbolViewParams params(m_id); + params.m_tileCenter = m_tileCenter; params.m_depth = m_symbolDepth; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -416,9 +422,12 @@ void ApplyPointFeature::Finish() } } -ApplyAreaFeature::ApplyAreaFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, float minPosZ, - float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions) - : TBase(insertShape, id, minVisibleScale, rank, captions, posZ) +ApplyAreaFeature::ApplyAreaFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD tileRect, float minPosZ, + float posZ, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions) + : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions, posZ) , m_minPosZ(minPosZ) , m_isBuilding(posZ > 0.0f) , m_tileRect(tileRect) @@ -575,6 +584,7 @@ void ApplyAreaFeature::ProcessRule(Stylist::TRuleWrapper const & rule) if (areaRule && !m_triangles.empty()) { AreaViewParams params; + params.m_tileCenter = m_tileCenter; params.m_depth = depth; params.m_color = ToDrapeColor(areaRule->color()); params.m_minVisibleScale = m_minVisibleScale; @@ -595,17 +605,18 @@ void ApplyAreaFeature::ProcessRule(Stylist::TRuleWrapper const & rule) TBase::ProcessRule(rule); } -ApplyLineFeature::ApplyLineFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, - int minVisibleScale, uint8_t rank, CaptionDescription const & captions, - double currentScaleGtoP, bool simplify, size_t pointsCount) - : TBase(insertShape, id, minVisibleScale, rank, captions) +ApplyLineFeature::ApplyLineFeature(m2::PointD const & tileCenter, double currentScaleGtoP, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD const & clipRect, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions, bool simplify, size_t pointsCount) + : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions) , m_currentScaleGtoP(currentScaleGtoP) , m_sqrScale(math::sqr(m_currentScaleGtoP)) , m_simplify(simplify) , m_initialPointsCount(pointsCount) , m_shieldDepth(0.0) , m_shieldRule(nullptr) - , m_tileRect(tileRect) + , m_clipRect(move(clipRect)) #ifdef CALC_FILTERED_POINTS , m_readedCount(0) #endif @@ -659,7 +670,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) LineDefProto const * pLineRule = pRule->GetLine(); ShieldRuleProto const * pShieldRule = pRule->GetShield(); - m_clippedSplines = m2::ClipSplineByRect(m_tileRect, m_spline); + m_clippedSplines = m2::ClipSplineByRect(m_clipRect, m_spline); if (m_clippedSplines.empty()) return; @@ -671,6 +682,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) CaptionDefProtoToFontDecl(pCaptionRule, fontDecl); PathTextViewParams params; + params.m_tileCenter = m_tileCenter; params.m_featureID = m_id; params.m_depth = depth; params.m_minVisibleScale = m_minVisibleScale; @@ -689,6 +701,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) { PathSymProto const & symRule = pLineRule->pathsym(); PathSymbolViewParams params; + params.m_tileCenter = m_tileCenter; params.m_depth = depth; params.m_minVisibleScale = m_minVisibleScale; params.m_rank = m_rank; @@ -704,6 +717,7 @@ void ApplyLineFeature::ProcessRule(Stylist::TRuleWrapper const & rule) else { LineViewParams params; + params.m_tileCenter = m_tileCenter; Extract(pLineRule, params); params.m_depth = depth; params.m_minVisibleScale = m_minVisibleScale; @@ -741,6 +755,7 @@ void ApplyLineFeature::Finish() float const mainScale = df::VisualParams::Instance().GetVisualScale(); TextViewParams viewParams; + viewParams.m_tileCenter = m_tileCenter; viewParams.m_depth = m_shieldDepth; viewParams.m_minVisibleScale = m_minVisibleScale; viewParams.m_rank = m_rank; diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp index b2edc079bd..b95baf4ab0 100644 --- a/drape_frontend/apply_feature_functors.hpp +++ b/drape_frontend/apply_feature_functors.hpp @@ -31,7 +31,8 @@ using TInsertShapeFn = function && shape)>; class BaseApplyFeature { public: - BaseApplyFeature(TInsertShapeFn const & insertShape, FeatureID const & id, + BaseApplyFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, int minVisibleScale, uint8_t rank, CaptionDescription const & captions); virtual ~BaseApplyFeature() {} @@ -58,6 +59,8 @@ protected: int m_minVisibleScale; uint8_t m_rank; HotelData m_hotelData; + + m2::PointD m_tileCenter; }; class ApplyPointFeature : public BaseApplyFeature @@ -65,7 +68,8 @@ class ApplyPointFeature : public BaseApplyFeature using TBase = BaseApplyFeature; public: - ApplyPointFeature(TInsertShapeFn const & insertShape, FeatureID const & id, + ApplyPointFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, int minVisibleScale, uint8_t rank, CaptionDescription const & captions, float posZ); @@ -93,8 +97,11 @@ class ApplyAreaFeature : public ApplyPointFeature using TBase = ApplyPointFeature; public: - ApplyAreaFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, float minPosZ, - float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions); + ApplyAreaFeature(m2::PointD const & tileCenter, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD tileRect, float minPosZ, + float posZ, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions); using TBase::operator (); @@ -112,7 +119,7 @@ private: bool FindEdge(TEdge const & edge); m2::PointD CalculateNormal(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) const; - vector m_triangles; + vector m_triangles; unordered_map m_indices; vector> m_edges; @@ -126,9 +133,10 @@ class ApplyLineFeature : public BaseApplyFeature using TBase = BaseApplyFeature; public: - ApplyLineFeature(TInsertShapeFn const & insertShape, FeatureID const & id, m2::RectD tileRect, - int minVisibleScale, uint8_t rank, CaptionDescription const & captions, - double currentScaleGtoP, bool simplify, size_t pointsCount); + ApplyLineFeature(m2::PointD const & tileCenter, double currentScaleGtoP, + TInsertShapeFn const & insertShape, FeatureID const & id, + m2::RectD const & clipRect, int minVisibleScale, uint8_t rank, + CaptionDescription const & captions, bool simplify, size_t pointsCount); void operator() (m2::PointD const & point); bool HasGeometry() const; @@ -145,7 +153,7 @@ private: size_t m_initialPointsCount; double m_shieldDepth; ShieldRuleProto const * m_shieldRule; - m2::RectD m_tileRect; + m2::RectD m_clipRect; #ifdef CALC_FILTERED_POINTS int m_readedCount; diff --git a/drape_frontend/area_shape.cpp b/drape_frontend/area_shape.cpp index 59d632eda5..6955ccb2df 100644 --- a/drape_frontend/area_shape.cpp +++ b/drape_frontend/area_shape.cpp @@ -15,7 +15,7 @@ namespace df { -AreaShape::AreaShape(vector && triangleList, vector && buildingEdges, +AreaShape::AreaShape(vector && triangleList, vector && buildingEdges, AreaViewParams const & params) : m_vertexes(move(triangleList)) , m_buildingEdges(move(buildingEdges)) @@ -36,26 +36,25 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr t for (auto const & edge : m_buildingEdges) { + glsl::vec2 const startPt = glsl::ToVec2(ConvertPt(edge.m_startVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const endPt = glsl::ToVec2(ConvertPt(edge.m_endVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec3 normal(glsl::ToVec2(edge.m_normal), 0.0f); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -m_params.m_minPosZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -m_params.m_minPosZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -m_params.m_posZ), - normal, colorPoint)); - - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -m_params.m_posZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -m_params.m_minPosZ), - normal, colorPoint)); - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -m_params.m_posZ), - normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_minPosZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(endPt, -m_params.m_minPosZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_posZ), normal, colorPoint)); + + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_posZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(endPt, -m_params.m_minPosZ), normal, colorPoint)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(endPt, -m_params.m_posZ), normal, colorPoint)); } glsl::vec3 normal(0.0f, 0.0f, -1.0f); for (auto const & vertex : m_vertexes) - vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(vertex), -m_params.m_posZ), - normal, colorPoint)); + { + glsl::vec2 const pt = glsl::ToVec2(ConvertPt(vertex, m_params.m_tileCenter, kShapeCoordScalar)); + vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(pt, -m_params.m_posZ), normal, colorPoint)); + } dp::GLState state(gpu::AREA_3D_PROGRAM, dp::GLState::GeometryLayer); state.SetColorTexture(region.GetTexture()); @@ -71,7 +70,8 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr t vertexes.resize(m_vertexes.size()); transform(m_vertexes.begin(), m_vertexes.end(), vertexes.begin(), [&colorPoint, this](m2::PointF const & vertex) { - return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(vertex), m_params.m_depth), colorPoint); + return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(ConvertPt(vertex, m_params.m_tileCenter, kShapeCoordScalar)), + m_params.m_depth), colorPoint); }); dp::GLState state(gpu::AREA_PROGRAM, dp::GLState::GeometryLayer); diff --git a/drape_frontend/area_shape.hpp b/drape_frontend/area_shape.hpp index 7dc2844082..c6ae7d1579 100644 --- a/drape_frontend/area_shape.hpp +++ b/drape_frontend/area_shape.hpp @@ -21,13 +21,13 @@ struct BuildingEdge class AreaShape : public MapShape { public: - AreaShape(vector && triangleList, vector && buildingEdges, + AreaShape(vector && triangleList, vector && buildingEdges, AreaViewParams const & params); void Draw(ref_ptr batcher, ref_ptr textures) const override; private: - vector m_vertexes; + vector m_vertexes; vector m_buildingEdges; AreaViewParams m_params; }; diff --git a/drape_frontend/arrow3d.cpp b/drape_frontend/arrow3d.cpp index a4a66e72ce..54aac7d554 100644 --- a/drape_frontend/arrow3d.cpp +++ b/drape_frontend/arrow3d.cpp @@ -118,7 +118,7 @@ void Arrow3d::SetPositionObsolete(bool obsolete) m_obsoletePosition = obsolete; } -void Arrow3d::Render(ScreenBase const & screen, ref_ptr mng) +void Arrow3d::Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng) { // Unbind current VAO, because glVertexAttributePointer and glEnableVertexAttribute can affect it. if (dp::GLExtensionsList::Instance().IsSupported(dp::GLExtensionsList::VertexArrayObject)) @@ -170,7 +170,7 @@ void Arrow3d::RenderArrow(ScreenBase const & screen, ref_ptr pro dp::UniformValuesStorage uniforms; math::Matrix const modelTransform = CalculateTransform(screen, dz); - uniforms.SetMatrix4x4Value("m_transform", modelTransform.m_data); + uniforms.SetMatrix4x4Value("u_transform", modelTransform.m_data); glsl::vec4 const c = glsl::ToVec4(color); uniforms.SetFloatValue("u_color", c.r, c.g, c.b, c.a); dp::ApplyState(m_state, program); diff --git a/drape_frontend/arrow3d.hpp b/drape_frontend/arrow3d.hpp index 56128c2b1d..7dcaeec3e2 100644 --- a/drape_frontend/arrow3d.hpp +++ b/drape_frontend/arrow3d.hpp @@ -30,7 +30,7 @@ public: void SetTexture(ref_ptr texMng); void SetPositionObsolete(bool obsolete); - void Render(ScreenBase const & screen, ref_ptr mng); + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng); private: void Build(); diff --git a/drape_frontend/circle_shape.cpp b/drape_frontend/circle_shape.cpp index 3fd8fba4aa..537133d0b5 100644 --- a/drape_frontend/circle_shape.cpp +++ b/drape_frontend/circle_shape.cpp @@ -24,12 +24,13 @@ void CircleShape::Draw(ref_ptr batcher, ref_ptr dp::TextureManager::ColorRegion region; textures->GetColorRegion(m_params.m_color, region); - glsl::vec2 colorPoint(glsl::ToVec2(region.GetTexRect().Center())); + glsl::vec2 const colorPoint(glsl::ToVec2(region.GetTexRect().Center())); + glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); buffer_vector vertexes; vertexes.push_back(gpu::SolidTexturingVertex { - glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, 0.0f), + glsl::vec4(pt, m_params.m_depth, 0.0f), glsl::vec2(0.0f, 0.0f), colorPoint }); @@ -41,7 +42,7 @@ void CircleShape::Draw(ref_ptr batcher, ref_ptr m2::PointD rotatedNormal = m2::Rotate(startNormal, (i) * etalonSector); vertexes.push_back(gpu::SolidTexturingVertex { - glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, 0.0f), + glsl::vec4(pt, m_params.m_depth, 0.0f), glsl::ToVec2(rotatedNormal), colorPoint }); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index e73e37def3..55c0999e4e 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1027,12 +1027,14 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) { ASSERT(m_myPositionController->IsModeHasPosition(), ()); m_selectionShape->SetPosition(m_myPositionController->Position()); - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, + make_ref(m_gpuProgramManager), m_generalUniforms); } else if (selectedObject == SelectionShape::OBJECT_POI) { if (!isPerspective && m_layers[RenderLayer::Geometry3dID].m_renderGroups.empty()) - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, + make_ref(m_gpuProgramManager), m_generalUniforms); else hasSelectedPOI = true; } @@ -1057,19 +1059,18 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) if (hasSelectedPOI) { GLFunctions::glDisable(gl_const::GLDepthTest); - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); } GLFunctions::glEnable(gl_const::GLDepthTest); GLFunctions::glClearDepth(); RenderOverlayLayer(modelView); - m_gpsTrackRenderer->RenderTrack(modelView, m_currentZoomLevel, - make_ref(m_gpuProgramManager), m_generalUniforms); + m_gpsTrackRenderer->RenderTrack(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); GLFunctions::glDisable(gl_const::GLDepthTest); if (m_selectionShape != nullptr && m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK) - m_selectionShape->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_selectionShape->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); m_routeRenderer->RenderRoute(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); @@ -1082,7 +1083,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) m_routeRenderer->RenderRouteSigns(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); - m_myPositionController->Render(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + m_myPositionController->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); if (m_guiRenderer != nullptr) m_guiRenderer->Render(make_ref(m_gpuProgramManager), modelView); @@ -1223,22 +1224,9 @@ void FrontendRenderer::RefreshProjection(ScreenBase const & screen) m_generalUniforms.SetMatrix4x4Value("projection", m.data()); } -void FrontendRenderer::RefreshModelView(ScreenBase const & screen) +void FrontendRenderer::RefreshZScale(ScreenBase const & screen) { - ScreenBase::MatrixT const & m = screen.GtoPMatrix(); - math::Matrix mv; - - /// preparing ModelView matrix - - mv(0, 0) = m(0, 0); mv(0, 1) = m(1, 0); mv(0, 2) = 0; mv(0, 3) = m(2, 0); - mv(1, 0) = m(0, 1); mv(1, 1) = m(1, 1); mv(1, 2) = 0; mv(1, 3) = m(2, 1); - mv(2, 0) = 0; mv(2, 1) = 0; mv(2, 2) = 1; mv(2, 3) = 0; - mv(3, 0) = m(0, 2); mv(3, 1) = m(1, 2); mv(3, 2) = 0; mv(3, 3) = m(2, 2); - - m_generalUniforms.SetMatrix4x4Value("modelView", mv.m_data); - - float const zScale = screen.GetZScale(); - m_generalUniforms.SetFloatValue("zScale", zScale); + m_generalUniforms.SetFloatValue("zScale", screen.GetZScale()); } void FrontendRenderer::RefreshPivotTransform(ScreenBase const & screen) @@ -1708,7 +1696,7 @@ ScreenBase const & FrontendRenderer::ProcessEvents(bool & modelViewChanged, bool void FrontendRenderer::PrepareScene(ScreenBase const & modelView) { - RefreshModelView(modelView); + RefreshZScale(modelView); RefreshPivotTransform(modelView); m_myPositionController->UpdatePixelPosition(modelView); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 6152e408f1..48418794a7 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -161,7 +161,7 @@ private: void MergeBuckets(); void RenderSingleGroup(ScreenBase const & modelView, ref_ptr group); void RefreshProjection(ScreenBase const & screen); - void RefreshModelView(ScreenBase const & screen); + void RefreshZScale(ScreenBase const & screen); void RefreshPivotTransform(ScreenBase const & screen); void RefreshBgColor(); diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index b5137402be..fcb47e6f70 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -1,5 +1,7 @@ #include "drape_frontend/gps_track_renderer.hpp" #include "drape_frontend/color_constants.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/glsl_func.hpp" @@ -227,11 +229,14 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, m_handlesCache.push_back(make_pair(handle, 0)); } + m_pivot = screen.GlobalRect().Center(); + size_t cacheIndex = 0; if (m_points.size() == 1) { dp::Color const color = GetColorBySpeed(m_points.front().m_speedMPS); - m_handlesCache[cacheIndex].first->SetPoint(0, m_points.front().m_point, m_radius, color); + m2::PointD const pt = MapShape::ConvertPt(m_points.front().m_point, m_pivot, kShapeCoordScalar); + m_handlesCache[cacheIndex].first->SetPoint(0, pt, m_radius, color); m_handlesCache[cacheIndex].second++; } else @@ -248,7 +253,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (screen.ClipRect().IsIntersect(pointRect)) { dp::Color const color = CalculatePointColor(static_cast(it.GetIndex()), pt, it.GetLength(), it.GetFullLength()); - m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, pt, m_radius, color); + m2::PointD const convertedPt = MapShape::ConvertPt(pt, m_pivot, kShapeCoordScalar); + m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius, color); m_handlesCache[cacheIndex].second++; if (m_handlesCache[cacheIndex].second >= m_handlesCache[cacheIndex].first->GetPointsCount()) cacheIndex++; @@ -266,7 +272,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, #ifdef SHOW_RAW_POINTS for (size_t i = 0; i < m_points.size(); i++) { - m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, m_points[i].m_point, m_radius * 1.2, dp::Color(0, 0, 255, 255)); + m2::PointD const convertedPt = MapShape::ConvertPt(m_points[i].m_point, m_pivot, kShapeCoordScalar); + m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius * 1.2, dp::Color(0, 0, 255, 255)); m_handlesCache[cacheIndex].second++; if (m_handlesCache[cacheIndex].second >= m_handlesCache[cacheIndex].first->GetPointsCount()) cacheIndex++; @@ -292,6 +299,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, // Render points. dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix mv = screen.GetModelView(m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); ref_ptr program = mng->GetProgram(gpu::TRACK_POINT_PROGRAM); program->Bind(); diff --git a/drape_frontend/gps_track_renderer.hpp b/drape_frontend/gps_track_renderer.hpp index cb40cb34e8..b9c67005ce 100644 --- a/drape_frontend/gps_track_renderer.hpp +++ b/drape_frontend/gps_track_renderer.hpp @@ -51,6 +51,7 @@ private: bool m_waitForRenderData; vector> m_handlesCache; float m_radius; + m2::PointD m_pivot; }; } // namespace df diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index b5f8073841..20d95615a5 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -73,13 +73,6 @@ public: m_joinGeom.reserve(joinsSize); } - void GetTexturingInfo(float const globalLength, int & steps, float & maskSize) - { - UNUSED_VALUE(globalLength); - UNUSED_VALUE(steps); - UNUSED_VALUE(maskSize); - } - dp::BindingInfo const & GetBindingInfo() override { return TVertex::GetBindingInfo(); @@ -135,42 +128,6 @@ public: return isLeft ? 1.0 : -1.0; } -protected: - vector const & GenerateCap(LineSegment const & segment, EPointType type, - float sign, bool isStart) - { - m_normalBuffer.clear(); - m_normalBuffer.reserve(24); - - GenerateCapNormals(m_params.m_cap, - segment.m_leftNormals[type], - segment.m_rightNormals[type], - sign * segment.m_tangent, - GetHalfWidth(), isStart, m_normalBuffer); - - return m_normalBuffer; - } - - vector const & GenerateJoin(LineSegment const & seg1, LineSegment const & seg2) - { - m_normalBuffer.clear(); - m_normalBuffer.reserve(24); - - glsl::vec2 n1 = seg1.m_hasLeftJoin[EndPoint] ? seg1.m_leftNormals[EndPoint] : - seg1.m_rightNormals[EndPoint]; - - glsl::vec2 n2 = seg2.m_hasLeftJoin[StartPoint] ? seg2.m_leftNormals[StartPoint] : - seg2.m_rightNormals[StartPoint]; - - float widthScalar = seg1.m_hasLeftJoin[EndPoint] ? seg1.m_rightWidthScalar[EndPoint].x : - seg1.m_leftWidthScalar[EndPoint].x; - - GenerateJoinNormals(m_params.m_join, n1, n2, GetHalfWidth(), - seg1.m_hasLeftJoin[EndPoint], widthScalar, m_normalBuffer); - - return m_normalBuffer; - } - protected: using V = TVertex; using TGeometryBuffer = vector; @@ -200,8 +157,7 @@ class SolidLineBuilder : public BaseLineBuilder : m_position(pos) , m_normal(normal) , m_color(color) - { - } + {} TPosition m_position; TNormal m_normal; @@ -326,11 +282,10 @@ public: , m_baseGtoPScale(params.m_baseGtoP) {} - void GetTexturingInfo(float const globalLength, int & steps, float & maskSize) + int GetDashesCount(float const globalLength) const { float const pixelLen = globalLength * m_baseGtoPScale; - steps = static_cast((pixelLen + m_texCoordGen.GetMaskLength() - 1) / m_texCoordGen.GetMaskLength()); - maskSize = globalLength / steps; + return static_cast((pixelLen + m_texCoordGen.GetMaskLength() - 1) / m_texCoordGen.GetMaskLength()); } dp::GLState GetState() override @@ -381,16 +336,16 @@ void LineShape::Construct(DashedLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::vec2(path[i - 1].x, path[i - 1].y); - glsl::vec2 const p2 = glsl::vec2(path[i].x, path[i].y); + glsl::vec2 const p1 = glsl::ToVec2(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(path[i], m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 tangent, leftNormal, rightNormal; CalculateTangentAndNormals(p1, p2, tangent, leftNormal, rightNormal); // calculate number of steps to cover line segment - float const initialGlobalLength = glsl::length(p2 - p1); - int steps = 1; - float maskSize = initialGlobalLength; - builder.GetTexturingInfo(initialGlobalLength, steps, maskSize); + float const initialGlobalLength = static_cast((path[i] - path[i - 1]).Length()); + int const steps = max(1, builder.GetDashesCount(initialGlobalLength)); + float const maskSize = glsl::length(p2 - p1) / steps; + float const offsetSize = initialGlobalLength / steps; // generate vertices float currentSize = 0; @@ -402,8 +357,8 @@ void LineShape::Construct(DashedLineBuilder & builder) const builder.SubmitVertex(currentStartPivot, rightNormal, false /* isLeft */, 0.0); builder.SubmitVertex(currentStartPivot, leftNormal, true /* isLeft */, 0.0); - builder.SubmitVertex(newPivot, rightNormal, false /* isLeft */, maskSize); - builder.SubmitVertex(newPivot, leftNormal, true /* isLeft */, maskSize); + builder.SubmitVertex(newPivot, rightNormal, false /* isLeft */, offsetSize); + builder.SubmitVertex(newPivot, leftNormal, true /* isLeft */, offsetSize); currentStartPivot = newPivot; } @@ -424,7 +379,7 @@ void LineShape::Construct(SolidLineBuilder & builder) const generateJoins = false; // build geometry - glsl::vec2 firstPoint = glsl::vec2(path.front().x, path.front().y); + glsl::vec2 firstPoint = glsl::ToVec2(ConvertPt(path.front(), m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 lastPoint; bool hasConstructedSegments = false; for (size_t i = 1; i < path.size(); ++i) @@ -432,8 +387,8 @@ void LineShape::Construct(SolidLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::vec2(path[i - 1].x, path[i - 1].y); - glsl::vec2 const p2 = glsl::vec2(path[i].x, path[i].y); + glsl::vec2 const p1 = glsl::ToVec2(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(path[i], m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 tangent, leftNormal, rightNormal; CalculateTangentAndNormals(p1, p2, tangent, leftNormal, rightNormal); diff --git a/drape_frontend/map_shape.hpp b/drape_frontend/map_shape.hpp index cdde3a35f4..8582670328 100644 --- a/drape_frontend/map_shape.hpp +++ b/drape_frontend/map_shape.hpp @@ -5,6 +5,8 @@ #include "drape/pointers.hpp" +#include "geometry/point2d.hpp" + namespace dp { class Batcher; @@ -33,6 +35,11 @@ public: void SetFeatureMinZoom(int minZoom) { m_minZoom = minZoom; } int GetFeatureMinZoom() const { return m_minZoom; } + static m2::PointD ConvertPt(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) + { + return (basePt - tileCenter) * scalar; + } + private: int m_minZoom = 0; }; diff --git a/drape_frontend/my_position.cpp b/drape_frontend/my_position.cpp index f3e682fa1e..98afdd7f2f 100644 --- a/drape_frontend/my_position.cpp +++ b/drape_frontend/my_position.cpp @@ -1,5 +1,8 @@ #include "drape_frontend/my_position.hpp" #include "drape_frontend/color_constants.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape/constants.hpp" #include "drape/glsl_func.hpp" @@ -95,21 +98,26 @@ void MyPosition::SetPositionObsolete(bool obsolete) m_arrow3d.SetPositionObsolete(obsolete); } -void MyPosition::RenderAccuracy(ScreenBase const & screen, - ref_ptr mng, - dp::UniformValuesStorage const & commonUniforms) +void MyPosition::RenderAccuracy(ScreenBase const & screen, int zoomLevel, + ref_ptr mng, + dp::UniformValuesStorage const & commonUniforms) { dp::UniformValuesStorage uniforms = commonUniforms; m2::PointD accuracyPoint(m_position.x + m_accuracy, m_position.y); float pixelAccuracy = (screen.GtoP(accuracyPoint) - screen.GtoP(m_position)).Length(); - uniforms.SetFloatValue("u_position", m_position.x, m_position.y, 0.0f); + TileKey const key = GetTileKeyByPoint(m_position, ClipTileZoomByMaxDataZoom(zoomLevel)); + math::Matrix mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + uniforms.SetFloatValue("u_position", pos.x, pos.y, 0.0f); uniforms.SetFloatValue("u_accuracy", pixelAccuracy); uniforms.SetFloatValue("u_opacity", 1.0f); RenderPart(mng, uniforms, MY_POSITION_ACCURACY); } -void MyPosition::RenderMyPosition(ScreenBase const & screen, +void MyPosition::RenderMyPosition(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { @@ -117,12 +125,17 @@ void MyPosition::RenderMyPosition(ScreenBase const & screen, { m_arrow3d.SetPosition(m_position); m_arrow3d.SetAzimuth(m_azimuth); - m_arrow3d.Render(screen, mng); + m_arrow3d.Render(screen, zoomLevel, mng); } else { dp::UniformValuesStorage uniforms = commonUniforms; - uniforms.SetFloatValue("u_position", m_position.x, m_position.y, dp::depth::MY_POSITION_MARK); + TileKey const key = GetTileKeyByPoint(m_position, ClipTileZoomByMaxDataZoom(zoomLevel)); + math::Matrix mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + uniforms.SetFloatValue("u_position", pos.x, pos.y, dp::depth::MY_POSITION_MARK); uniforms.SetFloatValue("u_azimut", -(m_azimuth + screen.GetAngle())); uniforms.SetFloatValue("u_opacity", 1.0); RenderPart(mng, uniforms, MY_POSITION_POINT); diff --git a/drape_frontend/my_position.hpp b/drape_frontend/my_position.hpp index 65abf0b176..8310f01955 100644 --- a/drape_frontend/my_position.hpp +++ b/drape_frontend/my_position.hpp @@ -28,11 +28,11 @@ public: void SetRoutingMode(bool routingMode); void SetPositionObsolete(bool obsolete); - void RenderAccuracy(ScreenBase const & screen, + void RenderAccuracy(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); - void RenderMyPosition(ScreenBase const & screen, + void RenderMyPosition(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index e51f72c1ce..592ea95390 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -500,7 +500,8 @@ bool MyPositionController::UpdateViewportWithAutoZoom() return false; } -void MyPositionController::Render(ScreenBase const & screen, ref_ptr mng, +void MyPositionController::Render(ScreenBase const & screen, int zoomLevel, + ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { if (IsWaitingForLocation()) @@ -551,8 +552,8 @@ void MyPositionController::Render(ScreenBase const & screen, ref_ptrSetAccuracy(m_errorRadius); m_shape->SetRoutingMode(IsInRouting()); - m_shape->RenderAccuracy(screen, mng, commonUniforms); - m_shape->RenderMyPosition(screen, mng, commonUniforms); + m_shape->RenderAccuracy(screen, zoomLevel, mng, commonUniforms); + m_shape->RenderMyPosition(screen, zoomLevel, mng, commonUniforms); } } diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 9d555fc880..51d9ff75ef 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -90,7 +90,7 @@ public: void SetModeListener(location::TMyPositionModeChanged const & fn); - void Render(ScreenBase const & screen, ref_ptr mng, + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); bool IsRotationAvailable() const { return m_isDirectionAssigned; } diff --git a/drape_frontend/path_symbol_shape.cpp b/drape_frontend/path_symbol_shape.cpp index 896b3b6c5a..8715588fce 100644 --- a/drape_frontend/path_symbol_shape.cpp +++ b/drape_frontend/path_symbol_shape.cpp @@ -40,7 +40,7 @@ void PathSymbolShape::Draw(ref_ptr batcher, ref_ptr textures, void PathTextShape::Draw(ref_ptr batcher, ref_ptr textures) const { - unique_ptr layout = make_unique(strings::MakeUniString(m_params.m_text), - m_params.m_textFont.m_size, textures); + auto layout = make_unique(m_params.m_tileCenter, strings::MakeUniString(m_params.m_text), + m_params.m_textFont.m_size, textures); uint32_t glyphCount = layout->GetGlyphCount(); if (glyphCount == 0) diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp index 46ab2394c0..8567d4e4f0 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -108,7 +108,8 @@ void PoiSymbolShape::Draw(ref_ptr batcher, ref_ptrGetSymbolRegion(m_params.m_symbolName, region); - glsl::vec4 const position = glsl::vec4(glsl::ToVec2(m_pt), m_params.m_depth, -m_params.m_posZ); + glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec4 const position = glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ); m2::PointU const pixelSize = region.GetPixelSize(); drape_ptr handle = make_unique_dp(m_params.m_id, diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index ffc8318b67..7cc96170f0 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -88,9 +88,15 @@ void RenderGroup::Render(ScreenBase const & screen) for(auto & renderBucket : m_renderBuckets) renderBucket->GetBuffer()->Build(shader); - auto const & params = df::VisualParams::Instance().GetGlyphVisualParams(); + // Set tile-based model-view matrix. + { + math::Matrix mv = GetTileKey().GetTileBasedModelView(screen); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + } + int programIndex = m_state.GetProgramIndex(); int program3dIndex = m_state.GetProgram3dIndex(); + auto const & params = df::VisualParams::Instance().GetGlyphVisualParams(); if (programIndex == gpu::TEXT_OUTLINED_PROGRAM || program3dIndex == gpu::TEXT_OUTLINED_BILLBOARD_PROGRAM) { @@ -215,6 +221,10 @@ void UserMarkRenderGroup::UpdateAnimation() void UserMarkRenderGroup::Render(ScreenBase const & screen) { BaseRenderGroup::Render(screen); + + math::Matrix mv = screen.GetModelView(); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + ref_ptr shader = screen.isPerspective() ? m_shader3d : m_shader; dp::ApplyUniforms(m_uniforms, shader); if (m_renderBucket != nullptr) diff --git a/drape_frontend/route_builder.cpp b/drape_frontend/route_builder.cpp index fbf06dcb0b..95946eb44f 100644 --- a/drape_frontend/route_builder.cpp +++ b/drape_frontend/route_builder.cpp @@ -23,6 +23,7 @@ void RouteBuilder::Build(m2::PolylineD const & routePolyline, vector con routeData->m_sourcePolyline = routePolyline; routeData->m_sourceTurns = turns; routeData->m_pattern = pattern; + routeData->m_pivot = routePolyline.GetLimitRect().Center(); RouteShape::CacheRoute(textures, *routeData.get()); m_routeCache.insert(make_pair(routeData->m_routeIndex, routePolyline)); @@ -63,6 +64,7 @@ void RouteBuilder::BuildArrows(int routeIndex, vector const & bord return; drape_ptr routeArrowsData = make_unique_dp(); + routeArrowsData->m_pivot = it->second.GetLimitRect().Center(); RouteShape::CacheRouteArrows(textures, it->second, borders, *routeArrowsData.get()); // Flush route arrows geometry. diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index f8c8866cd2..7c07b75c14 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -1,4 +1,5 @@ #include "drape_frontend/route_renderer.hpp" +#include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/message_subclasses.hpp" #include "drape/glsl_func.hpp" @@ -238,6 +239,8 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr mv = screen.GetModelView(m_routeData->m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); glsl::vec4 const color = glsl::ToVec4(df::GetColorConstant(GetStyleReader().GetCurrentStyle(), m_routeData->m_color)); uniforms.SetFloatValue("u_color", color.r, color.g, color.b, m_currentAlpha); @@ -269,6 +272,8 @@ void RouteRenderer::RenderRoute(ScreenBase const & screen, ref_ptr mv = screen.GetModelView(m_routeArrows->m_pivot, kShapeCoordScalar); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_arrowHalfWidth", m_currentHalfWidth * kArrowHeightFactor); uniforms.SetFloatValue("u_opacity", 1.0f); @@ -305,8 +310,9 @@ void RouteRenderer::RenderRouteSign(drape_ptr const & sign, Scree return; dp::GLState const & state = sign->m_sign.m_state; - dp::UniformValuesStorage uniforms = commonUniforms; + math::Matrix mv = screen.GetModelView(sign->m_position, 1.0); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); uniforms.SetFloatValue("u_opacity", 1.0f); ref_ptr program = screen.isPerspective() ? mng->GetProgram(state.GetProgram3dIndex()) diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 5acafd0e21..9954e098e7 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -1,5 +1,7 @@ #include "drape_frontend/route_shape.hpp" #include "drape_frontend/line_shape_helper.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape/attribute_provider.hpp" #include "drape/batcher.hpp" @@ -120,8 +122,9 @@ void GenerateArrowsTriangles(glsl::vec4 const & pivot, vector const } // namespace -void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffer & geometry, - TGeometryBuffer & joinsGeometry, double & outputLength) +void RouteShape::PrepareGeometry(vector const & path, m2::PointD const & pivot, + TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, + double & outputLength) { ASSERT(path.size() > 1, ()); @@ -139,8 +142,13 @@ void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffe (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - glsl::vec3 const startPivot = glsl::vec3(segments[i].m_points[StartPoint], kDepth); - glsl::vec3 const endPivot = glsl::vec3(segments[i].m_points[EndPoint], kDepth); + m2::PointD const startPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[EndPoint]), + pivot, kShapeCoordScalar); + + glsl::vec3 const startPivot = glsl::vec3(glsl::ToVec2(startPt), kDepth); + glsl::vec3 const endPivot = glsl::vec3(glsl::ToVec2(endPt), kDepth); float const endLength = length + glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); @@ -177,10 +185,11 @@ void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffe vector normals; normals.reserve(24); - GenerateJoinNormals(dp::RoundJoin, n1, n2, 1.0f, segments[i].m_hasLeftJoin[EndPoint], widthScalar, normals); + GenerateJoinNormals(dp::RoundJoin, n1, n2, 1.0f, segments[i].m_hasLeftJoin[EndPoint], + widthScalar, normals); - GenerateJoinsTriangles(glsl::vec3(segments[i].m_points[EndPoint], kDepth), normals, - glsl::vec2(endLength, 0), segments[i].m_hasLeftJoin[EndPoint], joinsGeometry); + GenerateJoinsTriangles(endPivot, normals, glsl::vec2(endLength, 0), + segments[i].m_hasLeftJoin[EndPoint], joinsGeometry); } // Generate caps. @@ -192,8 +201,7 @@ void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffe segments[i].m_rightNormals[StartPoint], -segments[i].m_tangent, 1.0f, true /* isStart */, normals); - GenerateJoinsTriangles(glsl::vec3(segments[i].m_points[StartPoint], kDepth), normals, - glsl::vec2(length, 0), true, joinsGeometry); + GenerateJoinsTriangles(startPivot, normals, glsl::vec2(length, 0), true, joinsGeometry); } if (i == segments.size() - 1) @@ -204,8 +212,7 @@ void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffe segments[i].m_rightNormals[EndPoint], segments[i].m_tangent, 1.0f, false /* isStart */, normals); - GenerateJoinsTriangles(glsl::vec3(segments[i].m_points[EndPoint], kDepth), normals, - glsl::vec2(endLength, 0), true, joinsGeometry); + GenerateJoinsTriangles(endPivot, normals, glsl::vec2(endLength, 0), true, joinsGeometry); } length = endLength; @@ -214,7 +221,8 @@ void RouteShape::PrepareGeometry(vector const & path, TGeometryBuffe outputLength = length; } -void RouteShape::PrepareArrowGeometry(vector const & path, m2::RectF const & texRect, float depth, +void RouteShape::PrepareArrowGeometry(vector const & path, m2::PointD const & pivot, + m2::RectF const & texRect, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry) { ASSERT(path.size() > 1, ()); @@ -240,8 +248,13 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::RectF (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - glsl::vec4 const startPivot = glsl::vec4(segments[i].m_points[StartPoint], depth, 1.0); - glsl::vec4 const endPivot = glsl::vec4(segments[i].m_points[EndPoint], depth, 1.0); + m2::PointD const startPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[EndPoint]), + pivot, kShapeCoordScalar); + + glsl::vec4 const startPivot = glsl::vec4(glsl::ToVec2(startPt), depth, 1.0); + glsl::vec4 const endPivot = glsl::vec4(glsl::ToVec2(endPt), depth, 1.0); float const endLength = length + glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); @@ -285,8 +298,7 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::RectF ASSERT_EQUAL(normals.size(), uv.size(), ()); - GenerateArrowsTriangles(glsl::vec4(segments[i].m_points[EndPoint], depth, 1.0), - normals, tr, uv, true /* normalizedUV */, joinsGeometry); + GenerateArrowsTriangles(endPivot, normals, tr, uv, true /* normalizedUV */, joinsGeometry); } // Generate arrow head. @@ -300,8 +312,7 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::RectF }; float const u = 1.0f - kArrowHeadSize; vector uv = { glsl::vec2(u, 1.0f), glsl::vec2(u, 0.0f), glsl::vec2(1.0f, 0.5f) }; - GenerateArrowsTriangles(glsl::vec4(segments[i].m_points[EndPoint], depth, 1.0), - normals, texRect, uv, true /* normalizedUV */, joinsGeometry); + GenerateArrowsTriangles(endPivot, normals, texRect, uv, true /* normalizedUV */, joinsGeometry); } // Generate arrow tail. @@ -325,8 +336,7 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::RectF glsl::ToVec2(t.LeftTop()) }; - GenerateArrowsTriangles(glsl::vec4(segments[i].m_points[StartPoint], depth, 1.0), - normals, texRect, uv, false /* normalizedUV */, joinsGeometry); + GenerateArrowsTriangles(startPivot, normals, texRect, uv, false /* normalizedUV */, joinsGeometry); } length = endLength; @@ -341,8 +351,7 @@ void RouteShape::CacheRouteSign(ref_ptr mng, RouteSignData & m2::RectF const & texRect = symbol.GetTexRect(); m2::PointF halfSize = m2::PointF(symbol.GetPixelSize()) * 0.5f; - glsl::vec2 const pos = glsl::ToVec2(routeSignData.m_position); - glsl::vec4 const pivot = glsl::vec4(pos.x, pos.y, 0.0f /* depth */, 0.0f /* pivot z */); + glsl::vec4 const pivot = glsl::vec4(0.0f /* x */, 0.0f /* y */, 0.0f /* depth */, 0.0f /* pivot z */); gpu::SolidTexturingVertex data[4]= { { pivot, glsl::vec2(-halfSize.x, halfSize.y), glsl::ToVec2(texRect.LeftTop()) }, @@ -389,7 +398,7 @@ void RouteShape::CacheRouteArrows(ref_ptr mng, m2::PolylineD { vector points = CalculatePoints(polyline, b.m_startDistance, b.m_endDistance); ASSERT_LESS_OR_EQUAL(points.size(), polyline.GetSize(), ()); - PrepareArrowGeometry(points, region.GetTexRect(), depth, geometry, joinsGeometry); + PrepareArrowGeometry(points, routeArrowsData.m_pivot, region.GetTexRect(), depth, geometry, joinsGeometry); depth += 1.0f; } @@ -402,7 +411,7 @@ void RouteShape::CacheRoute(ref_ptr textures, RouteData & ro { TGeometryBuffer geometry; TGeometryBuffer joinsGeometry; - PrepareGeometry(routeData.m_sourcePolyline.GetPoints(), + PrepareGeometry(routeData.m_sourcePolyline.GetPoints(), routeData.m_pivot, geometry, joinsGeometry, routeData.m_length); dp::GLState state = dp::GLState(gpu::ROUTE_PROGRAM, dp::GLState::GeometryLayer); diff --git a/drape_frontend/route_shape.hpp b/drape_frontend/route_shape.hpp index 21af6439fa..8495826f02 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -62,6 +62,7 @@ struct RouteData int m_routeIndex; m2::PolylineD m_sourcePolyline; vector m_sourceTurns; + m2::PointD m_pivot; df::ColorConstant m_color; double m_length; RouteRenderProperty m_route; @@ -79,6 +80,7 @@ struct RouteSignData struct RouteArrowsData { RouteRenderProperty m_arrows; + m2::PointD m_pivot; }; class RouteShape @@ -95,9 +97,11 @@ public: vector const & borders, RouteArrowsData & routeArrowsData); private: - static void PrepareGeometry(vector const & path, TGeometryBuffer & geometry, - TGeometryBuffer & joinsGeometry, double & outputLength); - static void PrepareArrowGeometry(vector const & path, m2::RectF const & texRect, float depth, + static void PrepareGeometry(vector const & path, m2::PointD const & pivot, + TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, + double & outputLength); + static void PrepareArrowGeometry(vector const & path, m2::PointD const & pivot, + m2::RectF const & texRect, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry); static void BatchGeometry(dp::GLState const & state, ref_ptr geometry, size_t geomSize, ref_ptr joinsGeometry, size_t joinsGeomSize, diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index 2a7a3a8102..e65a9eeabc 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -162,8 +162,8 @@ void RuleDrawer::operator()(FeatureType const & f) // highway-path-bridge and building (sic!) at the same time (pedestrian crossing). is3dBuilding = (ftypes::IsBuildingChecker::Instance()(f) || ftypes::IsBuildingPartChecker::Instance()(f)) && - !ftypes::IsBridgeChecker::Instance()(f) && - !ftypes::IsTunnelChecker::Instance()(f); + !ftypes::IsBridgeChecker::Instance()(f) && + !ftypes::IsTunnelChecker::Instance()(f); } m2::PointD featureCenter; @@ -220,8 +220,9 @@ void RuleDrawer::operator()(FeatureType const & f) if (applyPointStyle || is3dBuilding) minVisibleScale = feature::GetMinDrawableScale(f); - ApplyAreaFeature apply(insertShape, f.GetID(), m_globalRect, areaMinHeight, areaHeight, - minVisibleScale, f.GetRank(), s.GetCaptionDescription()); + ApplyAreaFeature apply(m_globalRect.Center(), insertShape, f.GetID(), m_globalRect, + areaMinHeight, areaHeight, minVisibleScale, f.GetRank(), + s.GetCaptionDescription()); f.ForEachTriangle(apply, zoomLevel); apply.SetHotelData(ExtractHotelData(f)); if (applyPointStyle) @@ -235,8 +236,9 @@ void RuleDrawer::operator()(FeatureType const & f) } else if (s.LineStyleExists()) { - ApplyLineFeature apply(insertShape, f.GetID(), m_globalRect, minVisibleScale, f.GetRank(), - s.GetCaptionDescription(), m_currentScaleGtoP, + ApplyLineFeature apply(m_globalRect.Center(), m_currentScaleGtoP, + insertShape, f.GetID(), m_globalRect, minVisibleScale, + f.GetRank(), s.GetCaptionDescription(), zoomLevel >= kLineSimplifyLevelStart && zoomLevel <= kLineSimplifyLevelEnd, f.GetPointsCount()); f.ForEachPoint(apply, zoomLevel); @@ -253,7 +255,7 @@ void RuleDrawer::operator()(FeatureType const & f) ASSERT(s.PointStyleExists(), ()); minVisibleScale = feature::GetMinDrawableScale(f); - ApplyPointFeature apply(insertShape, f.GetID(), minVisibleScale, f.GetRank(), + ApplyPointFeature apply(m_globalRect.Center(), insertShape, f.GetID(), minVisibleScale, f.GetRank(), s.GetCaptionDescription(), 0.0f /* posZ */); apply.SetHotelData(ExtractHotelData(f)); f.ForEachPoint([&apply](m2::PointD const & pt) { apply(pt, false /* hasArea */); }, zoomLevel); @@ -277,6 +279,7 @@ void RuleDrawer::operator()(FeatureType const & f) m2::SharedSpline spline(path); df::LineViewParams p; + p.m_tileCenter = m_globalRect.Center(); p.m_baseGtoPScale = 1.0; p.m_cap = dp::ButtCap; p.m_color = dp::Color::Red(); @@ -287,6 +290,7 @@ void RuleDrawer::operator()(FeatureType const & f) insertShape(make_unique_dp(spline, p)); df::TextViewParams tp; + tp.m_tileCenter = m_globalRect.Center(); tp.m_anchor = dp::Center; tp.m_depth = 20000; tp.m_primaryText = strings::to_string(key.m_x) + " " + diff --git a/drape_frontend/selection_shape.cpp b/drape_frontend/selection_shape.cpp index dd5a6ebb4d..224ab48197 100644 --- a/drape_frontend/selection_shape.cpp +++ b/drape_frontend/selection_shape.cpp @@ -1,5 +1,8 @@ #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/color_constants.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/attribute_provider.hpp" @@ -125,7 +128,7 @@ void SelectionShape::Hide() m_selectedObject = OBJECT_EMPTY; } -void SelectionShape::Render(ScreenBase const & screen, ref_ptr mng, +void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms) { ShowHideAnimation::EState state = m_animation.GetState(); @@ -133,7 +136,12 @@ void SelectionShape::Render(ScreenBase const & screen, ref_ptr mv = key.GetTileBasedModelView(screen); + uniforms.SetMatrix4x4Value("modelView", mv.m_data); + + m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + uniforms.SetFloatValue("u_position", pos.x, pos.y, -m_positionZ); float accuracy = m_mapping.GetValue(m_animation.GetT()); if (screen.isPerspective()) diff --git a/drape_frontend/selection_shape.hpp b/drape_frontend/selection_shape.hpp index 8eab71f90e..3f47a10c3a 100644 --- a/drape_frontend/selection_shape.hpp +++ b/drape_frontend/selection_shape.hpp @@ -35,8 +35,7 @@ public: void SetPosition(m2::PointD const & position) { m_position = position; } void Show(ESelectedObject obj, m2::PointD const & position, double positionZ, bool isAnimate); void Hide(); - void Render(ScreenBase const & screen, - ref_ptr mng, + void Render(ScreenBase const & screen, int zoomLevel, ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); ESelectedObject GetSelectedObject() const; diff --git a/drape_frontend/shape_view_params.hpp b/drape_frontend/shape_view_params.hpp index be8eea5fd8..51036d8eac 100644 --- a/drape_frontend/shape_view_params.hpp +++ b/drape_frontend/shape_view_params.hpp @@ -12,11 +12,14 @@ namespace df { +double const kShapeCoordScalar = 1000; + struct CommonViewParams { float m_depth = 0.0f; int m_minVisibleScale = 0; uint8_t m_rank = 0; + m2::PointD m_tileCenter; }; struct PoiSymbolViewParams : CommonViewParams diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp index d38f88f380..545dfa3878 100644 --- a/drape_frontend/text_layout.cpp +++ b/drape_frontend/text_layout.cpp @@ -1,6 +1,5 @@ #include "drape_frontend/text_layout.hpp" -#include "drape_frontend/visual_params.hpp" - +#include "drape_frontend/map_shape.hpp" #include "drape_frontend/visual_params.hpp" #include "drape/fribidi.hpp" @@ -436,8 +435,9 @@ void StraightTextLayout::Cache(glm::vec4 const & pivot, glm::vec2 const & pixelO } } -PathTextLayout::PathTextLayout(strings::UniString const & text, float fontSize, - ref_ptr textures) +PathTextLayout::PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text, + float fontSize, ref_ptr textures) + : m_tileCenter(tileCenter) { Init(fribidi::log2vis(text), fontSize, textures); } @@ -481,6 +481,8 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo glsl::vec2 pxPivot = glsl::ToVec2(iter.m_pos); buffer.resize(4 * m_metrics.size()); + + glsl::vec4 const pivot(glsl::ToVec2(MapShape::ConvertPt(globalPivot, m_tileCenter, kShapeCoordScalar)), depth, 0.0f); for (size_t i = 0; i < m_metrics.size(); ++i) { GlyphRegion const & g = m_metrics[i]; @@ -501,7 +503,6 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo size_t baseIndex = 4 * i; - glsl::vec4 pivot(glsl::ToVec2(globalPivot), depth, 0.0f); buffer[baseIndex + 0] = gpu::TextDynamicVertex(pivot, formingVector + normal * bottomVector + tangent * xOffset); buffer[baseIndex + 1] = gpu::TextDynamicVertex(pivot, formingVector + normal * upVector + tangent * xOffset); buffer[baseIndex + 2] = gpu::TextDynamicVertex(pivot, formingVector + normal * bottomVector + tangent * (pxSize.x + xOffset)); diff --git a/drape_frontend/text_layout.hpp b/drape_frontend/text_layout.hpp index 41edeca819..9b11365ba2 100644 --- a/drape_frontend/text_layout.hpp +++ b/drape_frontend/text_layout.hpp @@ -55,7 +55,7 @@ protected: class StraightTextLayout : public TextLayout { - typedef TextLayout TBase; + using TBase = TextLayout; public: StraightTextLayout(strings::UniString const & text, float fontSize, @@ -82,9 +82,9 @@ private: class PathTextLayout : public TextLayout { - typedef TextLayout TBase; + using TBase = TextLayout; public: - PathTextLayout(strings::UniString const & text, + PathTextLayout(m2::PointD const & tileCenter, strings::UniString const & text, float fontSize, ref_ptr textures); void CacheStaticGeometry(dp::TextureManager::ColorRegion const & colorRegion, @@ -107,6 +107,8 @@ public: private: static float CalculateTextLength(float textPixelLength); + + m2::PointD m_tileCenter; }; class SharedTextLayout diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp index 7da84dda33..b1bcee28c6 100644 --- a/drape_frontend/text_shape.cpp +++ b/drape_frontend/text_shape.cpp @@ -197,7 +197,8 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - layout.Cache(glsl::vec4(glsl::ToVec2(m_basePoint), m_params.m_depth, -m_params.m_posZ), + glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ), baseOffset, color, staticBuffer, dynamicBuffer); dp::GLState state(gpu::TEXT_PROGRAM, dp::GLState::OverlayLayer); @@ -244,7 +245,8 @@ void TextShape::DrawSubStringOutlined(StraightTextLayout const & layout, dp::Fon textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - layout.Cache(glsl::vec4(glsl::ToVec2(m_basePoint), m_params.m_depth, -m_params.m_posZ), + glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ), baseOffset, color, outline, staticBuffer, dynamicBuffer); dp::GLState state(gpu::TEXT_OUTLINED_PROGRAM, dp::GLState::OverlayLayer); diff --git a/drape_frontend/tile_key.cpp b/drape_frontend/tile_key.cpp index 106795ce63..2449960f15 100755 --- a/drape_frontend/tile_key.cpp +++ b/drape_frontend/tile_key.cpp @@ -1,4 +1,6 @@ #include "drape_frontend/tile_key.hpp" + +#include "drape_frontend/shape_view_params.hpp" #include "drape_frontend/tile_utils.hpp" #include "indexer/scales.hpp" @@ -80,6 +82,11 @@ m2::RectD TileKey::GetGlobalRect(bool clipByDataMaxZoom) const return m2::RectD (startX, startY, startX + rectSize, startY + rectSize); } +math::Matrix TileKey::GetTileBasedModelView(ScreenBase const & screen) const +{ + return screen.GetModelView(GetGlobalRect().Center(), kShapeCoordScalar); +} + string DebugPrint(TileKey const & key) { ostringstream out; diff --git a/drape_frontend/tile_key.hpp b/drape_frontend/tile_key.hpp index b9a2de9395..9818728d4e 100755 --- a/drape_frontend/tile_key.hpp +++ b/drape_frontend/tile_key.hpp @@ -1,6 +1,9 @@ #pragma once #include "geometry/rect2d.hpp" +#include "geometry/screenbase.hpp" + +#include "base/matrix.hpp" namespace df { @@ -24,6 +27,8 @@ struct TileKey m2::RectD GetGlobalRect(bool clipByDataMaxZoom = true) const; + math::Matrix GetTileBasedModelView(ScreenBase const & screen) const; + int m_x; int m_y; int m_zoomLevel; diff --git a/drape_frontend/tile_utils.cpp b/drape_frontend/tile_utils.cpp index 45853f459f..2496103581 100755 --- a/drape_frontend/tile_utils.cpp +++ b/drape_frontend/tile_utils.cpp @@ -46,4 +46,13 @@ int ClipTileZoomByMaxDataZoom(int zoom) return zoom <= upperScale ? zoom : upperScale; } +TileKey GetTileKeyByPoint(m2::PointD const & pt, int zoom) +{ + ASSERT_GREATER(zoom, 0, ()); + double const range = MercatorBounds::maxX - MercatorBounds::minX; + double const rectSize = range / (1 << (zoom - 1)); + return TileKey(static_cast(floor(pt.x / rectSize)), + static_cast(floor(pt.y / rectSize)), zoom); +} + } // namespace df diff --git a/drape_frontend/tile_utils.hpp b/drape_frontend/tile_utils.hpp index eb23761279..c6a098ceb7 100755 --- a/drape_frontend/tile_utils.hpp +++ b/drape_frontend/tile_utils.hpp @@ -28,4 +28,7 @@ bool IsNeighbours(TileKey const & tileKey1, TileKey const & tileKey2); /// This function performs clipping by maximum zoom label available for map data. int ClipTileZoomByMaxDataZoom(int zoom); +/// This function returns tile key by point on specific zoom level. +TileKey GetTileKeyByPoint(m2::PointD const & pt, int zoom); + } // namespace df -- cgit v1.2.3