Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_sprite/src/texture_slice/mod.rs
6600 views
1
mod border_rect;
2
mod slicer;
3
4
use bevy_math::{Rect, Vec2};
5
pub use border_rect::BorderRect;
6
pub use slicer::{SliceScaleMode, TextureSlicer};
7
8
/// Single texture slice, representing a texture rect to draw in a given area
9
#[derive(Debug, Clone, PartialEq)]
10
pub struct TextureSlice {
11
/// texture area to draw
12
pub texture_rect: Rect,
13
/// slice draw size
14
pub draw_size: Vec2,
15
/// offset of the slice
16
pub offset: Vec2,
17
}
18
19
impl TextureSlice {
20
/// Transforms the given slice in a collection of tiled subdivisions.
21
///
22
/// # Arguments
23
///
24
/// * `stretch_value` - The slice will repeat when the ratio between the *drawing dimensions* of texture and the
25
/// *original texture size* (rect) are above `stretch_value`.
26
/// * `tile_x` - should the slice be tiled horizontally
27
/// * `tile_y` - should the slice be tiled vertically
28
#[must_use]
29
pub fn tiled(self, stretch_value: f32, (tile_x, tile_y): (bool, bool)) -> Vec<Self> {
30
if !tile_x && !tile_y {
31
return vec![self];
32
}
33
let stretch_value = stretch_value.max(0.001);
34
let rect_size = self.texture_rect.size();
35
// Each tile expected size
36
let expected_size = Vec2::new(
37
if tile_x {
38
// No slice should be less than 1 pixel wide
39
(rect_size.x * stretch_value).max(1.0)
40
} else {
41
self.draw_size.x
42
},
43
if tile_y {
44
// No slice should be less than 1 pixel high
45
(rect_size.y * stretch_value).max(1.0)
46
} else {
47
self.draw_size.y
48
},
49
)
50
.min(self.draw_size);
51
let mut slices = Vec::new();
52
let base_offset = Vec2::new(
53
-self.draw_size.x / 2.0,
54
self.draw_size.y / 2.0, // Start from top
55
);
56
let mut offset = base_offset;
57
58
let mut remaining_columns = self.draw_size.y;
59
while remaining_columns > 0.0 {
60
let size_y = expected_size.y.min(remaining_columns);
61
offset.x = base_offset.x;
62
offset.y -= size_y / 2.0;
63
let mut remaining_rows = self.draw_size.x;
64
while remaining_rows > 0.0 {
65
let size_x = expected_size.x.min(remaining_rows);
66
offset.x += size_x / 2.0;
67
let draw_size = Vec2::new(size_x, size_y);
68
let delta = draw_size / expected_size;
69
slices.push(Self {
70
texture_rect: Rect {
71
min: self.texture_rect.min,
72
max: self.texture_rect.min + self.texture_rect.size() * delta,
73
},
74
draw_size,
75
offset: self.offset + offset,
76
});
77
offset.x += size_x / 2.0;
78
remaining_rows -= size_x;
79
}
80
offset.y -= size_y / 2.0;
81
remaining_columns -= size_y;
82
}
83
if slices.len() > 1_000 {
84
tracing::warn!("One of your tiled textures has generated {} slices. You might want to use higher stretch values to avoid a great performance cost", slices.len());
85
}
86
slices
87
}
88
}
89
90