|
|
@@ -2,7 +2,7 @@ use context::Context;
|
|
2
|
2
|
use coord::{ScreenRect, SubTileCoord, TileCoord, TextureRect};
|
|
3
|
3
|
use image;
|
|
4
|
4
|
use linked_hash_map::LinkedHashMap;
|
|
5
|
|
-use mercator_view::VisibleTile;
|
|
|
5
|
+use mercator_view;
|
|
6
|
6
|
use std::collections::HashMap;
|
|
7
|
7
|
use std::collections::hash_map::Entry;
|
|
8
|
8
|
use texture::Texture;
|
|
|
@@ -91,7 +91,14 @@ impl TileAtlas {
|
|
91
|
91
|
CacheSlot { x: 0, y: 0 }
|
|
92
|
92
|
}
|
|
93
|
93
|
|
|
94
|
|
- pub fn store(&mut self, cx: &mut Context, tile_coord: TileCoord, source: &TileSource, cache: &mut TileCache, load: bool) -> Option<CacheSlot> {
|
|
|
94
|
+ pub fn store(
|
|
|
95
|
+ &mut self,
|
|
|
96
|
+ cx: &mut Context,
|
|
|
97
|
+ tile_coord: TileCoord,
|
|
|
98
|
+ source: &TileSource,
|
|
|
99
|
+ cache: &mut TileCache,
|
|
|
100
|
+ load: bool
|
|
|
101
|
+ ) -> Option<CacheSlot> {
|
|
95
|
102
|
let mut remove_tile = None;
|
|
96
|
103
|
let tile = Tile::new(tile_coord, source.id());
|
|
97
|
104
|
|
|
|
@@ -146,19 +153,68 @@ impl TileAtlas {
|
|
146
|
153
|
0.5 / f64::from(self.texture.height()))
|
|
147
|
154
|
}
|
|
148
|
155
|
|
|
|
156
|
+ pub fn slot_to_texture_rect(&self, slot: CacheSlot) -> TextureRect {
|
|
|
157
|
+ let scale_x = f64::from(self.tile_size) / f64::from(self.texture.width());
|
|
|
158
|
+ let scale_y = f64::from(self.tile_size) / f64::from(self.texture.height());
|
|
|
159
|
+
|
|
|
160
|
+ TextureRect {
|
|
|
161
|
+ x1: f64::from(slot.x) * scale_x,
|
|
|
162
|
+ y1: f64::from(slot.y) * scale_y,
|
|
|
163
|
+ x2: f64::from(slot.x + 1) * scale_x,
|
|
|
164
|
+ y2: f64::from(slot.y + 1) * scale_y,
|
|
|
165
|
+ }
|
|
|
166
|
+ }
|
|
|
167
|
+
|
|
|
168
|
+ fn subslot_to_texture_rect(&self, slot: CacheSlot, sub_coord: SubTileCoord) -> TextureRect {
|
|
|
169
|
+ let scale_x = f64::from(self.tile_size) / (f64::from(self.texture.width()) *
|
|
|
170
|
+ f64::from(sub_coord.size));
|
|
|
171
|
+ let scale_y = f64::from(self.tile_size) / (f64::from(self.texture.height()) *
|
|
|
172
|
+ f64::from(sub_coord.size));
|
|
|
173
|
+
|
|
|
174
|
+ TextureRect {
|
|
|
175
|
+ x1: f64::from(slot.x * sub_coord.size + sub_coord.x) * scale_x,
|
|
|
176
|
+ y1: f64::from(slot.y * sub_coord.size + sub_coord.y) * scale_y,
|
|
|
177
|
+ x2: f64::from(slot.x * sub_coord.size + sub_coord.x + 1) * scale_x,
|
|
|
178
|
+ y2: f64::from(slot.y * sub_coord.size + sub_coord.y + 1) * scale_y,
|
|
|
179
|
+ }
|
|
|
180
|
+ }
|
|
|
181
|
+
|
|
|
182
|
+ pub fn texture(&self) -> &Texture {
|
|
|
183
|
+ &self.texture
|
|
|
184
|
+ }
|
|
|
185
|
+}
|
|
|
186
|
+
|
|
|
187
|
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
|
188
|
+pub struct CacheSlot {
|
|
|
189
|
+ pub x: u32,
|
|
|
190
|
+ pub y: u32,
|
|
|
191
|
+}
|
|
|
192
|
+
|
|
|
193
|
+pub trait VisibleTilesProvider<T> {
|
|
149
|
194
|
/// Finds textures from the cache for a given slice of visible tiles. The texture atlas may not
|
|
150
|
|
- /// be big enough to hold all textures at once; a possible remainder of untextured visible tiles is
|
|
151
|
|
- /// returned as an `Option`.
|
|
152
|
|
- /// The function guarantees that no more than `max_tiles_to_use` tiles are used for texturing;
|
|
|
195
|
+ /// be big enough to hold all textures at once; a possible remainder of untextured visible
|
|
|
196
|
+ /// tiles is returned as an `Option`.
|
|
|
197
|
+ /// The function should guarantee that no more than `max_tiles_to_use` tiles are used for texturing;
|
|
153
|
198
|
/// the number of used tiles is returned as an `usize`.
|
|
154
|
|
- pub fn textured_visible_tiles<'b>(
|
|
|
199
|
+ fn textured_visible_tiles<'b>(
|
|
|
200
|
+ &mut self,
|
|
|
201
|
+ cx: &mut Context,
|
|
|
202
|
+ visible_tiles: &'b [T],
|
|
|
203
|
+ max_tiles_to_use: usize,
|
|
|
204
|
+ source: &TileSource,
|
|
|
205
|
+ cache: &mut TileCache,
|
|
|
206
|
+ ) -> (Vec<TexturedVisibleTile>, Option<&'b [T]>, usize);
|
|
|
207
|
+}
|
|
|
208
|
+
|
|
|
209
|
+impl VisibleTilesProvider<mercator_view::VisibleTile> for TileAtlas {
|
|
|
210
|
+ fn textured_visible_tiles<'b>(
|
|
155
|
211
|
&mut self,
|
|
156
|
212
|
cx: &mut Context,
|
|
157
|
|
- visible_tiles: &'b [VisibleTile],
|
|
|
213
|
+ visible_tiles: &'b [mercator_view::VisibleTile],
|
|
158
|
214
|
max_tiles_to_use: usize,
|
|
159
|
215
|
source: &TileSource,
|
|
160
|
216
|
cache: &mut TileCache,
|
|
161
|
|
- ) -> (Vec<TexturedVisibleTile>, Option<&'b [VisibleTile]>, usize)
|
|
|
217
|
+ ) -> (Vec<TexturedVisibleTile>, Option<&'b [mercator_view::VisibleTile]>, usize)
|
|
162
|
218
|
{
|
|
163
|
219
|
let mut tvt = Vec::with_capacity(visible_tiles.len());
|
|
164
|
220
|
|
|
|
@@ -210,7 +266,9 @@ impl TileAtlas {
|
|
210
|
266
|
}
|
|
211
|
267
|
|
|
212
|
268
|
// look for cached tiles in higher zoom layers
|
|
213
|
|
- for &(child_tile, child_sub_coord) in &vt.tile.children() {
|
|
|
269
|
+ //TODO Just create one rect (instead of four) if there is no tile from a higher
|
|
|
270
|
+ // zoom level available
|
|
|
271
|
+ for (child_tile, child_sub_coord) in vt.tile.children_iter(1) {
|
|
214
|
272
|
if let Some(slot) = self.store(cx, child_tile, source, cache, false) {
|
|
215
|
273
|
used_slots += 1;
|
|
216
|
274
|
let tex_rect = self.slot_to_texture_rect(slot);
|
|
|
@@ -237,38 +295,4 @@ impl TileAtlas {
|
|
237
|
295
|
|
|
238
|
296
|
(tvt, None, used_slots)
|
|
239
|
297
|
}
|
|
240
|
|
-
|
|
241
|
|
- pub fn slot_to_texture_rect(&self, slot: CacheSlot) -> TextureRect {
|
|
242
|
|
- let scale_x = f64::from(self.tile_size) / f64::from(self.texture.width());
|
|
243
|
|
- let scale_y = f64::from(self.tile_size) / f64::from(self.texture.height());
|
|
244
|
|
-
|
|
245
|
|
- TextureRect {
|
|
246
|
|
- x1: f64::from(slot.x) * scale_x,
|
|
247
|
|
- y1: f64::from(slot.y) * scale_y,
|
|
248
|
|
- x2: f64::from(slot.x + 1) * scale_x,
|
|
249
|
|
- y2: f64::from(slot.y + 1) * scale_y,
|
|
250
|
|
- }
|
|
251
|
|
- }
|
|
252
|
|
-
|
|
253
|
|
- fn subslot_to_texture_rect(&self, slot: CacheSlot, sub_coord: SubTileCoord) -> TextureRect {
|
|
254
|
|
- let scale_x = f64::from(self.tile_size) / (f64::from(self.texture.width()) * f64::from(sub_coord.size));
|
|
255
|
|
- let scale_y = f64::from(self.tile_size) / (f64::from(self.texture.height()) * f64::from(sub_coord.size));
|
|
256
|
|
-
|
|
257
|
|
- TextureRect {
|
|
258
|
|
- x1: f64::from(slot.x * sub_coord.size + sub_coord.x) * scale_x,
|
|
259
|
|
- y1: f64::from(slot.y * sub_coord.size + sub_coord.y) * scale_y,
|
|
260
|
|
- x2: f64::from(slot.x * sub_coord.size + sub_coord.x + 1) * scale_x,
|
|
261
|
|
- y2: f64::from(slot.y * sub_coord.size + sub_coord.y + 1) * scale_y,
|
|
262
|
|
- }
|
|
263
|
|
- }
|
|
264
|
|
-
|
|
265
|
|
- pub fn texture(&self) -> &Texture {
|
|
266
|
|
- &self.texture
|
|
267
|
|
- }
|
|
268
|
|
-}
|
|
269
|
|
-
|
|
270
|
|
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
271
|
|
-pub struct CacheSlot {
|
|
272
|
|
- pub x: u32,
|
|
273
|
|
- pub y: u32,
|
|
274
|
298
|
}
|