34 lines
1.4 KiB
C++
34 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <cstdint>
|
|
|
|
namespace mbgl::particle {
|
|
|
|
// Internal RGBA8 UNORM field representation. Nearest sampling and highp
|
|
// shader arithmetic reconstruct the byte with floor(sample*255 + 0.5).
|
|
inline uint8_t encodeSignedVelocity8(const float value, const float scale, const bool valid) {
|
|
if (!valid || !std::isfinite(value) || !std::isfinite(scale) || scale <= 0.0f) return 128;
|
|
return static_cast<uint8_t>(128 + static_cast<int>(
|
|
std::lround(std::clamp(value / scale, -1.0f, 1.0f) * 127.0f)));
|
|
}
|
|
|
|
inline float decodeSignedVelocity8(const uint8_t byte, const float scale) {
|
|
return static_cast<float>(static_cast<int>(byte) - 128) * scale / 127.0f;
|
|
}
|
|
|
|
inline std::array<double, 2> mercatorVelocityDelta(const double eastMps,
|
|
const double northMps,
|
|
const double latitudeDegrees,
|
|
const double visualSeconds) {
|
|
constexpr double circumference = 40075016.68557849;
|
|
constexpr double radiansPerDegree = 3.14159265358979323846 / 180.0;
|
|
const double cosine = std::max(std::cos(latitudeDegrees * radiansPerDegree), 0.01);
|
|
return {{eastMps * visualSeconds / (circumference * cosine),
|
|
-northMps * visualSeconds / (circumference * cosine)}};
|
|
}
|
|
|
|
} // namespace mbgl::particle
|