| 99 | } |
| 100 | |
| 101 | uint64_t TileKey::GetHashValue(BatcherBucket bucket) const |
| 102 | { |
| 103 | // Format (from most significant to least): |
| 104 | // 8 bit - generation mod 2^8; |
| 105 | // 8 bit - user marks generation mod 2^8; |
| 106 | // 5 bit - zoom level; |
| 107 | // 20 bit - y; |
| 108 | // 20 bit - x; |
| 109 | // 3 bit - bucket. |
| 110 | |
| 111 | uint8_t constexpr kCoordsBits = 20; |
| 112 | uint8_t constexpr kZoomBits = 5; |
| 113 | uint8_t constexpr kGenerationBits = 8; |
| 114 | uint8_t constexpr kBucketBits = 3; |
| 115 | uint32_t constexpr kCoordsMask = GetMask(kCoordsBits); |
| 116 | uint32_t constexpr kZoomMask = GetMask(kZoomBits); |
| 117 | uint32_t constexpr kBucketMask = GetMask(kBucketBits); |
| 118 | uint32_t constexpr kGenerationMod = 1 << kGenerationBits; |
| 119 | |
| 120 | // Transform [-b, b] coordinates range -> [0, 2b] positive coordinates range. |
| 121 | int constexpr kCoordsOffset = 1 << (kCoordsBits - 1); |
| 122 | CHECK(abs(m_x) <= kCoordsOffset, (m_x)); |
| 123 | CHECK(abs(m_y) <= kCoordsOffset, (m_y)); |
| 124 | auto const x = static_cast<uint64_t>(m_x + kCoordsOffset) & kCoordsMask; |
| 125 | auto const y = static_cast<uint64_t>(m_y + kCoordsOffset) & kCoordsMask; |
| 126 | |
| 127 | CHECK(m_zoomLevel <= kZoomMask, (m_zoomLevel)); |
| 128 | uint64_t const zoom = static_cast<uint64_t>(m_zoomLevel) & kZoomMask; |
| 129 | |
| 130 | auto const umg = static_cast<uint64_t>(m_userMarksGeneration % kGenerationMod); |
| 131 | auto const g = static_cast<uint64_t>(m_generation % kGenerationMod); |
| 132 | |
| 133 | auto const hash = x | (y << kCoordsBits) | (zoom << (2 * kCoordsBits)) | (umg << (2 * kCoordsBits + kZoomBits)) | |
| 134 | (g << (2 * kCoordsBits + kZoomBits + kGenerationBits)); |
| 135 | |
| 136 | return (hash << kBucketBits) | (static_cast<uint64_t>(bucket) & kBucketMask); |
| 137 | } |
| 138 | |
| 139 | math::Matrix<float, 4, 4> TileKey::GetTileBasedModelView(ScreenBase const & screen) const |
| 140 | { |
no test coverage detected