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>2017-06-09 10:50:30 +0300
committerGitHub <noreply@github.com>2017-06-09 10:50:30 +0300
commit899a7f38782bd128996e39cbd23c7a48f9c8f181 (patch)
tree4bb26f27aba2557865829d9bd3035c59cc916b21 /drape_frontend
parentce1d8aeae3ac9b8e5c75951fedc827ee5f7df52f (diff)
parentef54fe571f46bbdea2120f2da86b43902dfffd3e (diff)
Merge pull request #6217 from rokuz/route-preview
Added route preview
Diffstat (limited to 'drape_frontend')
-rw-r--r--drape_frontend/CMakeLists.txt8
-rw-r--r--drape_frontend/apply_feature_functors.cpp1
-rw-r--r--drape_frontend/backend_renderer.cpp17
-rw-r--r--drape_frontend/circles_pack_shape.cpp175
-rw-r--r--drape_frontend/circles_pack_shape.hpp (renamed from drape_frontend/gps_track_shape.hpp)37
-rw-r--r--drape_frontend/drape_engine.cpp30
-rw-r--r--drape_frontend/drape_engine.hpp5
-rwxr-xr-xdrape_frontend/drape_frontend.pro8
-rwxr-xr-xdrape_frontend/frontend_renderer.cpp81
-rwxr-xr-xdrape_frontend/frontend_renderer.hpp2
-rw-r--r--drape_frontend/gps_track_point.hpp4
-rw-r--r--drape_frontend/gps_track_renderer.cpp83
-rw-r--r--drape_frontend/gps_track_renderer.hpp26
-rw-r--r--drape_frontend/gps_track_shape.cpp178
-rw-r--r--drape_frontend/message.hpp7
-rw-r--r--drape_frontend/message_subclasses.hpp135
-rw-r--r--drape_frontend/route_renderer.cpp253
-rw-r--r--drape_frontend/route_renderer.hpp42
-rw-r--r--drape_frontend/shaders/circle_point.fsh.glsl (renamed from drape_frontend/shaders/trackpoint.fsh.glsl)0
-rw-r--r--drape_frontend/shaders/circle_point.vsh.glsl (renamed from drape_frontend/shaders/trackpoint.vsh.glsl)0
-rw-r--r--drape_frontend/shaders/shader_index.txt2
-rw-r--r--drape_frontend/traffic_renderer.cpp61
-rw-r--r--drape_frontend/traffic_renderer.hpp8
-rw-r--r--drape_frontend/visual_params.cpp17
-rw-r--r--drape_frontend/visual_params.hpp2
25 files changed, 775 insertions, 407 deletions
diff --git a/drape_frontend/CMakeLists.txt b/drape_frontend/CMakeLists.txt
index 7b3f68f7bc..4e34f3aad6 100644
--- a/drape_frontend/CMakeLists.txt
+++ b/drape_frontend/CMakeLists.txt
@@ -66,6 +66,8 @@ set(
batch_merge_helper.cpp
batch_merge_helper.hpp
batchers_pool.hpp
+ circles_pack_shape.cpp
+ circles_pack_shape.hpp
color_constants.cpp
color_constants.hpp
colored_symbol_shape.cpp
@@ -89,8 +91,6 @@ set(
gps_track_point.hpp
gps_track_renderer.cpp
gps_track_renderer.hpp
- gps_track_shape.cpp
- gps_track_shape.hpp
gui/choose_position_mark.cpp
gui/choose_position_mark.hpp
gui/compass.cpp
@@ -250,6 +250,8 @@ set(
shaders/arrow3d_shadow.vsh.glsl
shaders/circle.fsh.glsl
shaders/circle.vsh.glsl
+ shaders/circle_point.fsh.glsl
+ shaders/circle_point.vsh.glsl
shaders/colored_symbol.fsh.glsl
shaders/colored_symbol.vsh.glsl
shaders/colored_symbol_billboard.vsh.glsl
@@ -295,8 +297,6 @@ set(
shaders/texturing3d.fsh.glsl
shaders/texturing_billboard.vsh.glsl
shaders/texturing_gui.vsh.glsl
- shaders/trackpoint.fsh.glsl
- shaders/trackpoint.vsh.glsl
shaders/traffic.fsh.glsl
shaders/traffic.vsh.glsl
shaders/traffic_line.fsh.glsl
diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp
index 3060676315..ee8af08d56 100644
--- a/drape_frontend/apply_feature_functors.cpp
+++ b/drape_frontend/apply_feature_functors.cpp
@@ -434,7 +434,6 @@ void ApplyPointFeature::ProcessRule(Stylist::TRuleWrapper const & rule)
m_symbolRule = symRule;
}
- bool const hasPOI = m_symbolRule != nullptr;
bool const isNode = (pRule->GetType() & drule::node) != 0;
CaptionDefProto const * capRule = pRule->GetCaption(0);
if (capRule && isNode)
diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp
index 5f4bc53bb2..ad0065c1a8 100644
--- a/drape_frontend/backend_renderer.cpp
+++ b/drape_frontend/backend_renderer.cpp
@@ -2,9 +2,9 @@
#include "drape_frontend/backend_renderer.hpp"
#include "drape_frontend/batchers_pool.hpp"
+#include "drape_frontend/circles_pack_shape.hpp"
#include "drape_frontend/drape_api_builder.hpp"
#include "drape_frontend/drape_measurer.hpp"
-#include "drape_frontend/gps_track_shape.hpp"
#include "drape_frontend/map_shape.hpp"
#include "drape_frontend/message_subclasses.hpp"
#include "drape_frontend/read_manager.hpp"
@@ -12,10 +12,10 @@
#include "drape_frontend/user_mark_shapes.hpp"
#include "drape_frontend/visual_params.hpp"
-#include "indexer/scales.hpp"
-
#include "drape/texture_manager.hpp"
+#include "indexer/scales.hpp"
+
#include "platform/platform.hpp"
#include "base/logging.hpp"
@@ -303,14 +303,15 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
- case Message::CacheGpsTrackPoints:
+ case Message::CacheCirclesPack:
{
- ref_ptr<CacheGpsTrackPointsMessage> msg = message;
- drape_ptr<GpsTrackRenderData> data = make_unique_dp<GpsTrackRenderData>();
+ ref_ptr<CacheCirclesPackMessage> msg = message;
+ drape_ptr<CirclesPackRenderData> data = make_unique_dp<CirclesPackRenderData>();
data->m_pointsCount = msg->GetPointsCount();
- GpsTrackShape::Draw(m_texMng, *data.get());
+ CirclesPackShape::Draw(m_texMng, *data.get());
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
- make_unique_dp<FlushGpsTrackPointsMessage>(move(data)),
+ make_unique_dp<FlushCirclesPackMessage>(
+ std::move(data), msg->GetDestination()),
MessagePriority::Normal);
break;
}
diff --git a/drape_frontend/circles_pack_shape.cpp b/drape_frontend/circles_pack_shape.cpp
new file mode 100644
index 0000000000..5f4366d030
--- /dev/null
+++ b/drape_frontend/circles_pack_shape.cpp
@@ -0,0 +1,175 @@
+#include "drape_frontend/circles_pack_shape.hpp"
+#include "drape_frontend/shader_def.hpp"
+
+#include "drape/attribute_provider.hpp"
+#include "drape/batcher.hpp"
+#include "drape/glsl_func.hpp"
+#include "drape/glsl_types.hpp"
+#include "drape/texture_manager.hpp"
+
+namespace df
+{
+namespace
+{
+uint32_t const kDynamicStreamID = 0x7F;
+
+struct CirclesPackStaticVertex
+{
+ using TNormal = glsl::vec3;
+
+ CirclesPackStaticVertex() = default;
+ CirclesPackStaticVertex(TNormal const & normal) : m_normal(normal) {}
+
+ TNormal m_normal;
+};
+
+dp::GLState GetCirclesPackState(ref_ptr<dp::TextureManager> texMng)
+{
+ dp::GLState state(gpu::CIRCLE_POINT_PROGRAM, dp::GLState::OverlayLayer);
+ state.SetColorTexture(texMng->GetSymbolsTexture());
+ return state;
+}
+
+dp::BindingInfo const & GetCirclesPackStaticBindingInfo()
+{
+ static unique_ptr<dp::BindingInfo> s_info;
+ if (s_info == nullptr)
+ {
+ dp::BindingFiller<CirclesPackStaticVertex> filler(1);
+ filler.FillDecl<CirclesPackStaticVertex::TNormal>("a_normal");
+ s_info.reset(new dp::BindingInfo(filler.m_info));
+ }
+ return *s_info;
+}
+
+dp::BindingInfo const & GetCirclesPackDynamicBindingInfo()
+{
+ static unique_ptr<dp::BindingInfo> s_info;
+ if (s_info == nullptr)
+ {
+ dp::BindingFiller<CirclesPackDynamicVertex> filler(2, kDynamicStreamID);
+ filler.FillDecl<CirclesPackDynamicVertex::TPosition>("a_position");
+ filler.FillDecl<CirclesPackDynamicVertex::TColor>("a_color");
+ s_info.reset(new dp::BindingInfo(filler.m_info));
+ }
+ return *s_info;
+}
+} // namespace
+
+CirclesPackHandle::CirclesPackHandle(size_t pointsCount)
+ : OverlayHandle(FeatureID(), dp::Anchor::Center, 0, false)
+ , m_needUpdate(false)
+{
+ m_buffer.resize(pointsCount * dp::Batcher::VertexPerQuad);
+}
+
+void CirclesPackHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const
+{
+ if (!m_needUpdate)
+ return;
+
+ TOffsetNode const & node = GetOffsetNode(kDynamicStreamID);
+ ASSERT(node.first.GetElementSize() == sizeof(CirclesPackDynamicVertex), ());
+ ASSERT(node.second.m_count == m_buffer.size(), ());
+
+ uint32_t const byteCount =
+ static_cast<uint32_t>(m_buffer.size()) * sizeof(CirclesPackDynamicVertex);
+ void * buffer = mutator->AllocateMutationBuffer(byteCount);
+ memcpy(buffer, m_buffer.data(), byteCount);
+
+ dp::MutateNode mutateNode;
+ mutateNode.m_region = node.second;
+ mutateNode.m_data = make_ref(buffer);
+ mutator->AddMutation(node.first, mutateNode);
+
+ m_needUpdate = false;
+}
+
+bool CirclesPackHandle::Update(ScreenBase const & screen)
+{
+ UNUSED_VALUE(screen);
+ return true;
+}
+
+bool CirclesPackHandle::IndexesRequired() const { return false; }
+
+m2::RectD CirclesPackHandle::GetPixelRect(ScreenBase const & screen, bool perspective) const
+{
+ UNUSED_VALUE(screen);
+ UNUSED_VALUE(perspective);
+ return m2::RectD();
+}
+
+void CirclesPackHandle::GetPixelShape(ScreenBase const & screen, bool perspective,
+ Rects & rects) const
+{
+ UNUSED_VALUE(screen);
+ UNUSED_VALUE(perspective);
+}
+
+void CirclesPackHandle::SetPoint(size_t index, m2::PointD const & position, float radius,
+ dp::Color const & color)
+{
+ size_t bufferIndex = index * dp::Batcher::VertexPerQuad;
+ ASSERT_GREATER_OR_EQUAL(bufferIndex, 0, ());
+ ASSERT_LESS(bufferIndex, m_buffer.size(), ());
+
+ for (size_t i = 0; i < dp::Batcher::VertexPerQuad; i++)
+ {
+ m_buffer[bufferIndex + i].m_position = glsl::vec3(position.x, position.y, radius);
+ m_buffer[bufferIndex + i].m_color = glsl::ToVec4(color);
+ }
+ m_needUpdate = true;
+}
+
+void CirclesPackHandle::Clear()
+{
+ memset(m_buffer.data(), 0, m_buffer.size() * sizeof(CirclesPackDynamicVertex));
+ m_needUpdate = true;
+}
+
+size_t CirclesPackHandle::GetPointsCount() const
+{
+ return m_buffer.size() / dp::Batcher::VertexPerQuad;
+}
+
+void CirclesPackShape::Draw(ref_ptr<dp::TextureManager> texMng, CirclesPackRenderData & data)
+{
+ ASSERT_NOT_EQUAL(data.m_pointsCount, 0, ());
+
+ uint32_t const kVerticesInPoint = dp::Batcher::VertexPerQuad;
+ uint32_t const kIndicesInPoint = dp::Batcher::IndexPerQuad;
+ std::vector<CirclesPackStaticVertex> staticVertexData;
+ staticVertexData.reserve(data.m_pointsCount * kVerticesInPoint);
+ for (size_t i = 0; i < data.m_pointsCount; i++)
+ {
+ staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(-1.0f, 1.0f, 1.0f));
+ staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(-1.0f, -1.0f, 1.0f));
+ staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(1.0f, 1.0f, 1.0f));
+ staticVertexData.emplace_back(CirclesPackStaticVertex::TNormal(1.0f, -1.0f, 1.0f));
+ }
+
+ std::vector<CirclesPackDynamicVertex> dynamicVertexData;
+ dynamicVertexData.resize(data.m_pointsCount * kVerticesInPoint);
+
+ dp::Batcher batcher(data.m_pointsCount * kIndicesInPoint, data.m_pointsCount * kVerticesInPoint);
+ dp::SessionGuard guard(batcher, [&data](dp::GLState const & state, drape_ptr<dp::RenderBucket> && b)
+ {
+ data.m_bucket = std::move(b);
+ data.m_state = state;
+ });
+
+ drape_ptr<dp::OverlayHandle> handle = make_unique_dp<CirclesPackHandle>(data.m_pointsCount);
+
+ dp::AttributeProvider provider(2 /* stream count */,
+ static_cast<uint32_t>(staticVertexData.size()));
+ provider.InitStream(0 /* stream index */, GetCirclesPackStaticBindingInfo(),
+ make_ref(staticVertexData.data()));
+ provider.InitStream(1 /* stream index */, GetCirclesPackDynamicBindingInfo(),
+ make_ref(dynamicVertexData.data()));
+ batcher.InsertListOfStrip(GetCirclesPackState(texMng), make_ref(&provider), std::move(handle),
+ kVerticesInPoint);
+
+ GLFunctions::glFlush();
+}
+} // namespace df
diff --git a/drape_frontend/gps_track_shape.hpp b/drape_frontend/circles_pack_shape.hpp
index 6a19bbadfb..bc820292f0 100644
--- a/drape_frontend/gps_track_shape.hpp
+++ b/drape_frontend/circles_pack_shape.hpp
@@ -4,51 +4,49 @@
#include "drape_frontend/shape_view_params.hpp"
#include "drape/glstate.hpp"
-#include "drape/render_bucket.hpp"
-#include "drape/utils/vertex_decl.hpp"
#include "drape/overlay_handle.hpp"
#include "drape/pointers.hpp"
+#include "drape/render_bucket.hpp"
+#include "drape/utils/vertex_decl.hpp"
-#include "std/vector.hpp"
+#include <vector>
namespace dp
{
- class TextureManager;
-}
+class TextureManager;
+} // namespace dp
namespace df
{
-
-struct GpsTrackRenderData
+struct CirclesPackRenderData
{
uint32_t m_pointsCount;
dp::GLState m_state;
drape_ptr<dp::RenderBucket> m_bucket;
- GpsTrackRenderData() : m_pointsCount(0), m_state(0, dp::GLState::OverlayLayer) {}
+ CirclesPackRenderData() : m_pointsCount(0), m_state(0, dp::GLState::OverlayLayer) {}
};
-struct GpsTrackDynamicVertex
+struct CirclesPackDynamicVertex
{
using TPosition = glsl::vec3;
using TColor = glsl::vec4;
- GpsTrackDynamicVertex() = default;
- GpsTrackDynamicVertex(TPosition const & pos, TColor const & color)
- : m_position(pos)
- , m_color(color)
+ CirclesPackDynamicVertex() = default;
+ CirclesPackDynamicVertex(TPosition const & pos, TColor const & color)
+ : m_position(pos), m_color(color)
{}
TPosition m_position;
TColor m_color;
};
-class GpsTrackHandle : public dp::OverlayHandle
+class CirclesPackHandle : public dp::OverlayHandle
{
using TBase = dp::OverlayHandle;
public:
- GpsTrackHandle(size_t pointsCount);
+ CirclesPackHandle(size_t pointsCount);
void GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const override;
bool Update(ScreenBase const & screen) override;
m2::RectD GetPixelRect(ScreenBase const & screen, bool perspective) const override;
@@ -60,14 +58,13 @@ public:
size_t GetPointsCount() const;
private:
- vector<GpsTrackDynamicVertex> m_buffer;
+ std::vector<CirclesPackDynamicVertex> m_buffer;
mutable bool m_needUpdate;
};
-class GpsTrackShape
+class CirclesPackShape
{
public:
- static void Draw(ref_ptr<dp::TextureManager> texMng, GpsTrackRenderData & data);
+ static void Draw(ref_ptr<dp::TextureManager> texMng, CirclesPackRenderData & data);
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp
index 14d2eb5b5b..3ad284934e 100644
--- a/drape_frontend/drape_engine.cpp
+++ b/drape_frontend/drape_engine.cpp
@@ -444,6 +444,36 @@ void DrapeEngine::DeactivateRouteFollowing()
MessagePriority::Normal);
}
+void DrapeEngine::SetRouteSegmentVisibility(dp::DrapeID segmentId, bool isVisible)
+{
+ m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<SetRouteSegmentVisibilityMessage>(segmentId, isVisible),
+ MessagePriority::Normal);
+}
+
+dp::DrapeID DrapeEngine::AddRoutePreviewSegment(m2::PointD const & startPt, m2::PointD const & finishPt)
+{
+ dp::DrapeID const id = GenerateDrapeID();
+ m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<AddRoutePreviewSegmentMessage>(id, startPt, finishPt),
+ MessagePriority::Normal);
+ return id;
+}
+
+void DrapeEngine::RemoveRoutePreviewSegment(dp::DrapeID segmentId)
+{
+ m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<RemoveRoutePreviewSegmentMessage>(segmentId),
+ MessagePriority::Normal);
+}
+
+void DrapeEngine::RemoveAllRoutePreviewSegments()
+{
+ m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<RemoveRoutePreviewSegmentMessage>(),
+ MessagePriority::Normal);
+}
+
void DrapeEngine::SetWidgetLayout(gui::TWidgetsLayoutInfo && info)
{
m_widgetsLayout = std::move(info);
diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp
index 10c0dd8cb6..b6c52bc969 100644
--- a/drape_frontend/drape_engine.hpp
+++ b/drape_frontend/drape_engine.hpp
@@ -161,9 +161,12 @@ public:
dp::DrapeID AddRouteSegment(drape_ptr<RouteSegment> && segment);
void RemoveRouteSegment(dp::DrapeID segmentId, bool deactivateFollowing);
-
void FollowRoute(int preferredZoomLevel, int preferredZoomLevel3d, bool enableAutoZoom);
void DeactivateRouteFollowing();
+ void SetRouteSegmentVisibility(dp::DrapeID segmentId, bool isVisible);
+ dp::DrapeID AddRoutePreviewSegment(m2::PointD const & startPt, m2::PointD const & finishPt);
+ void RemoveRoutePreviewSegment(dp::DrapeID segmentId);
+ void RemoveAllRoutePreviewSegments();
void SetWidgetLayout(gui::TWidgetsLayoutInfo && info);
diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro
index 51077eb59f..da8970357d 100755
--- a/drape_frontend/drape_frontend.pro
+++ b/drape_frontend/drape_frontend.pro
@@ -47,6 +47,7 @@ SOURCES += \
backend_renderer.cpp \
base_renderer.cpp \
batch_merge_helper.cpp \
+ circles_pack_shape.cpp \
color_constants.cpp \
colored_symbol_shape.cpp \
drape_api.cpp \
@@ -57,7 +58,6 @@ SOURCES += \
engine_context.cpp \
frontend_renderer.cpp \
gps_track_renderer.cpp \
- gps_track_shape.cpp \
line_shape.cpp \
line_shape_helper.cpp \
map_data_provider.cpp \
@@ -149,6 +149,7 @@ HEADERS += \
base_renderer.hpp \
batchers_pool.hpp \
batch_merge_helper.hpp \
+ circles_pack_shape.hpp \
color_constants.hpp \
colored_symbol_shape.hpp \
custom_symbol.hpp \
@@ -162,7 +163,6 @@ HEADERS += \
frontend_renderer.hpp \
gps_track_point.hpp \
gps_track_renderer.hpp \
- gps_track_shape.hpp \
intrusive_vector.hpp \
line_shape.hpp \
line_shape_helper.hpp \
@@ -243,6 +243,8 @@ OTHER_FILES += \
shaders/arrow3d_shadow.vsh.glsl \
shaders/circle.fsh.glsl \
shaders/circle.vsh.glsl \
+ shaders/circle_point.fsh.glsl \
+ shaders/circle_point.vsh.glsl \
shaders/colored_symbol.fsh.glsl \
shaders/colored_symbol.vsh.glsl \
shaders/colored_symbol_billboard.vsh.glsl \
@@ -288,8 +290,6 @@ OTHER_FILES += \
shaders/texturing3d.fsh.glsl \
shaders/texturing_billboard.vsh.glsl \
shaders/texturing_gui.vsh.glsl \
- shaders/trackpoint.fsh.glsl \
- shaders/trackpoint.vsh.glsl \
shaders/traffic.fsh.glsl \
shaders/traffic.vsh.glsl \
shaders/traffic_line.fsh.glsl \
diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp
index 8d93e0bbe7..c086380798 100755
--- a/drape_frontend/frontend_renderer.cpp
+++ b/drape_frontend/frontend_renderer.cpp
@@ -113,10 +113,7 @@ struct RemoveTilePredicate
FrontendRenderer::FrontendRenderer(Params && params)
: BaseRenderer(ThreadsCommutator::RenderThread, params)
, m_gpuProgramManager(new dp::GpuProgramManager())
- , m_routeRenderer(new RouteRenderer())
, m_trafficRenderer(new TrafficRenderer())
- , m_gpsTrackRenderer(
- new GpsTrackRenderer(std::bind(&FrontendRenderer::PrepareGpsTrackPoints, this, _1)))
, m_drapeApiRenderer(new DrapeApiRenderer())
, m_overlayTree(new dp::OverlayTree())
, m_enablePerspectiveInNavigation(false)
@@ -147,7 +144,23 @@ FrontendRenderer::FrontendRenderer(Params && params)
ASSERT(m_tapEventInfoFn, ());
ASSERT(m_userPositionChangedFn, ());
- m_myPositionController.reset(new MyPositionController(std::move(params.m_myPositionParams)));
+ m_gpsTrackRenderer = make_unique_dp<GpsTrackRenderer>([this](size_t pointsCount)
+ {
+ m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
+ make_unique_dp<CacheCirclesPackMessage>(
+ pointsCount, CacheCirclesPackMessage::GpsTrack),
+ MessagePriority::Normal);
+ });
+
+ m_routeRenderer = make_unique_dp<RouteRenderer>([this](size_t pointsCount)
+ {
+ m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
+ make_unique_dp<CacheCirclesPackMessage>(
+ pointsCount, CacheCirclesPackMessage::RoutePreview),
+ MessagePriority::Normal);
+ });
+
+ m_myPositionController = make_unique_dp<MyPositionController>(std::move(params.m_myPositionParams));
for (auto const & effect : params.m_enabledEffects)
m_postprocessRenderer->SetEffectEnabled(effect, true /* enabled */);
@@ -542,6 +555,33 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
+ case Message::AddRoutePreviewSegment:
+ {
+ ref_ptr<AddRoutePreviewSegmentMessage> const msg = message;
+ RouteRenderer::PreviewInfo info;
+ info.m_startPoint = msg->GetStartPoint();
+ info.m_finishPoint = msg->GetFinishPoint();
+ m_routeRenderer->AddPreviewSegment(msg->GetSegmentId(), std::move(info));
+ break;
+ }
+
+ case Message::RemoveRoutePreviewSegment:
+ {
+ ref_ptr<RemoveRoutePreviewSegmentMessage> const msg = message;
+ if (msg->NeedRemoveAll())
+ m_routeRenderer->RemoveAllPreviewSegments();
+ else
+ m_routeRenderer->RemovePreviewSegment(msg->GetSegmentId());
+ break;
+ }
+
+ case Message::SetRouteSegmentVisibility:
+ {
+ ref_ptr<SetRouteSegmentVisibilityMessage> const msg = message;
+ m_routeRenderer->SetRouteSegmentVisibility(msg->GetSegmentId(), msg->IsVisible());
+ break;
+ }
+
case Message::RecoverGLResources:
{
UpdateGLResources();
@@ -624,10 +664,18 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
- case Message::FlushGpsTrackPoints:
+ case Message::FlushCirclesPack:
{
- ref_ptr<FlushGpsTrackPointsMessage> msg = message;
- m_gpsTrackRenderer->AddRenderData(make_ref(m_gpuProgramManager), msg->AcceptRenderData());
+ ref_ptr<FlushCirclesPackMessage> msg = message;
+ switch (msg->GetDestination())
+ {
+ case CacheCirclesPackMessage::GpsTrack:
+ m_gpsTrackRenderer->AddRenderData(make_ref(m_gpuProgramManager), msg->AcceptRenderData());
+ break;
+ case CacheCirclesPackMessage::RoutePreview:
+ m_routeRenderer->AddPreviewRenderData(msg->AcceptRenderData(), make_ref(m_gpuProgramManager));
+ break;
+ }
break;
}
@@ -1014,13 +1062,6 @@ FeatureID FrontendRenderer::GetVisiblePOI(m2::RectD const & pixelRect)
return featureID;
}
-void FrontendRenderer::PrepareGpsTrackPoints(uint32_t pointsCount)
-{
- m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
- make_unique_dp<CacheGpsTrackPointsMessage>(pointsCount),
- MessagePriority::Normal);
-}
-
void FrontendRenderer::PullToBoundArea(bool randomPlace, bool applyZoom)
{
if (m_dragBoundArea.empty())
@@ -1766,14 +1807,16 @@ void FrontendRenderer::Routine::Do()
if (viewportChanged)
m_renderer.OnResize(modelView);
- if (modelViewChanged || viewportChanged)
- m_renderer.PrepareScene(modelView);
-
// Check for a frame is active.
- bool isActiveFrame = modelViewChanged || viewportChanged ||
- m_renderer.m_myPositionController->IsWaitingForTimers();
+ bool isActiveFrame = modelViewChanged || viewportChanged;
+ if (isActiveFrame)
+ m_renderer.PrepareScene(modelView);
+
+ isActiveFrame |= m_renderer.m_myPositionController->IsWaitingForTimers();
isActiveFrame |= m_renderer.m_texMng->UpdateDynamicTextures();
+ isActiveFrame |= m_renderer.m_routeRenderer->UpdatePreview(modelView);
+
m_renderer.RenderScene(modelView);
if (modelViewChanged || m_renderer.m_forceUpdateScene)
diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp
index 0ab7728a5f..7412b1edbd 100755
--- a/drape_frontend/frontend_renderer.hpp
+++ b/drape_frontend/frontend_renderer.hpp
@@ -220,8 +220,6 @@ private:
FeatureID GetVisiblePOI(m2::PointD const & pixelPoint);
FeatureID GetVisiblePOI(m2::RectD const & pixelRect);
- void PrepareGpsTrackPoints(uint32_t pointsCount);
-
void PullToBoundArea(bool randomPlace, bool applyZoom);
void ProcessSelection(ref_ptr<SelectObjectMessage> msg);
diff --git a/drape_frontend/gps_track_point.hpp b/drape_frontend/gps_track_point.hpp
index 4de53e85e5..a3387b327b 100644
--- a/drape_frontend/gps_track_point.hpp
+++ b/drape_frontend/gps_track_point.hpp
@@ -4,7 +4,6 @@
namespace df
{
-
struct GpsTrackPoint
{
// Timestamp of the point, seconds from 1st Jan 1970
@@ -19,5 +18,4 @@ struct GpsTrackPoint
// Unique identifier of the point
uint32_t m_id;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp
index e68ec70ec9..d2cfc42962 100644
--- a/drape_frontend/gps_track_renderer.cpp
+++ b/drape_frontend/gps_track_renderer.cpp
@@ -13,14 +13,12 @@
#include "base/logging.hpp"
-#include "std/algorithm.hpp"
+#include <algorithm>
namespace df
{
-
namespace
{
-
//#define SHOW_RAW_POINTS
df::ColorConstant const kTrackUnknownDistanceColor = "TrackUnknownDistance";
@@ -33,7 +31,7 @@ int const kMinVisibleZoomLevel = 5;
size_t const kAveragePointsCount = 512;
// Radius of circles depending on zoom levels.
-float const kRadiusInPixel[] =
+std::vector<float> const kRadiusInPixel =
{
// 1 2 3 4 5 6 7 8 9 10
0.8f, 0.8f, 0.8f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f,
@@ -49,13 +47,24 @@ uint8_t const kMinNightAlpha = 50;
uint8_t const kMaxNightAlpha = 102;
double const kUnknownDistanceTime = 5 * 60; // seconds
+double const kDistanceScalar = 0.4;
+
+float CalculateRadius(ScreenBase const & screen)
+{
+ double zoom = 0.0;
+ int index = 0;
+ float lerpCoef = 0.0f;
+ ExtractZoomFactors(screen, zoom, index, lerpCoef);
+ float const radius = InterpolateByZoomLevels(index, lerpCoef, kRadiusInPixel);
+ return radius * static_cast<float>(VisualParams::Instance().GetVisualScale());
+}
+
#ifdef DEBUG
bool GpsPointsSortPredicate(GpsTrackPoint const & pt1, GpsTrackPoint const & pt2)
{
return pt1.m_id < pt2.m_id;
}
#endif
-
} // namespace
GpsTrackRenderer::GpsTrackRenderer(TRenderDataRequestFn const & dataRequestFn)
@@ -69,30 +78,14 @@ GpsTrackRenderer::GpsTrackRenderer(TRenderDataRequestFn const & dataRequestFn)
m_handlesCache.reserve(8);
}
-float GpsTrackRenderer::CalculateRadius(ScreenBase const & screen) const
-{
- double const zoomLevel = GetZoomLevel(screen.GetScale());
- double zoom = trunc(zoomLevel);
- int const index = zoom - 1.0;
- float const lerpCoef = zoomLevel - zoom;
-
- float radius = 0.0f;
- if (index < scales::UPPER_STYLE_SCALE)
- radius = kRadiusInPixel[index] + lerpCoef * (kRadiusInPixel[index + 1] - kRadiusInPixel[index]);
- else
- radius = kRadiusInPixel[scales::UPPER_STYLE_SCALE];
-
- return radius * VisualParams::Instance().GetVisualScale();
-}
-
void GpsTrackRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng,
- drape_ptr<GpsTrackRenderData> && renderData)
+ drape_ptr<CirclesPackRenderData> && renderData)
{
- drape_ptr<GpsTrackRenderData> data = move(renderData);
- ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::TRACK_POINT_PROGRAM);
+ drape_ptr<CirclesPackRenderData> data = std::move(renderData);
+ ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM);
program->Bind();
data->m_bucket->GetBuffer()->Build(program);
- m_renderData.push_back(move(data));
+ m_renderData.push_back(std::move(data));
m_waitForRenderData = false;
}
@@ -104,16 +97,18 @@ void GpsTrackRenderer::ClearRenderData()
m_needUpdate = true;
}
-void GpsTrackRenderer::UpdatePoints(vector<GpsTrackPoint> const & toAdd, vector<uint32_t> const & toRemove)
+void GpsTrackRenderer::UpdatePoints(std::vector<GpsTrackPoint> const & toAdd,
+ std::vector<uint32_t> const & toRemove)
{
bool wasChanged = false;
if (!toRemove.empty())
{
auto removePredicate = [&toRemove](GpsTrackPoint const & pt)
{
- return find(toRemove.begin(), toRemove.end(), pt.m_id) != toRemove.end();
+ return std::find(toRemove.begin(), toRemove.end(), pt.m_id) != toRemove.end();
};
- m_points.erase(remove_if(m_points.begin(), m_points.end(), removePredicate), m_points.end());
+ m_points.erase(std::remove_if(m_points.begin(), m_points.end(), removePredicate),
+ m_points.end());
wasChanged = true;
}
@@ -170,7 +165,8 @@ dp::Color GpsTrackRenderer::CalculatePointColor(size_t pointIndex, m2::PointD co
if ((end.m_timestamp - start.m_timestamp) > kUnknownDistanceTime)
{
dp::Color const color = df::GetColorConstant(df::kTrackUnknownDistanceColor);
- return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha);
+ return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(),
+ static_cast<uint8_t>(alpha));
}
double const length = (end.m_point - start.m_point).Length();
@@ -179,7 +175,8 @@ dp::Color GpsTrackRenderer::CalculatePointColor(size_t pointIndex, m2::PointD co
double const speed = max(start.m_speedMPS * (1.0 - td) + end.m_speedMPS * td, 0.0);
dp::Color const color = GetColorBySpeed(speed);
- return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(), alpha);
+ return dp::Color(color.GetRed(), color.GetGreen(), color.GetBlue(),
+ static_cast<uint8_t>(alpha));
}
dp::Color GpsTrackRenderer::GetColorBySpeed(double speed) const
@@ -228,10 +225,11 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel,
m_handlesCache.clear();
for (size_t i = 0; i < m_renderData.size(); i++)
{
- ASSERT_EQUAL(m_renderData[i]->m_bucket->GetOverlayHandlesCount(), 1, ());
- GpsTrackHandle * handle = static_cast<GpsTrackHandle*>(m_renderData[i]->m_bucket->GetOverlayHandle(0).get());
+ auto & bucket = m_renderData[i]->m_bucket;
+ ASSERT_EQUAL(bucket->GetOverlayHandlesCount(), 1, ());
+ CirclesPackHandle * handle = static_cast<CirclesPackHandle *>(bucket->GetOverlayHandle(0).get());
handle->Clear();
- m_handlesCache.push_back(make_pair(handle, 0));
+ m_handlesCache.push_back(std::make_pair(handle, 0));
}
m_pivot = screen.GlobalRect().Center();
@@ -246,8 +244,6 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel,
}
else
{
- double const kDistanceScalar = 0.4;
-
m2::Spline::iterator it;
it.Attach(m_pointsSpline);
while (!it.BeginAgain())
@@ -257,9 +253,11 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel,
pt.x + radiusMercator, pt.y + radiusMercator);
if (screen.ClipRect().IsIntersect(pointRect))
{
- dp::Color const color = CalculatePointColor(it.GetIndex(), pt, it.GetLength(), it.GetFullLength());
+ dp::Color const color = CalculatePointColor(it.GetIndex(), pt,
+ it.GetLength(), it.GetFullLength());
m2::PointD const convertedPt = MapShape::ConvertToLocal(pt, m_pivot, kShapeCoordScalar);
- m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius, color);
+ 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++;
@@ -278,7 +276,8 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel,
for (size_t i = 0; i < m_points.size(); i++)
{
m2::PointD const convertedPt = MapShape::ConvertToLocal(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].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++;
@@ -305,7 +304,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel,
math::Matrix<float, 4, 4> mv = screen.GetModelView(m_pivot, kShapeCoordScalar);
uniforms.SetMatrix4x4Value("modelView", mv.m_data);
uniforms.SetFloatValue("u_opacity", 1.0f);
- ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::TRACK_POINT_PROGRAM);
+ ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM);
program->Bind();
ASSERT_GREATER(m_renderData.size(), 0, ());
@@ -314,8 +313,10 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel,
dp::ApplyUniforms(uniforms, program);
for (size_t i = 0; i < m_renderData.size(); i++)
+ {
if (m_handlesCache[i].second != 0)
m_renderData[i]->m_bucket->Render(state.GetDrawAsLine());
+ }
}
void GpsTrackRenderer::Update()
@@ -328,6 +329,4 @@ void GpsTrackRenderer::Clear()
m_points.clear();
m_needUpdate = true;
}
-
-} // namespace df
-
+} // namespace df
diff --git a/drape_frontend/gps_track_renderer.hpp b/drape_frontend/gps_track_renderer.hpp
index b9c67005ce..bf13acf107 100644
--- a/drape_frontend/gps_track_renderer.hpp
+++ b/drape_frontend/gps_track_renderer.hpp
@@ -1,7 +1,7 @@
#pragma once
+#include "drape_frontend/circles_pack_shape.hpp"
#include "drape_frontend/gps_track_point.hpp"
-#include "drape_frontend/gps_track_shape.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/pointers.hpp"
@@ -10,23 +10,23 @@
#include "geometry/screenbase.hpp"
#include "geometry/spline.hpp"
-#include "std/map.hpp"
-#include "std/vector.hpp"
+#include <functional>
+#include <map>
+#include <vector>
namespace df
{
-
class GpsTrackRenderer final
{
public:
- using TRenderDataRequestFn = function<void(size_t)>;
+ using TRenderDataRequestFn = std::function<void(size_t)>;
explicit GpsTrackRenderer(TRenderDataRequestFn const & dataRequestFn);
void AddRenderData(ref_ptr<dp::GpuProgramManager> mng,
- drape_ptr<GpsTrackRenderData> && renderData);
+ drape_ptr<CirclesPackRenderData> && renderData);
- void UpdatePoints(vector<GpsTrackPoint> const & toAdd,
- vector<uint32_t> const & toRemove);
+ void UpdatePoints(std::vector<GpsTrackPoint> const & toAdd,
+ std::vector<uint32_t> const & toRemove);
void RenderTrack(ScreenBase const & screen, int zoomLevel,
ref_ptr<dp::GpuProgramManager> mng,
@@ -37,21 +37,19 @@ public:
void ClearRenderData();
private:
- float CalculateRadius(ScreenBase const & screen) const;
size_t GetAvailablePointsCount() const;
dp::Color CalculatePointColor(size_t pointIndex, m2::PointD const & curPoint,
double lengthFromStart, double fullLength) const;
dp::Color GetColorBySpeed(double speed) const;
TRenderDataRequestFn m_dataRequestFn;
- vector<drape_ptr<GpsTrackRenderData>> m_renderData;
- vector<GpsTrackPoint> m_points;
+ std::vector<drape_ptr<CirclesPackRenderData>> m_renderData;
+ std::vector<GpsTrackPoint> m_points;
m2::Spline m_pointsSpline;
bool m_needUpdate;
bool m_waitForRenderData;
- vector<pair<GpsTrackHandle*, size_t>> m_handlesCache;
+ std::vector<std::pair<CirclesPackHandle *, size_t>> m_handlesCache;
float m_radius;
m2::PointD m_pivot;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/gps_track_shape.cpp b/drape_frontend/gps_track_shape.cpp
deleted file mode 100644
index c48b1f915d..0000000000
--- a/drape_frontend/gps_track_shape.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "drape_frontend/gps_track_shape.hpp"
-#include "drape_frontend/shader_def.hpp"
-
-#include "drape/attribute_provider.hpp"
-#include "drape/batcher.hpp"
-#include "drape/glsl_func.hpp"
-#include "drape/glsl_types.hpp"
-#include "drape/texture_manager.hpp"
-
-#include "base/logging.hpp"
-
-namespace df
-{
-
-namespace
-{
-
-uint32_t const kDynamicStreamID = 0x7F;
-
-struct GpsTrackStaticVertex
-{
- using TNormal = glsl::vec3;
-
- GpsTrackStaticVertex() = default;
- GpsTrackStaticVertex(TNormal const & normal) : m_normal(normal) {}
-
- TNormal m_normal;
-};
-
-dp::GLState GetGpsTrackState(ref_ptr<dp::TextureManager> texMng)
-{
- dp::GLState state(gpu::TRACK_POINT_PROGRAM, dp::GLState::OverlayLayer);
- state.SetColorTexture(texMng->GetSymbolsTexture());
- return state;
-}
-
-dp::BindingInfo const & GetGpsTrackStaticBindingInfo()
-{
- static unique_ptr<dp::BindingInfo> s_info;
- if (s_info == nullptr)
- {
- dp::BindingFiller<GpsTrackStaticVertex> filler(1);
- filler.FillDecl<GpsTrackStaticVertex::TNormal>("a_normal");
- s_info.reset(new dp::BindingInfo(filler.m_info));
- }
- return *s_info;
-}
-
-dp::BindingInfo const & GetGpsTrackDynamicBindingInfo()
-{
- static unique_ptr<dp::BindingInfo> s_info;
- if (s_info == nullptr)
- {
- dp::BindingFiller<GpsTrackDynamicVertex> filler(2, kDynamicStreamID);
- filler.FillDecl<GpsTrackDynamicVertex::TPosition>("a_position");
- filler.FillDecl<GpsTrackDynamicVertex::TColor>("a_color");
- s_info.reset(new dp::BindingInfo(filler.m_info));
- }
- return *s_info;
-}
-
-} // namespace
-
-GpsTrackHandle::GpsTrackHandle(size_t pointsCount)
- : OverlayHandle(FeatureID(), dp::Anchor::Center, 0, false)
- , m_needUpdate(false)
-{
- m_buffer.resize(pointsCount * dp::Batcher::VertexPerQuad);
-}
-
-void GpsTrackHandle::GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const
-{
- if (!m_needUpdate)
- return;
-
- TOffsetNode const & node = GetOffsetNode(kDynamicStreamID);
- ASSERT(node.first.GetElementSize() == sizeof(GpsTrackDynamicVertex), ());
- ASSERT(node.second.m_count == m_buffer.size(), ());
-
- uint32_t const byteCount = static_cast<uint32_t>(m_buffer.size()) * sizeof(GpsTrackDynamicVertex);
- void * buffer = mutator->AllocateMutationBuffer(byteCount);
- memcpy(buffer, m_buffer.data(), byteCount);
-
- dp::MutateNode mutateNode;
- mutateNode.m_region = node.second;
- mutateNode.m_data = make_ref(buffer);
- mutator->AddMutation(node.first, mutateNode);
-
- m_needUpdate = false;
-}
-
-bool GpsTrackHandle::Update(ScreenBase const & screen)
-{
- UNUSED_VALUE(screen);
- return true;
-}
-
-bool GpsTrackHandle::IndexesRequired() const
-{
- return false;
-}
-
-m2::RectD GpsTrackHandle::GetPixelRect(ScreenBase const & screen, bool perspective) const
-{
- UNUSED_VALUE(screen);
- UNUSED_VALUE(perspective);
- return m2::RectD();
-}
-
-void GpsTrackHandle::GetPixelShape(ScreenBase const & screen, bool perspective, Rects & rects) const
-{
- UNUSED_VALUE(screen);
- UNUSED_VALUE(perspective);
-}
-
-void GpsTrackHandle::SetPoint(size_t index, m2::PointD const & position,
- float radius, dp::Color const & color)
-{
- size_t bufferIndex = index * dp::Batcher::VertexPerQuad;
- ASSERT_GREATER_OR_EQUAL(bufferIndex, 0, ());
- ASSERT_LESS(bufferIndex, m_buffer.size(), ());
-
- for (size_t i = 0; i < dp::Batcher::VertexPerQuad; i++)
- {
- m_buffer[bufferIndex + i].m_position = glsl::vec3(position.x, position.y, radius);
- m_buffer[bufferIndex + i].m_color = glsl::ToVec4(color);
- }
- m_needUpdate = true;
-}
-
-void GpsTrackHandle::Clear()
-{
- memset(m_buffer.data(), 0, m_buffer.size() * sizeof(GpsTrackDynamicVertex));
- m_needUpdate = true;
-}
-
-size_t GpsTrackHandle::GetPointsCount() const
-{
- return m_buffer.size() / dp::Batcher::VertexPerQuad;
-}
-
-void GpsTrackShape::Draw(ref_ptr<dp::TextureManager> texMng, GpsTrackRenderData & data)
-{
- ASSERT_NOT_EQUAL(data.m_pointsCount, 0, ());
-
- size_t const kVerticesInPoint = dp::Batcher::VertexPerQuad;
- size_t const kIndicesInPoint = dp::Batcher::IndexPerQuad;
- vector<GpsTrackStaticVertex> staticVertexData;
- staticVertexData.reserve(data.m_pointsCount * kVerticesInPoint);
- for (size_t i = 0; i < data.m_pointsCount; i++)
- {
- staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(-1.0f, 1.0f, 1.0f)));
- staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(-1.0f, -1.0f, 1.0f)));
- staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(1.0f, 1.0f, 1.0f)));
- staticVertexData.push_back(GpsTrackStaticVertex(GpsTrackStaticVertex::TNormal(1.0f, -1.0f, 1.0f)));
- }
-
- vector<GpsTrackDynamicVertex> dynamicVertexData;
- dynamicVertexData.resize(data.m_pointsCount * kVerticesInPoint);
-
- dp::Batcher batcher(data.m_pointsCount * kIndicesInPoint, data.m_pointsCount * kVerticesInPoint);
- dp::SessionGuard guard(batcher, [&data](dp::GLState const & state, drape_ptr<dp::RenderBucket> && b)
- {
- data.m_bucket = move(b);
- data.m_state = state;
- });
-
- drape_ptr<dp::OverlayHandle> handle = make_unique_dp<GpsTrackHandle>(data.m_pointsCount);
-
- dp::AttributeProvider provider(2 /* stream count */, static_cast<uint32_t>(staticVertexData.size()));
- provider.InitStream(0 /* stream index */, GetGpsTrackStaticBindingInfo(), make_ref(staticVertexData.data()));
- provider.InitStream(1 /* stream index */, GetGpsTrackDynamicBindingInfo(), make_ref(dynamicVertexData.data()));
- batcher.InsertListOfStrip(GetGpsTrackState(texMng), make_ref(&provider), move(handle), kVerticesInPoint);
-
- GLFunctions::glFlush();
-}
-
-} // namespace df
diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp
index a18c6fa4ac..25e7159014 100644
--- a/drape_frontend/message.hpp
+++ b/drape_frontend/message.hpp
@@ -43,14 +43,17 @@ public:
FlushRouteArrows,
FollowRoute,
DeactivateRouteFollowing,
+ SetRouteSegmentVisibility,
+ AddRoutePreviewSegment,
+ RemoveRoutePreviewSegment,
UpdateMapStyle,
SwitchMapStyle,
Invalidate,
Allow3dMode,
Allow3dBuildings,
EnablePerspective,
- CacheGpsTrackPoints,
- FlushGpsTrackPoints,
+ FlushCirclesPack,
+ CacheCirclesPack,
UpdateGpsTrackPoints,
ClearGpsTrackPoints,
ShowChoosePositionMark,
diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp
index f9e7f2700a..c2cb3aba99 100644
--- a/drape_frontend/message_subclasses.hpp
+++ b/drape_frontend/message_subclasses.hpp
@@ -1,14 +1,13 @@
#pragma once
-#include "drape_frontend/gui/layer_render.hpp"
-#include "drape_frontend/gui/skin.hpp"
-
+#include "drape_frontend/circles_pack_shape.hpp"
#include "drape_frontend/color_constants.hpp"
#include "drape_frontend/custom_symbol.hpp"
#include "drape_frontend/drape_api.hpp"
#include "drape_frontend/drape_api_builder.hpp"
#include "drape_frontend/gps_track_point.hpp"
-#include "drape_frontend/gps_track_shape.hpp"
+#include "drape_frontend/gui/layer_render.hpp"
+#include "drape_frontend/gui/skin.hpp"
#include "drape_frontend/message.hpp"
#include "drape_frontend/my_position.hpp"
#include "drape_frontend/overlay_batcher.hpp"
@@ -17,25 +16,25 @@
#include "drape_frontend/selection_shape.hpp"
#include "drape_frontend/tile_utils.hpp"
#include "drape_frontend/traffic_generator.hpp"
-#include "drape_frontend/user_marks_provider.hpp"
#include "drape_frontend/user_mark_shapes.hpp"
-
-#include "geometry/polyline2d.hpp"
-#include "geometry/rect2d.hpp"
-#include "geometry/screenbase.hpp"
-#include "geometry/triangle2d.hpp"
+#include "drape_frontend/user_marks_provider.hpp"
#include "drape/glstate.hpp"
#include "drape/pointers.hpp"
#include "drape/render_bucket.hpp"
#include "drape/viewport.hpp"
+#include "geometry/polyline2d.hpp"
+#include "geometry/rect2d.hpp"
+#include "geometry/screenbase.hpp"
+#include "geometry/triangle2d.hpp"
+
#include "platform/location.hpp"
#include "std/condition_variable.hpp"
-#include "std/shared_ptr.hpp"
-#include "std/set.hpp"
#include "std/function.hpp"
+#include "std/set.hpp"
+#include "std/shared_ptr.hpp"
#include "std/utility.hpp"
namespace df
@@ -702,6 +701,68 @@ private:
drape_ptr<RouteArrowsData> m_routeArrowsData;
};
+class AddRoutePreviewSegmentMessage : public Message
+{
+public:
+ AddRoutePreviewSegmentMessage(dp::DrapeID segmentId, m2::PointD const & startPt,
+ m2::PointD const & finishPt)
+ : m_segmentId(segmentId)
+ , m_startPoint(startPt)
+ , m_finishPoint(finishPt)
+ {}
+
+ Type GetType() const override { return Message::AddRoutePreviewSegment; }
+
+ dp::DrapeID GetSegmentId() const { return m_segmentId; };
+ m2::PointD const & GetStartPoint() const { return m_startPoint; }
+ m2::PointD const & GetFinishPoint() const { return m_finishPoint; }
+
+private:
+ dp::DrapeID m_segmentId;
+ m2::PointD m_startPoint;
+ m2::PointD m_finishPoint;
+};
+
+class RemoveRoutePreviewSegmentMessage : public Message
+{
+public:
+ RemoveRoutePreviewSegmentMessage()
+ : m_needRemoveAll(true)
+ {}
+
+ explicit RemoveRoutePreviewSegmentMessage(dp::DrapeID segmentId)
+ : m_segmentId(segmentId)
+ , m_needRemoveAll(false)
+ {}
+
+ Type GetType() const override { return Message::RemoveRoutePreviewSegment; }
+
+ dp::DrapeID GetSegmentId() const { return m_segmentId; }
+ bool NeedRemoveAll() const { return m_needRemoveAll; }
+
+private:
+ dp::DrapeID m_segmentId;
+ bool m_needRemoveAll;
+};
+
+class SetRouteSegmentVisibilityMessage : public Message
+{
+public:
+ SetRouteSegmentVisibilityMessage(dp::DrapeID segmentId, bool isVisible)
+ : m_segmentId(segmentId)
+ , m_isVisible(isVisible)
+ {}
+
+ Type GetType() const override { return Message::SetRouteSegmentVisibility; }
+
+ dp::DrapeID GetSegmentId() const { return m_segmentId; }
+ bool IsVisible() const { return m_isVisible; }
+
+private:
+ dp::DrapeID m_segmentId;
+ bool m_isVisible;
+};
+
class UpdateMapStyleMessage : public BaseBlockingMessage
{
public:
@@ -839,51 +900,68 @@ public:
Type GetType() const override { return Message::EnablePerspective; }
};
-class CacheGpsTrackPointsMessage : public Message
+class CacheCirclesPackMessage : public Message
{
public:
- CacheGpsTrackPointsMessage(uint32_t pointsCount) : m_pointsCount(pointsCount) {}
+ enum Destination
+ {
+ GpsTrack,
+ RoutePreview
+ };
- Type GetType() const override { return Message::CacheGpsTrackPoints; }
+ CacheCirclesPackMessage(uint32_t pointsCount, Destination dest)
+ : m_pointsCount(pointsCount)
+ , m_destination(dest)
+ {}
+
+ Type GetType() const override { return Message::CacheCirclesPack; }
uint32_t GetPointsCount() const { return m_pointsCount; }
+ Destination GetDestination() const { return m_destination; }
private:
uint32_t m_pointsCount;
+ Destination m_destination;
};
-class FlushGpsTrackPointsMessage : public Message
+class FlushCirclesPackMessage : public Message
{
public:
- FlushGpsTrackPointsMessage(drape_ptr<GpsTrackRenderData> && renderData)
- : m_renderData(move(renderData))
+
+ FlushCirclesPackMessage(drape_ptr<CirclesPackRenderData> && renderData,
+ CacheCirclesPackMessage::Destination dest)
+ : m_renderData(std::move(renderData))
+ , m_destination(dest)
{}
- Type GetType() const override { return Message::FlushGpsTrackPoints; }
+ Type GetType() const override { return Message::FlushCirclesPack; }
bool IsGLContextDependent() const override { return true; }
- drape_ptr<GpsTrackRenderData> && AcceptRenderData() { return move(m_renderData); }
+ drape_ptr<CirclesPackRenderData> && AcceptRenderData() { return std::move(m_renderData); }
+ CacheCirclesPackMessage::Destination GetDestination() const { return m_destination; }
private:
- drape_ptr<GpsTrackRenderData> m_renderData;
+ drape_ptr<CirclesPackRenderData> m_renderData;
+ CacheCirclesPackMessage::Destination m_destination;
};
class UpdateGpsTrackPointsMessage : public Message
{
public:
- UpdateGpsTrackPointsMessage(vector<GpsTrackPoint> && toAdd, vector<uint32_t> && toRemove)
- : m_pointsToAdd(move(toAdd))
- , m_pointsToRemove(move(toRemove))
+ UpdateGpsTrackPointsMessage(std::vector<GpsTrackPoint> && toAdd,
+ std::vector<uint32_t> && toRemove)
+ : m_pointsToAdd(std::move(toAdd))
+ , m_pointsToRemove(std::move(toRemove))
{}
Type GetType() const override { return Message::UpdateGpsTrackPoints; }
- vector<GpsTrackPoint> const & GetPointsToAdd() { return m_pointsToAdd; }
- vector<uint32_t> const & GetPointsToRemove() { return m_pointsToRemove; }
+ std::vector<GpsTrackPoint> const & GetPointsToAdd() { return m_pointsToAdd; }
+ std::vector<uint32_t> const & GetPointsToRemove() { return m_pointsToRemove; }
private:
- vector<GpsTrackPoint> m_pointsToAdd;
- vector<uint32_t> m_pointsToRemove;
+ std::vector<GpsTrackPoint> m_pointsToAdd;
+ std::vector<uint32_t> m_pointsToRemove;
};
class ClearGpsTrackPointsMessage : public Message
@@ -892,7 +970,6 @@ public:
ClearGpsTrackPointsMessage() = default;
Type GetType() const override { return Message::ClearGpsTrackPoints; }
-
};
class SetTimeInBackgroundMessage : public Message
diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp
index 872cdfd034..438372544a 100644
--- a/drape_frontend/route_renderer.cpp
+++ b/drape_frontend/route_renderer.cpp
@@ -13,6 +13,7 @@
#include "base/logging.hpp"
#include <algorithm>
+#include <cmath>
namespace df
{
@@ -20,10 +21,11 @@ std::string const kRouteColor = "Route";
std::string const kRouteOutlineColor = "RouteOutline";
std::string const kRoutePedestrian = "RoutePedestrian";
std::string const kRouteBicycle = "RouteBicycle";
+std::string const kRoutePreview = "RoutePreview";
namespace
{
-float const kHalfWidthInPixelCar[] =
+std::vector<float> const kHalfWidthInPixelCar =
{
// 1 2 3 4 5 6 7 8 9 10
1.0f, 1.0f, 1.5f, 1.5f, 1.5f, 2.0f, 2.0f, 2.0f, 2.5f, 2.5f,
@@ -31,7 +33,7 @@ float const kHalfWidthInPixelCar[] =
3.0f, 3.0f, 4.0f, 5.0f, 6.0, 8.0f, 10.0f, 10.0f, 18.0f, 27.0f
};
-float const kHalfWidthInPixelOthers[] =
+std::vector<float> const kHalfWidthInPixelOthers =
{
// 1 2 3 4 5 6 7 8 9 10
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.2f, 1.2f,
@@ -39,9 +41,46 @@ float const kHalfWidthInPixelOthers[] =
1.5f, 1.5f, 2.0f, 2.5f, 3.0, 4.0f, 5.0f, 5.0f, 9.0f, 13.0f
};
+std::vector<float> const kPreviewPointRadiusInPixel =
+{
+ // 1 2 3 4 5 6 7 8 9 10
+ 0.8f, 0.8f, 0.8f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f,
+ //11 12 13 14 15 16 17 18 19 20
+ 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 3.5f, 4.5f, 4.5f, 4.5f, 5.5f
+};
+
int const kArrowAppearingZoomLevel = 14;
int const kInvalidGroup = -1;
+size_t const kPreviewPointsCount = 512;
+double const kPreviewAnimationSpeed = 3.0;
+double const kPreviewAnimationScale = 0.3;
+
+void InterpolateByZoom(drape_ptr<RouteSegment> const & routeSegment, ScreenBase const & screen,
+ float & halfWidth, double & zoom)
+{
+ int index = 0;
+ float lerpCoef = 0.0f;
+ ExtractZoomFactors(screen, zoom, index, lerpCoef);
+
+ std::vector<float> const * halfWidthInPixel = &kHalfWidthInPixelOthers;
+ if (routeSegment->m_routeType == RouteType::Car || routeSegment->m_routeType == RouteType::Taxi)
+ halfWidthInPixel = &kHalfWidthInPixelCar;
+
+ halfWidth = InterpolateByZoomLevels(index, lerpCoef, *halfWidthInPixel);
+ halfWidth *= static_cast<float>(df::VisualParams::Instance().GetVisualScale());
+}
+
+float CalculateRadius(ScreenBase const & screen)
+{
+ double zoom = 0.0;
+ int index = 0;
+ float lerpCoef = 0.0f;
+ ExtractZoomFactors(screen, zoom, index, lerpCoef);
+ float const radius = InterpolateByZoomLevels(index, lerpCoef, kPreviewPointRadiusInPixel);
+ return radius * static_cast<float>(VisualParams::Instance().GetVisualScale());
+}
+
void ClipBorders(std::vector<ArrowBorders> & borders)
{
auto invalidBorders = [](ArrowBorders const & borders)
@@ -196,32 +235,16 @@ dp::Color GetOutlineColor(drape_ptr<RouteSegment> const & routeSegment)
}
} // namespace
-RouteRenderer::RouteRenderer()
+RouteRenderer::RouteRenderer(PreviewPointsRequestCallback && previewPointsRequest)
: m_distanceFromBegin(0.0)
, m_followingEnabled(false)
-{}
-
-void RouteRenderer::InterpolateByZoom(drape_ptr<RouteSegment> const & routeSegment, ScreenBase const & screen,
- float & halfWidth, double & zoom) const
+ , m_previewPointsRequest(std::move(previewPointsRequest))
+ , m_waitForPreviewRenderData(false)
{
- double const zoomLevel = GetZoomLevel(screen.GetScale());
- zoom = trunc(zoomLevel);
- int const index = static_cast<int>(zoom - 1.0);
- float const lerpCoef = static_cast<float>(zoomLevel - zoom);
-
- float const * halfWidthInPixel = kHalfWidthInPixelOthers;
- if (routeSegment->m_routeType == RouteType::Car || routeSegment->m_routeType == RouteType::Taxi)
- halfWidthInPixel = kHalfWidthInPixelCar;
-
- if (index < scales::UPPER_STYLE_SCALE)
- halfWidth = halfWidthInPixel[index] + lerpCoef * (halfWidthInPixel[index + 1] - halfWidthInPixel[index]);
- else
- halfWidth = halfWidthInPixel[scales::UPPER_STYLE_SCALE];
-
- halfWidth *= df::VisualParams::Instance().GetVisualScale();
+ ASSERT(m_previewPointsRequest != nullptr, ());
}
-void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCallback const & callback)
+void RouteRenderer::UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallback const & callback)
{
ASSERT(callback != nullptr, ());
for (auto const & routeData : m_routeData)
@@ -258,6 +281,94 @@ void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCall
}
}
+bool RouteRenderer::UpdatePreview(ScreenBase const & screen)
+{
+ // Check if there are preview render data.
+ if (m_previewRenderData.empty() && !m_waitForPreviewRenderData)
+ {
+ m_previewPointsRequest(kPreviewPointsCount);
+ m_waitForPreviewRenderData = true;
+ }
+ if (m_waitForPreviewRenderData)
+ return false;
+
+ float scale = 1.0f;
+ float previewCircleRadius = 0.0;
+ if (!m_previewSegments.empty())
+ {
+ ClearPreviewHandles();
+ m_previewPivot = screen.GlobalRect().Center();
+ previewCircleRadius = CalculateRadius(screen);
+
+ using namespace std::chrono;
+ auto dt = steady_clock::now() - m_showPreviewTimestamp;
+ double const seconds = duration_cast<duration<double>>(dt).count();
+ scale = static_cast<float>(1.0 + kPreviewAnimationScale *
+ abs(sin(kPreviewAnimationSpeed * seconds)));
+ }
+ double const currentScaleGtoP = 1.0 / screen.GetScale();
+ double const radiusMercator = previewCircleRadius / currentScaleGtoP;
+ double const diameterMercator = 2.0 * radiusMercator;
+ double const gapMercator = diameterMercator;
+ dp::Color const circleColor = df::GetColorConstant(kRoutePreview);
+
+ for (auto const & previewSegment : m_previewSegments)
+ {
+ auto const & info = previewSegment.second;
+ m2::PolylineD polyline = {info.m_startPoint, info.m_finishPoint};
+ double const segmentLen = polyline.GetLength();
+ size_t circlesCount = static_cast<size_t>(segmentLen / (diameterMercator + gapMercator));
+ if (circlesCount == 0)
+ circlesCount = 1;
+ double const distDelta = segmentLen / circlesCount;
+ for (double d = distDelta * 0.5; d < segmentLen; d += distDelta)
+ {
+ float const r = scale * static_cast<float>(radiusMercator);
+ m2::PointD const pt = polyline.GetPointByDistance(d);
+ m2::RectD const circleRect(pt.x - r, pt.y - r, pt.x + r, pt.y + r);
+ if (!screen.ClipRect().IsIntersect(circleRect))
+ continue;
+
+ size_t pointIndex;
+ CirclesPackHandle * h = GetPreviewHandle(pointIndex);
+ if (h == nullptr)
+ {
+ // There is no any available handle.
+ m_previewPointsRequest(kPreviewPointsCount);
+ m_waitForPreviewRenderData = true;
+ return true;
+ }
+
+ m2::PointD const convertedPt = MapShape::ConvertToLocal(pt, m_previewPivot, kShapeCoordScalar);
+ h->SetPoint(pointIndex, convertedPt, scale * previewCircleRadius, circleColor);
+ }
+ }
+ return !m_previewSegments.empty();
+}
+
+void RouteRenderer::ClearPreviewHandles()
+{
+ for (auto & handle : m_previewHandlesCache)
+ {
+ handle.first->Clear();
+ handle.second = 0;
+ }
+}
+
+CirclesPackHandle * RouteRenderer::GetPreviewHandle(size_t & index)
+{
+ for (auto & handle : m_previewHandlesCache)
+ {
+ if (handle.second < handle.first->GetPointsCount())
+ {
+ index = handle.second++;
+ return handle.first;
+ }
+ }
+ index = 0;
+ return nullptr;
+}
+
void RouteRenderer::RenderRouteData(drape_ptr<RouteData> const & routeData,
ScreenBase const & screen, bool trafficShown,
ref_ptr<dp::GpuProgramManager> mng,
@@ -266,6 +377,10 @@ void RouteRenderer::RenderRouteData(drape_ptr<RouteData> const & routeData,
if (routeData->m_renderProperty.m_buckets.empty())
return;
+ // Skip rendering of hidden segments.
+ if (m_hiddenSegments.find(routeData->m_segmentId) != m_hiddenSegments.end())
+ return;
+
float const currentHalfWidth = m_routeAdditional[routeData->m_segmentId].m_currentHalfWidth;
float const screenHalfWidth = static_cast<float>(currentHalfWidth * screen.GetScale());
float const dist = m_followingEnabled ? static_cast<float>(m_distanceFromBegin) : -1.0f;
@@ -338,20 +453,48 @@ void RouteRenderer::RenderRouteArrowData(dp::DrapeID segmentId, RouteAdditional
bucket->Render(state.GetDrawAsLine());
}
+void RouteRenderer::RenderPreviewData(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng,
+ dp::UniformValuesStorage const & commonUniforms)
+{
+ if (m_waitForPreviewRenderData || m_previewSegments.empty() || m_previewRenderData.empty())
+ return;
+
+ dp::UniformValuesStorage uniforms = commonUniforms;
+ math::Matrix<float, 4, 4> mv = screen.GetModelView(m_previewPivot, kShapeCoordScalar);
+ uniforms.SetMatrix4x4Value("modelView", mv.m_data);
+ uniforms.SetFloatValue("u_opacity", 1.0f);
+ ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM);
+ program->Bind();
+
+ dp::GLState const & state = m_previewRenderData.front()->m_state;
+ dp::ApplyState(state, program);
+ dp::ApplyUniforms(uniforms, program);
+
+ ASSERT_EQUAL(m_previewRenderData.size(), m_previewHandlesCache.size(), ());
+ for (size_t i = 0; i < m_previewRenderData.size(); i++)
+ {
+ if (m_previewHandlesCache[i].second != 0)
+ m_previewRenderData[i]->m_bucket->Render(state.GetDrawAsLine());
+ }
+}
+
void RouteRenderer::RenderRoute(ScreenBase const & screen, bool trafficShown,
ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms)
{
- if (m_routeData.empty())
- return;
+ if (!m_routeData.empty())
+ {
+ // Render route.
+ for (auto const & routeData : m_routeData)
+ RenderRouteData(routeData, screen, trafficShown, mng, commonUniforms);
- // Render route.
- for (auto const & routeData : m_routeData)
- RenderRouteData(routeData, screen, trafficShown, mng, commonUniforms);
+ // Render arrows.
+ for (auto const & p : m_routeAdditional)
+ RenderRouteArrowData(p.first, p.second, screen, mng, commonUniforms);
+ }
- // Render arrows.
- for (auto const & p : m_routeAdditional)
- RenderRouteArrowData(p.first, p.second, screen, mng, commonUniforms);
+ // Render preview.
+ RenderPreviewData(screen, mng, commonUniforms);
}
void RouteRenderer::AddRouteData(drape_ptr<RouteData> && routeData,
@@ -390,10 +533,29 @@ void RouteRenderer::AddRouteArrowsData(drape_ptr<RouteArrowsData> && routeArrows
BuildBuckets(additional.m_arrowsData->m_renderProperty, mng);
}
+void RouteRenderer::AddPreviewRenderData(drape_ptr<CirclesPackRenderData> && renderData,
+ ref_ptr<dp::GpuProgramManager> mng)
+{
+ drape_ptr<CirclesPackRenderData> data = std::move(renderData);
+ ref_ptr<dp::GpuProgram> program = mng->GetProgram(gpu::CIRCLE_POINT_PROGRAM);
+ program->Bind();
+ data->m_bucket->GetBuffer()->Build(program);
+ m_previewRenderData.push_back(std::move(data));
+ m_waitForPreviewRenderData = false;
+
+ // Save handle in the cache.
+ auto & bucket = m_previewRenderData.back()->m_bucket;
+ ASSERT_EQUAL(bucket->GetOverlayHandlesCount(), 1, ());
+ CirclesPackHandle * handle = static_cast<CirclesPackHandle *>(bucket->GetOverlayHandle(0).get());
+ handle->Clear();
+ m_previewHandlesCache.push_back(std::make_pair(handle, 0));
+}
+
void RouteRenderer::ClearRouteData()
{
m_routeData.clear();
m_routeAdditional.clear();
+ m_hiddenSegments.clear();
}
void RouteRenderer::Clear()
@@ -410,6 +572,10 @@ void RouteRenderer::ClearGLDependentResources()
// All additional data (like arrows) will be regenerated, so clear them all.
m_routeAdditional.clear();
+
+ m_previewRenderData.clear();
+ m_previewHandlesCache.clear();
+ m_waitForPreviewRenderData = false;
}
void RouteRenderer::UpdateDistanceFromBegin(double distanceFromBegin)
@@ -421,4 +587,29 @@ void RouteRenderer::SetFollowingEnabled(bool enabled)
{
m_followingEnabled = enabled;
}
+
+void RouteRenderer::AddPreviewSegment(dp::DrapeID id, PreviewInfo && info)
+{
+ if (m_previewSegments.empty())
+ m_showPreviewTimestamp = std::chrono::steady_clock::now();
+ m_previewSegments.insert(std::make_pair(id, std::move(info)));
+}
+
+void RouteRenderer::RemovePreviewSegment(dp::DrapeID id)
+{
+ m_previewSegments.erase(id);
+}
+
+void RouteRenderer::RemoveAllPreviewSegments()
+{
+ m_previewSegments.clear();
+}
+
+void RouteRenderer::SetRouteSegmentVisibility(dp::DrapeID id, bool isVisible)
+{
+ if (isVisible)
+ m_hiddenSegments.erase(id);
+ else
+ m_hiddenSegments.insert(id);
+}
} // namespace df
diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp
index 2a0ff6167f..7ca388d9ee 100644
--- a/drape_frontend/route_renderer.hpp
+++ b/drape_frontend/route_renderer.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "drape_frontend/circles_pack_shape.hpp"
#include "drape_frontend/route_builder.hpp"
#include "drape/drape_global.hpp"
@@ -8,10 +9,12 @@
#include "geometry/screenbase.hpp"
+#include <chrono>
#include <functional>
#include <string>
#include <vector>
#include <unordered_map>
+#include <unordered_set>
namespace df
{
@@ -23,11 +26,18 @@ extern std::string const kRouteBicycle;
class RouteRenderer final
{
public:
- using TCacheRouteArrowsCallback = std::function<void(dp::DrapeID, std::vector<ArrowBorders> const &)>;
+ using CacheRouteArrowsCallback = std::function<void(dp::DrapeID, std::vector<ArrowBorders> const &)>;
+ using PreviewPointsRequestCallback = std::function<void(size_t)>;
- RouteRenderer();
+ struct PreviewInfo
+ {
+ m2::PointD m_startPoint;
+ m2::PointD m_finishPoint;
+ };
- void UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCallback const & callback);
+ RouteRenderer(PreviewPointsRequestCallback && previewPointsRequest);
+
+ void UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallback const & callback);
void RenderRoute(ScreenBase const & screen, bool trafficShown, ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms);
@@ -40,6 +50,11 @@ public:
void AddRouteArrowsData(drape_ptr<RouteArrowsData> && routeArrowsData,
ref_ptr<dp::GpuProgramManager> mng);
+ void AddPreviewRenderData(drape_ptr<CirclesPackRenderData> && renderData,
+ ref_ptr<dp::GpuProgramManager> mng);
+
+ bool UpdatePreview(ScreenBase const & screen);
+
void Clear();
void ClearRouteData();
void ClearGLDependentResources();
@@ -47,6 +62,12 @@ public:
void UpdateDistanceFromBegin(double distanceFromBegin);
void SetFollowingEnabled(bool enabled);
+ void AddPreviewSegment(dp::DrapeID id, PreviewInfo && info);
+ void RemovePreviewSegment(dp::DrapeID id);
+ void RemoveAllPreviewSegments();
+
+ void SetRouteSegmentVisibility(dp::DrapeID id, bool isVisible);
+
private:
struct RouteAdditional
{
@@ -55,18 +76,29 @@ private:
float m_currentHalfWidth = 0.0f;
};
- void InterpolateByZoom(drape_ptr<RouteSegment> const & routeSegment, ScreenBase const & screen,
- float & halfWidth, double & zoom) const;
void RenderRouteData(drape_ptr<RouteData> const & routeData, ScreenBase const & screen,
bool trafficShown, ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms);
void RenderRouteArrowData(dp::DrapeID segmentId, RouteAdditional const & routeAdditional,
ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms);
+ void RenderPreviewData(ScreenBase const & screen, ref_ptr<dp::GpuProgramManager> mng,
+ dp::UniformValuesStorage const & commonUniforms);
+ void ClearPreviewHandles();
+ CirclesPackHandle * GetPreviewHandle(size_t & index);
double m_distanceFromBegin;
std::vector<drape_ptr<RouteData>> m_routeData;
std::unordered_map<dp::DrapeID, RouteAdditional> m_routeAdditional;
bool m_followingEnabled;
+ std::unordered_set<dp::DrapeID> m_hiddenSegments;
+
+ PreviewPointsRequestCallback m_previewPointsRequest;
+ std::vector<drape_ptr<CirclesPackRenderData>> m_previewRenderData;
+ std::vector<std::pair<CirclesPackHandle *, size_t>> m_previewHandlesCache;
+ bool m_waitForPreviewRenderData;
+ std::unordered_map<dp::DrapeID, PreviewInfo> m_previewSegments;
+ m2::PointD m_previewPivot = m2::PointD::Zero();
+ std::chrono::steady_clock::time_point m_showPreviewTimestamp;
};
} // namespace df
diff --git a/drape_frontend/shaders/trackpoint.fsh.glsl b/drape_frontend/shaders/circle_point.fsh.glsl
index f96beba503..f96beba503 100644
--- a/drape_frontend/shaders/trackpoint.fsh.glsl
+++ b/drape_frontend/shaders/circle_point.fsh.glsl
diff --git a/drape_frontend/shaders/trackpoint.vsh.glsl b/drape_frontend/shaders/circle_point.vsh.glsl
index 7d658bc5ed..7d658bc5ed 100644
--- a/drape_frontend/shaders/trackpoint.vsh.glsl
+++ b/drape_frontend/shaders/circle_point.vsh.glsl
diff --git a/drape_frontend/shaders/shader_index.txt b/drape_frontend/shaders/shader_index.txt
index 1abb3719a7..66558f9808 100644
--- a/drape_frontend/shaders/shader_index.txt
+++ b/drape_frontend/shaders/shader_index.txt
@@ -22,7 +22,7 @@ BOOKMARK_PROGRAM user_mark.vsh.glsl texturing.fsh.glsl
ROUTE_PROGRAM route.vsh.glsl route.fsh.glsl
ROUTE_DASH_PROGRAM route.vsh.glsl route_dash.fsh.glsl
ROUTE_ARROW_PROGRAM route_arrow.vsh.glsl discarded_texturing.fsh.glsl
-TRACK_POINT_PROGRAM trackpoint.vsh.glsl trackpoint.fsh.glsl
+CIRCLE_POINT_PROGRAM circle_point.vsh.glsl circle_point.fsh.glsl
DEBUG_RECT_PROGRAM debug_rect.vsh.glsl debug_rect.fsh.glsl
SCREEN_QUAD_PROGRAM screen_quad.vsh.glsl texturing.fsh.glsl
ARROW_3D_PROGRAM arrow3d.vsh.glsl arrow3d.fsh.glsl
diff --git a/drape_frontend/traffic_renderer.cpp b/drape_frontend/traffic_renderer.cpp
index edd71a5821..0270e324b6 100644
--- a/drape_frontend/traffic_renderer.cpp
+++ b/drape_frontend/traffic_renderer.cpp
@@ -12,7 +12,7 @@
#include "base/logging.hpp"
-#include "std/algorithm.hpp"
+#include <algorithm>
namespace df
{
@@ -28,7 +28,7 @@ int constexpr kOutlineMinZoomLevel = 14;
float const kTrafficArrowAspect = 128.0f / 8.0f;
-float const kLeftWidthInPixel[] =
+std::vector<float> const kLeftWidthInPixel =
{
// 1 2 3 4 5 6 7 8 9 10
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
@@ -36,7 +36,7 @@ float const kLeftWidthInPixel[] =
0.5f, 0.5f, 0.5f, 0.5f, 0.7f, 2.5f, 3.0f, 4.0f, 4.0f, 4.0f
};
-float const kRightWidthInPixel[] =
+std::vector<float> const kRightWidthInPixel =
{
// 1 2 3 4 5 6 7 8 9 10
2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f,
@@ -44,7 +44,7 @@ float const kRightWidthInPixel[] =
3.0f, 3.0f, 4.0f, 4.0f, 3.8f, 2.5f, 3.0f, 4.0f, 4.0f, 4.0f
};
-float const kRoadClass1WidthScalar[] =
+std::vector<float> const kRoadClass1WidthScalar =
{
// 1 2 3 4 5 6 7 8 9 10
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3,
@@ -52,7 +52,7 @@ float const kRoadClass1WidthScalar[] =
0.3, 0.3f, 0.4f, 0.5f, 0.6f, 0.6f, 1.0f, 1.0f, 1.0f, 1.0f
};
-float const kRoadClass2WidthScalar[] =
+std::vector<float> const kRoadClass2WidthScalar =
{
// 1 2 3 4 5 6 7 8 9 10
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.3f,
@@ -60,7 +60,7 @@ float const kRoadClass2WidthScalar[] =
0.3f, 0.3f, 0.3f, 0.3f, 0.5f, 0.5f, 0.5f, 0.8f, 0.9f, 1.0f
};
-float const kTwoWayOffsetInPixel[] =
+std::vector<float> const kTwoWayOffsetInPixel =
{
// 1 2 3 4 5 6 7 8 9 10
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
@@ -68,41 +68,27 @@ float const kTwoWayOffsetInPixel[] =
0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f
};
-vector<int> const kLineDrawerRoadClass1 = {12, 13, 14};
+std::vector<int> const kLineDrawerRoadClass1 = {12, 13, 14};
-vector<int> const kLineDrawerRoadClass2 = {15, 16};
+std::vector<int> const kLineDrawerRoadClass2 = {15, 16};
float CalculateHalfWidth(ScreenBase const & screen, RoadClass const & roadClass, bool left)
{
- double const zoomLevel = GetZoomLevel(screen.GetScale());
- double zoom = trunc(zoomLevel);
- int const index = static_cast<int>(zoom - 1.0);
- float const lerpCoef = static_cast<float>(zoomLevel - zoom);
+ double zoom = 0.0;
+ int index = 0;
+ float lerpCoef = 0.0f;
+ ExtractZoomFactors(screen, zoom, index, lerpCoef);
- float const * widthScalar = nullptr;
+ std::vector<float> const * halfWidth = left ? &kLeftWidthInPixel : &kRightWidthInPixel;
+ float radius = InterpolateByZoomLevels(index, lerpCoef, *halfWidth);
if (roadClass == RoadClass::Class1)
- widthScalar = kRoadClass1WidthScalar;
+ radius *= InterpolateByZoomLevels(index, lerpCoef, kRoadClass1WidthScalar);
else if (roadClass == RoadClass::Class2)
- widthScalar = kRoadClass2WidthScalar;
-
- float const * halfWidth = left ? kLeftWidthInPixel : kRightWidthInPixel;
- float radius = 0.0f;
- if (index < scales::UPPER_STYLE_SCALE)
- {
- radius = halfWidth[index] + lerpCoef * (halfWidth[index + 1] - halfWidth[index]);
- if (widthScalar != nullptr)
- radius *= (widthScalar[index] + lerpCoef * (widthScalar[index + 1] - widthScalar[index]));
- }
- else
- {
- radius = halfWidth[scales::UPPER_STYLE_SCALE];
- if (widthScalar != nullptr)
- radius *= widthScalar[scales::UPPER_STYLE_SCALE];
- }
+ radius *= InterpolateByZoomLevels(index, lerpCoef, kRoadClass2WidthScalar);
return radius * static_cast<float>(VisualParams::Instance().GetVisualScale());
}
-} // namespace
+} // namespace
void TrafficRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng, TrafficRenderData && renderData)
{
@@ -275,16 +261,16 @@ float TrafficRenderer::GetPixelWidthInternal(RoadClass const & roadClass, int zo
{
ASSERT_GREATER(zoomLevel, 1, ());
ASSERT_LESS_OR_EQUAL(zoomLevel, scales::GetUpperStyleScale(), ());
- float const * widthScalar = nullptr;
+ std::vector<float> const * widthScalar = nullptr;
if (roadClass == RoadClass::Class1)
- widthScalar = kRoadClass1WidthScalar;
+ widthScalar = &kRoadClass1WidthScalar;
else if (roadClass == RoadClass::Class2)
- widthScalar = kRoadClass2WidthScalar;
+ widthScalar = &kRoadClass2WidthScalar;
int const index = zoomLevel - 1;
float const baseWidth = (kLeftWidthInPixel[index] + kRightWidthInPixel[index]) *
static_cast<float>(df::VisualParams::Instance().GetVisualScale());
- return (widthScalar != nullptr) ? (baseWidth * widthScalar[index]) : baseWidth;
+ return (widthScalar != nullptr) ? (baseWidth * (*widthScalar)[index]) : baseWidth;
}
// static
@@ -293,7 +279,7 @@ bool TrafficRenderer::CanBeRendereredAsLine(RoadClass const & roadClass, int zoo
if (roadClass == RoadClass::Class0)
return false;
- vector<int> const * lineDrawer = nullptr;
+ std::vector<int> const * lineDrawer = nullptr;
if (roadClass == RoadClass::Class1)
lineDrawer = &kLineDrawerRoadClass1;
else if (roadClass == RoadClass::Class2)
@@ -307,5 +293,4 @@ bool TrafficRenderer::CanBeRendereredAsLine(RoadClass const & roadClass, int zoo
width = max(1, my::rounds(TrafficRenderer::GetPixelWidthInternal(roadClass, zoomLevel)));
return width <= dp::SupportManager::Instance().GetMaxLineWidth();
}
-} // namespace df
-
+} // namespace df
diff --git a/drape_frontend/traffic_renderer.hpp b/drape_frontend/traffic_renderer.hpp
index 222a271538..e79aa65e25 100644
--- a/drape_frontend/traffic_renderer.hpp
+++ b/drape_frontend/traffic_renderer.hpp
@@ -10,11 +10,10 @@
#include "geometry/screenbase.hpp"
#include "geometry/spline.hpp"
-#include "std/vector.hpp"
+#include <vector>
namespace df
{
-
class TrafficRenderer final
{
public:
@@ -43,7 +42,6 @@ private:
static float GetPixelWidth(RoadClass const & roadClass, int zoomLevel);
static float GetPixelWidthInternal(RoadClass const & roadClass, int zoomLevel);
- vector<TrafficRenderData> m_renderData;
+ std::vector<TrafficRenderData> m_renderData;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/visual_params.cpp b/drape_frontend/visual_params.cpp
index e258dadfd9..2ba044fa8f 100644
--- a/drape_frontend/visual_params.cpp
+++ b/drape_frontend/visual_params.cpp
@@ -296,6 +296,23 @@ double GetZoomLevel(double scale)
return my::clamp(fabs(log(scale) / kLog2), 1.0, scales::GetUpperStyleScale() + 1.0);
}
+void ExtractZoomFactors(ScreenBase const & s, double & zoom, int & index, float & lerpCoef)
+{
+ double const zoomLevel = GetZoomLevel(s.GetScale());
+ zoom = trunc(zoomLevel);
+ index = static_cast<int>(zoom - 1.0);
+ lerpCoef = static_cast<float>(zoomLevel - zoom);
+}
+
+float InterpolateByZoomLevels(int index, float lerpCoef, std::vector<float> const & values)
+{
+ ASSERT_GREATER_OR_EQUAL(index, 0, ());
+ ASSERT_GREATER(values.size(), scales::UPPER_STYLE_SCALE, ());
+ if (index < scales::UPPER_STYLE_SCALE)
+ return values[index] + lerpCoef * (values[index + 1] - values[index]);
+ return values[scales::UPPER_STYLE_SCALE];
+}
+
double GetNormalizedZoomLevel(double scale, int minZoom)
{
double const kMaxZoom = scales::GetUpperStyleScale() + 1.0;
diff --git a/drape_frontend/visual_params.hpp b/drape_frontend/visual_params.hpp
index 7f2320b3a5..eb32f284ee 100644
--- a/drape_frontend/visual_params.hpp
+++ b/drape_frontend/visual_params.hpp
@@ -85,6 +85,8 @@ m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center);
uint32_t CalculateTileSize(uint32_t screenWidth, uint32_t screenHeight);
double GetZoomLevel(double scale);
+void ExtractZoomFactors(ScreenBase const & s, double & zoom, int & index, float & lerpCoef);
+float InterpolateByZoomLevels(int index, float lerpCoef, std::vector<float> const & values);
double GetNormalizedZoomLevel(double scale, int minZoom = 1);
double GetScale(double zoomLevel);