250 lines
8.4 KiB
C++
250 lines
8.4 KiB
C++
#pragma once
|
|
|
|
#include "drape_frontend/color_constants.hpp"
|
|
#include "drape_frontend/map_shape.hpp"
|
|
#include "drape_frontend/render_state_extension.hpp"
|
|
#include "drape_frontend/shape_view_params.hpp"
|
|
|
|
#include "drape/pointers.hpp"
|
|
#include "drape/render_bucket.hpp"
|
|
#include "drape/utils/vertex_decl.hpp"
|
|
|
|
#include "traffic/speed_groups.hpp"
|
|
|
|
#include "geometry/polyline2d.hpp"
|
|
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace df
|
|
{
|
|
double constexpr kArrowSize = 0.0008;
|
|
|
|
// Constants below depend on arrow texture.
|
|
double constexpr kArrowTextureWidth = 74.0;
|
|
double constexpr kArrowTextureHeight = 44.0;
|
|
double constexpr kArrowBodyHeight = 24.0;
|
|
double constexpr kArrowHeadTextureWidth = 32.0;
|
|
double constexpr kArrowTailTextureWidth = 4.0;
|
|
|
|
double constexpr kArrowHeadSize = kArrowHeadTextureWidth / kArrowTextureWidth;
|
|
float constexpr kArrowHeadFactor = static_cast<float>(2.0 * kArrowHeadTextureWidth / kArrowTextureHeight);
|
|
double constexpr kArrowTailSize = kArrowTailTextureWidth / kArrowTextureWidth;
|
|
float constexpr kArrowTailFactor = static_cast<float>(2.0 * kArrowTailTextureWidth / kArrowTextureHeight);
|
|
double constexpr kArrowHeightFactor = kArrowTextureHeight / kArrowBodyHeight;
|
|
double constexpr kArrowAspect = kArrowTextureWidth / kArrowTextureHeight;
|
|
|
|
std::array<float, 20> constexpr kRouteHalfWidthInPixelCar = {
|
|
// 1 2 3 4 5 6 7 8 9 10
|
|
1.0f, 1.2f, 1.5f, 1.5f, 1.7f, 2.0f, 2.0f, 2.3f, 2.5f, 2.7f,
|
|
// 11 12 13 14 15 16 17 18 19 20
|
|
3.0f, 3.5f, 4.5f, 5.5f, 7.0, 9.0f, 10.0f, 14.0f, 22.0f, 27.0f};
|
|
|
|
std::array<float, 20> constexpr kRouteHalfWidthInPixelTransit = {
|
|
// 1 2 3 4 5 6 7 8 9 10
|
|
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.7f,
|
|
// 11 12 13 14 15 16 17 18 19 20
|
|
1.8f, 2.1f, 2.5f, 2.8f, 3.5, 4.5f, 5.0f, 7.0f, 11.0f, 13.0f};
|
|
|
|
std::array<float, 20> constexpr kRouteHalfWidthInPixelOthers = {
|
|
// 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.1f, 1.2f, 1.3f,
|
|
// 11 12 13 14 15 16 17 18 19 20
|
|
1.5f, 1.7f, 2.3f, 2.7f, 3.5, 4.5f, 5.0f, 7.0f, 11.0f, 13.0f};
|
|
|
|
enum class RouteType : uint8_t
|
|
{
|
|
Car,
|
|
Pedestrian,
|
|
Bicycle,
|
|
Taxi,
|
|
Transit,
|
|
Ruler
|
|
};
|
|
|
|
struct RoutePattern
|
|
{
|
|
RoutePattern() = default;
|
|
|
|
RoutePattern(double dashLength, double gapLength) : m_isDashed(true), m_dashLength(dashLength), m_gapLength(gapLength)
|
|
{}
|
|
|
|
bool operator==(RoutePattern const & pattern) const
|
|
{
|
|
double constexpr kEps = 1e-5;
|
|
return m_isDashed == pattern.m_isDashed && std::fabs(m_dashLength - pattern.m_dashLength) < kEps &&
|
|
std::fabs(m_gapLength - pattern.m_gapLength) < kEps;
|
|
}
|
|
|
|
bool m_isDashed = false;
|
|
double m_dashLength = 0.0;
|
|
double m_gapLength = 0.0;
|
|
};
|
|
|
|
enum class SubrouteStyleType
|
|
{
|
|
Single = 0,
|
|
Multiple
|
|
};
|
|
|
|
struct SubrouteStyle
|
|
{
|
|
SubrouteStyle() = default;
|
|
explicit SubrouteStyle(df::ColorConstant const & color) : m_color(color), m_outlineColor(color) {}
|
|
SubrouteStyle(df::ColorConstant const & color, df::ColorConstant const & outlineColor)
|
|
: m_color(color)
|
|
, m_outlineColor(outlineColor)
|
|
{}
|
|
SubrouteStyle(df::ColorConstant const & color, df::RoutePattern const & pattern)
|
|
: m_color(color)
|
|
, m_outlineColor(color)
|
|
, m_pattern(pattern)
|
|
{}
|
|
SubrouteStyle(df::ColorConstant const & color, df::ColorConstant const & outlineColor,
|
|
df::RoutePattern const & pattern)
|
|
: m_color(color)
|
|
, m_outlineColor(outlineColor)
|
|
, m_pattern(pattern)
|
|
{}
|
|
|
|
bool operator==(SubrouteStyle const & style) const
|
|
{
|
|
return m_color == style.m_color && m_outlineColor == style.m_outlineColor && m_pattern == style.m_pattern;
|
|
}
|
|
|
|
bool operator!=(SubrouteStyle const & style) const { return !operator==(style); }
|
|
|
|
df::ColorConstant m_color;
|
|
df::ColorConstant m_outlineColor;
|
|
df::RoutePattern m_pattern;
|
|
size_t m_startIndex = 0;
|
|
size_t m_endIndex = 0;
|
|
};
|
|
|
|
// Colored circle on the subroute.
|
|
struct SubrouteMarker
|
|
{
|
|
// Position in mercator.
|
|
m2::PointD m_position = {};
|
|
// Distance from the beginning of route.
|
|
double m_distance = 0.0;
|
|
// Array of colors in range [0;2].
|
|
std::vector<df::ColorConstant> m_colors;
|
|
// Color of inner circle.
|
|
df::ColorConstant m_innerColor;
|
|
// Normalized up vector to determine rotation of circle.
|
|
m2::PointD m_up = m2::PointD(0.0, 1.0);
|
|
// Scale (1.0 when the radius is equal to route line half-width).
|
|
float m_scale = 1.0f;
|
|
};
|
|
|
|
struct Subroute
|
|
{
|
|
void AddStyle(SubrouteStyle const & style);
|
|
|
|
df::RouteType m_routeType;
|
|
m2::PolylineD m_polyline;
|
|
std::vector<double> m_turns;
|
|
std::vector<traffic::SpeedGroup> m_traffic;
|
|
double m_baseDistance = 0.0;
|
|
double m_baseDepthIndex = 0.0;
|
|
float m_maxPixelWidth = -1.0f;
|
|
|
|
SubrouteStyleType m_styleType = SubrouteStyleType::Single;
|
|
std::vector<SubrouteStyle> m_style;
|
|
|
|
std::vector<SubrouteMarker> m_markers;
|
|
|
|
double m_headFakeDistance = 0.0;
|
|
double m_tailFakeDistance = 0.0;
|
|
};
|
|
|
|
using SubrouteConstPtr = std::shared_ptr<Subroute const>;
|
|
|
|
struct RouteRenderProperty
|
|
{
|
|
RouteRenderProperty() : m_state(CreateRenderState(gpu::Program::Route, DepthLayer::GeometryLayer)) {}
|
|
|
|
dp::RenderState m_state;
|
|
std::vector<drape_ptr<dp::RenderBucket>> m_buckets;
|
|
std::vector<m2::RectD> m_boundingBoxes;
|
|
};
|
|
|
|
struct BaseSubrouteData
|
|
{
|
|
dp::DrapeID m_subrouteId = 0;
|
|
m2::PointD m_pivot = m2::PointD(0.0, 0.0);
|
|
int m_recacheId = -1;
|
|
RouteRenderProperty m_renderProperty;
|
|
};
|
|
|
|
struct SubrouteData : public BaseSubrouteData
|
|
{
|
|
SubrouteConstPtr m_subroute;
|
|
size_t m_startPointIndex = 0;
|
|
size_t m_endPointIndex = 0;
|
|
size_t m_styleIndex = 0;
|
|
double m_distanceOffset = 0.0;
|
|
};
|
|
|
|
struct SubrouteArrowsData : public BaseSubrouteData
|
|
{};
|
|
|
|
struct SubrouteMarkersData : public BaseSubrouteData
|
|
{};
|
|
|
|
struct ArrowBorders
|
|
{
|
|
double m_startDistance = 0.0;
|
|
double m_endDistance = 0.0;
|
|
int m_groupIndex = 0;
|
|
};
|
|
|
|
class RouteShape
|
|
{
|
|
public:
|
|
using RV = gpu::RouteVertex;
|
|
using GeometryBuffer = gpu::VBUnknownSizeT<RV>;
|
|
using AV = gpu::SolidTexturingVertex;
|
|
using ArrowGeometryBuffer = gpu::VBUnknownSizeT<AV>;
|
|
using MV = gpu::RouteMarkerVertex;
|
|
using MarkersGeometryBuffer = gpu::VBUnknownSizeT<MV>;
|
|
|
|
static drape_ptr<df::SubrouteData> CacheRoute(ref_ptr<dp::GraphicsContext> context, dp::DrapeID subrouteId,
|
|
SubrouteConstPtr subroute, size_t styleIndex, int recacheId);
|
|
|
|
static drape_ptr<df::SubrouteMarkersData> CacheMarkers(ref_ptr<dp::GraphicsContext> context, dp::DrapeID subrouteId,
|
|
SubrouteConstPtr subroute, int recacheId,
|
|
ref_ptr<dp::TextureManager> textures);
|
|
|
|
static void CacheRouteArrows(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> mng,
|
|
m2::PolylineD const & polyline, std::vector<ArrowBorders> const & borders,
|
|
double baseDepthIndex, SubrouteArrowsData & routeArrowsData);
|
|
|
|
private:
|
|
template <typename GeometryBufferType>
|
|
struct GeometryBufferData
|
|
{
|
|
GeometryBufferData() : m_boundingBox(m2::RectD::GetEmptyRect()) {}
|
|
|
|
GeometryBufferType m_geometry;
|
|
GeometryBufferType m_joinsGeometry;
|
|
m2::RectD m_boundingBox;
|
|
};
|
|
static void PrepareGeometry(std::vector<m2::PointD> const & path, m2::PointD const & pivot,
|
|
std::vector<glsl::vec4> const & segmentsColors, float baseDepth,
|
|
std::vector<GeometryBufferData<GeometryBuffer>> & geometryBufferData);
|
|
static void PrepareArrowGeometry(std::vector<m2::PointD> const & path, m2::PointD const & pivot,
|
|
m2::RectF const & texRect, float depthStep, float depth,
|
|
GeometryBufferData<ArrowGeometryBuffer> & geometryBufferData);
|
|
static void PrepareMarkersGeometry(std::vector<SubrouteMarker> const & markers, m2::PointD const & pivot,
|
|
float baseDepth, MarkersGeometryBuffer & geometry);
|
|
|
|
static void BatchGeometry(ref_ptr<dp::GraphicsContext> context, dp::RenderState const & state, ref_ptr<void> geometry,
|
|
uint32_t geomSize, ref_ptr<void> joinsGeometry, uint32_t joinsGeomSize,
|
|
m2::RectD const & boundingBox, dp::BindingInfo const & bindingInfo,
|
|
RouteRenderProperty & property);
|
|
};
|
|
} // namespace df
|