1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
#pragma once
#include "drape_frontend/batchers_pool.hpp"
#include "drape_frontend/color_constants.hpp"
#include "drape_frontend/tile_key.hpp"
#include "drape/color.hpp"
#include "drape/glsl_types.hpp"
#include "drape/glstate.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 "std/array.hpp"
#include "std/map.hpp"
#include "std/set.hpp"
#include "std/string.hpp"
#include "std/vector.hpp"
#include "std/unordered_map.hpp"
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(move(polyline))
, m_roadClass(roadClass)
{}
};
using TrafficSegmentsGeometry = map<MwmSet::MwmId, vector<pair<traffic::TrafficInfo::RoadSegmentId,
TrafficSegmentGeometry>>>;
using TrafficSegmentsColoring = map<MwmSet::MwmId, traffic::TrafficInfo::Coloring>;
struct TrafficRenderData
{
dp::GLState m_state;
drape_ptr<dp::RenderBucket> m_bucket;
TileKey m_tileKey;
MwmSet::MwmId m_mwmId;
RoadClass m_roadClass;
TrafficRenderData(dp::GLState const & state) : m_state(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;
};
using TrafficTexCoords = unordered_map<size_t, glsl::vec2>;
class TrafficGenerator final
{
public:
using TFlushRenderDataFn = function<void (TrafficRenderData && renderData)>;
explicit TrafficGenerator(TFlushRenderDataFn flushFn)
: m_flushRenderDataFn(flushFn)
, m_providerTriangles(1 /* stream count */, 0 /* vertices count*/)
, m_providerLines(1 /* stream count */, 0 /* vertices count*/)
{}
void Init();
void ClearGLDependentResources();
void FlushSegmentsGeometry(TileKey const & tileKey, TrafficSegmentsGeometry const & geom,
ref_ptr<dp::TextureManager> textures);
void UpdateColoring(TrafficSegmentsColoring const & coloring);
void ClearCache();
void ClearCache(MwmSet::MwmId const & mwmId);
void InvalidateTexturesCache();
static void SetSimplifiedColorSchemeEnabled(bool enabled);
static df::ColorConstant GetColorBySpeedGroup(traffic::SpeedGroup const & 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(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter,
bool generateCaps, float depth, float vOffset, float minU,
vector<TrafficStaticVertex> & staticGeometry);
void GenerateLineSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter, float depth,
vector<TrafficLineStaticVertex> & staticGeometry);
void FillColorsCache(ref_ptr<dp::TextureManager> textures);
void FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state,
drape_ptr<dp::RenderBucket> && buffer);
TrafficSegmentsColoring m_coloring;
array<dp::TextureManager::ColorRegion, static_cast<size_t>(traffic::SpeedGroup::Count)> m_colorsCache;
bool m_colorsCacheValid = false;
drape_ptr<BatchersPool<TrafficBatcherKey, TrafficBatcherKeyComparator>> m_batchersPool;
TFlushRenderDataFn m_flushRenderDataFn;
dp::AttributeProvider m_providerTriangles;
dp::AttributeProvider m_providerLines;
static bool m_simplifiedColorScheme;
};
} // namespace df
|