* Clamp the smooth scroll to a maxmimum speed and distance based on time elapsed. * * Every 30ms, we move 1/4th of the distance, to give a smooth movement experience. * But we never go over the max_scroll speed. * * @param delta_ms Time elapsed since last update. * @param delta_hi The distance to move in highest dimension (can't be zero). * @param delta_lo The distance to move in lowest dim
| 1958 | * @param[out] delta_lo_clamped The clamped distance to move in lowest dimension. |
| 1959 | */ |
| 1960 | static void ClampSmoothScroll(uint32_t delta_ms, int64_t delta_hi, int64_t delta_lo, int &delta_hi_clamped, int &delta_lo_clamped) |
| 1961 | { |
| 1962 | /** A tile is 64 pixels in width at 1x zoom; viewport coordinates are in 4x zoom. */ |
| 1963 | constexpr int PIXELS_PER_TILE = TILE_PIXELS * 2 * ZOOM_BASE; |
| 1964 | |
| 1965 | assert(delta_hi != 0); |
| 1966 | |
| 1967 | /* Move at most 75% of the distance every 30ms, for a smooth experience */ |
| 1968 | int64_t delta_left = delta_hi * std::pow(0.75, delta_ms / 30.0); |
| 1969 | /* Move never more than 16 tiles per 30ms. */ |
| 1970 | int max_scroll = Map::ScaleBySize1D(16 * PIXELS_PER_TILE * delta_ms / 30); |
| 1971 | |
| 1972 | /* We never go over the max_scroll speed. */ |
| 1973 | delta_hi_clamped = Clamp(delta_hi - delta_left, -max_scroll, max_scroll); |
| 1974 | /* The lower delta is in ratio of the higher delta, so we keep going straight at the destination. */ |
| 1975 | delta_lo_clamped = delta_lo * delta_hi_clamped / delta_hi; |
| 1976 | |
| 1977 | /* Ensure we always move (delta_hi can't be zero). */ |
| 1978 | if (delta_hi_clamped == 0) { |
| 1979 | delta_hi_clamped = delta_hi > 0 ? 1 : -1; |
| 1980 | } |
| 1981 | } |
| 1982 | |
| 1983 | /** |
| 1984 | * Update the viewport position being displayed. |
no test coverage detected