1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/// A 2D rectangle with integer coordinates.
///
/// Typically used for texture cutouts etc.
#[derive(Clone, Copy, Debug)]
pub struct RectInt {
    /// The corner with the smallest coordinates.
    ///
    /// In most coordinate spaces this is the to top left corner of the rectangle.
    pub min: glam::IVec2,

    /// The size of the rectangle.
    pub extent: glam::UVec2,
}

impl RectInt {
    #[inline]
    pub fn from_middle_and_extent(middle: glam::IVec2, size: glam::UVec2) -> Self {
        Self {
            min: middle - size.as_ivec2() / 2,
            extent: size,
        }
    }

    #[inline]
    pub fn width(self) -> u32 {
        self.extent.x
    }

    #[inline]
    pub fn height(self) -> u32 {
        self.extent.y
    }

    #[inline]
    pub fn min(self) -> glam::IVec2 {
        self.min
    }

    #[inline]
    pub fn max(self) -> glam::IVec2 {
        self.min + self.extent.as_ivec2()
    }

    #[inline]
    pub fn wgpu_origin(self) -> wgpu::Origin3d {
        wgpu::Origin3d {
            x: self.min.x as u32,
            y: self.min.y as u32,
            z: 0,
        }
    }

    #[inline]
    pub fn wgpu_extent(self) -> wgpu::Extent3d {
        wgpu::Extent3d {
            width: self.extent.x,
            height: self.extent.y,
            depth_or_array_layers: 1,
        }
    }
}

/// A 2D rectangle with float coordinates.
#[derive(Clone, Copy, Debug)]
pub struct RectF32 {
    /// The corner with the smallest coordinates.
    ///
    /// In most coordinate spaces this is the to top left corner of the rectangle.
    pub min: glam::Vec2,

    /// The size of the rectangle. Supposed to be positive.
    pub extent: glam::Vec2,
}

impl RectF32 {
    /// The unit rectangle, defined as (0, 0) - (1, 1).
    pub const UNIT: Self = Self {
        min: glam::Vec2::ZERO,
        extent: glam::Vec2::ONE,
    };

    #[inline]
    pub fn max(self) -> glam::Vec2 {
        self.min + self.extent
    }

    #[inline]
    pub fn center(self) -> glam::Vec2 {
        self.min + self.extent / 2.0
    }

    #[inline]
    pub fn scale_extent(self, factor: f32) -> Self {
        Self {
            min: self.min * factor,
            extent: self.extent * factor,
        }
    }
}

impl From<RectInt> for RectF32 {
    #[inline]
    fn from(rect: RectInt) -> Self {
        Self {
            min: rect.min.as_vec2(),
            extent: rect.extent.as_vec2(),
        }
    }
}