#pragma once #include "drape_frontend/batchers_pool.hpp" #include "drape_frontend/color_constants.hpp" #include "drape_frontend/render_state_extension.hpp" #include "drape_frontend/tile_key.hpp" #include "drape/color.hpp" #include "drape/glsl_types.hpp" #include "drape/render_bucket.hpp" #include "drape/texture_manager.hpp" #include "traffic/traffic_info.hpp" #include "indexer/feature_decl.hpp" #include "geometry/polyline2d.hpp" #include #include #include #include #include namespace dp { class GraphicsContext; } // namespace dp namespace df { enum class RoadClass : uint8_t { Class0, Class1, Class2 }; int constexpr kRoadClass0ZoomLevel = 10; int constexpr kRoadClass1ZoomLevel = 12; int constexpr kRoadClass2ZoomLevel = 15; struct TrafficSegmentID { MwmSet::MwmId m_mwmId; traffic::TrafficInfo::RoadSegmentId m_segmentId; TrafficSegmentID(MwmSet::MwmId const & mwmId, traffic::TrafficInfo::RoadSegmentId const & segmentId) : m_mwmId(mwmId) , m_segmentId(segmentId) {} inline bool operator<(TrafficSegmentID const & r) const { if (m_mwmId == r.m_mwmId) return m_segmentId < r.m_segmentId; return m_mwmId < r.m_mwmId; } inline bool operator==(TrafficSegmentID const & r) const { return (m_mwmId == r.m_mwmId && m_segmentId == r.m_segmentId); } inline bool operator!=(TrafficSegmentID const & r) const { return !(*this == r); } }; struct TrafficSegmentGeometry { m2::PolylineD m_polyline; RoadClass m_roadClass; TrafficSegmentGeometry(m2::PolylineD && polyline, RoadClass const & roadClass) : m_polyline(std::move(polyline)) , m_roadClass(roadClass) {} }; using TrafficSegmentsGeometryValue = std::vector>; using TrafficSegmentsGeometry = std::map; using TrafficSegmentsColoring = std::map; struct TrafficRenderData { dp::RenderState m_state; drape_ptr m_bucket; TileKey m_tileKey; MwmSet::MwmId m_mwmId; RoadClass m_roadClass = RoadClass::Class0; explicit TrafficRenderData(dp::RenderState const & state) : m_state(state) {} bool operator<(TrafficRenderData const & renderData) const { if (m_roadClass != renderData.m_roadClass) return m_roadClass > renderData.m_roadClass; return m_state < renderData.m_state; } }; struct TrafficStaticVertex { using TPosition = glsl::vec3; using TNormal = glsl::vec4; using TTexCoord = glsl::vec4; TrafficStaticVertex() = default; TrafficStaticVertex(TPosition const & position, TNormal const & normal, TTexCoord const & colorTexCoord) : m_position(position) , m_normal(normal) , m_colorTexCoord(colorTexCoord) {} TPosition m_position; TNormal m_normal; TTexCoord m_colorTexCoord; }; struct TrafficLineStaticVertex { using TPosition = glsl::vec3; using TTexCoord = glsl::vec2; TrafficLineStaticVertex() = default; TrafficLineStaticVertex(TPosition const & position, TTexCoord const & colorTexCoord) : m_position(position) , m_colorTexCoord(colorTexCoord) {} TPosition m_position; TTexCoord m_colorTexCoord; }; struct TrafficCircleStaticVertex { using TPosition = glsl::vec4; using TNormal = glsl::vec4; using TTexCoord = glsl::vec2; TrafficCircleStaticVertex() = default; TrafficCircleStaticVertex(TPosition const & position, TNormal const & normal, TTexCoord const & colorTexCoord) : m_position(position) , m_normal(normal) , m_colorTexCoord(colorTexCoord) {} TPosition m_position; TNormal m_normal; TTexCoord m_colorTexCoord; }; using TrafficTexCoords = std::unordered_map; class TrafficGenerator final { public: using FlushRenderDataFn = std::function; explicit TrafficGenerator(FlushRenderDataFn flushFn) : m_flushRenderDataFn(std::move(flushFn)) , m_providerTriangles(1 /* stream count */, 0 /* vertices count*/) , m_providerLines(1 /* stream count */, 0 /* vertices count*/) , m_providerCircles(1 /* stream count */, 0 /* vertices count*/) {} void Init(); void ClearContextDependentResources(); void FlushSegmentsGeometry(ref_ptr context, TileKey const & tileKey, TrafficSegmentsGeometry const & geom, ref_ptr textures); void UpdateColoring(TrafficSegmentsColoring const & coloring); void ClearCache(); void ClearCache(MwmSet::MwmId const & mwmId); void InvalidateTexturesCache(); static void SetSimplifiedColorSchemeEnabled(bool enabled); static traffic::SpeedGroup CheckColorsSimplification(traffic::SpeedGroup speedGroup); static df::ColorConstant GetColorBySpeedGroup(traffic::SpeedGroup speedGroup, bool route); private: struct TrafficBatcherKey { TrafficBatcherKey() = default; TrafficBatcherKey(MwmSet::MwmId const & mwmId, TileKey const & tileKey, RoadClass const & roadClass) : m_mwmId(mwmId) , m_tileKey(tileKey) , m_roadClass(roadClass) {} MwmSet::MwmId m_mwmId; TileKey m_tileKey; RoadClass m_roadClass; }; struct TrafficBatcherKeyComparator { bool operator()(TrafficBatcherKey const & lhs, TrafficBatcherKey const & rhs) const { if (lhs.m_mwmId == rhs.m_mwmId) { if (lhs.m_tileKey.EqualStrict(rhs.m_tileKey)) return lhs.m_roadClass < rhs.m_roadClass; return lhs.m_tileKey.LessStrict(rhs.m_tileKey); } return lhs.m_mwmId < rhs.m_mwmId; } }; void GenerateSegment(RoadClass roadClass, dp::TextureManager::ColorRegion const & colorRegion, m2::PolylineD const & polyline, m2::PointD const & tileCenter, bool generateCircles, float depth, float vOffset, float minU, bool isLeftHand, std::vector & staticGeometry, std::vector & circlesGeometry); void GenerateLineSegment(dp::TextureManager::ColorRegion const & colorRegion, m2::PolylineD const & polyline, m2::PointD const & tileCenter, float depth, std::vector & staticGeometry); void FillColorsCache(ref_ptr textures); void FlushGeometry(TrafficBatcherKey const & key, dp::RenderState const & state, drape_ptr && buffer); void GenerateSegmentsGeometry(ref_ptr context, MwmSet::MwmId const & mwmId, TileKey const & tileKey, TrafficSegmentsGeometryValue const & geometry, traffic::TrafficInfo::Coloring const & coloring, ref_ptr texturesMgr); TrafficSegmentsColoring m_coloring; std::array(traffic::SpeedGroup::Count)> m_colorsCache; bool m_colorsCacheValid = false; using BatcherPoolType = BatchersPool; drape_ptr m_batchersPool; drape_ptr m_circlesBatcher; FlushRenderDataFn m_flushRenderDataFn; dp::AttributeProvider m_providerTriangles; dp::AttributeProvider m_providerLines; dp::AttributeProvider m_providerCircles; static bool m_simplifiedColorScheme; }; } // namespace df