use std::hash::Hash;
use glam::Vec2;
use ordered_float::OrderedFloat;
use crate::{color::Color, handle::Handle};
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Rect {
pub min: Vec2,
pub max: Vec2,
}
impl Rect {
pub fn new(center: Vec2, radius: f32) -> Self {
Self {
min: center - Vec2::splat(radius),
max: center + Vec2::splat(radius),
}
}
pub fn is_touching(&self, other: &Self) -> bool {
!(self.min.x > other.max.x
|| self.max.x < other.min.x
|| self.min.y > other.max.y
|| self.max.y < other.min.y)
}
pub fn contains_pos(&self, pos: Vec2) -> bool {
let Rect { min, max } = self;
pos.x >= min.x && pos.y >= min.y && pos.x <= max.x && pos.y <= max.y
}
pub fn center(&self) -> Vec2 {
(self.min + self.max) * 0.5
}
pub fn size(&self) -> Vec2 {
self.max - self.min
}
pub fn overlap(&self, other: &Self) -> Vec2 {
(self.max - other.min).min(other.max - self.min)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LinePattern {
Solid,
Dashed { dash_length: f32, gap_length: f32 },
Dotted { spacing: f32 },
}
#[derive(Debug, Clone)]
pub struct Line {
pub start: Vec2,
pub end: Vec2,
pub thickness: f32,
pub color: Color,
}
#[derive(Debug, Clone)]
pub(crate) enum DrawContent {
Texture {
handle: Handle,
color: Color,
},
Lines(Vec<Line>),
Circle {
radius: f32,
color: Color,
},
Polygon {
vertices: Vec<Vec2>,
color: Color,
},
PolygonTextured {
vertices: Vec<Vec2>,
uvs: Vec<Vec2>,
color: Color,
handle: Handle,
},
}
impl DrawContent {
pub fn texture_handle(&self) -> Option<&Handle> {
if let Self::Texture { handle, .. } = self {
Some(handle)
} else if let Self::PolygonTextured { handle, .. } = self {
Some(handle)
} else {
None
}
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct LineCacheKey {
start: [OrderedFloat<f32>; 2],
end: [OrderedFloat<f32>; 2],
thickness: OrderedFloat<f32>,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum DrawContentCacheKey {
Texture {
handle: u64,
},
Lines(Vec<LineCacheKey>),
Circle {
radius: OrderedFloat<f32>,
},
Polygon(Vec<[OrderedFloat<f32>; 2]>),
PolygonTextured {
handle: u64,
vertices: Vec<[OrderedFloat<f32>; 2]>,
uvs: Vec<[OrderedFloat<f32>; 2]>,
},
}
impl From<DrawContent> for DrawContentCacheKey {
fn from(value: DrawContent) -> Self {
match value {
DrawContent::Texture { handle, color: _ } => Self::Texture {
handle: handle.id(),
},
DrawContent::Lines(lines) => Self::Lines(
lines
.into_iter()
.map(
|Line {
start,
end,
thickness,
color: _,
}| {
LineCacheKey {
start: [start.x.into(), start.y.into()],
end: [end.x.into(), end.y.into()],
thickness: thickness.into(),
}
},
)
.collect(),
),
DrawContent::Circle { radius, color: _ } => Self::Circle {
radius: radius.into(),
},
DrawContent::Polygon { vertices, color: _ } => Self::Polygon(
vertices
.into_iter()
.map(|Vec2 { x, y }| [OrderedFloat(x), OrderedFloat(y)])
.collect(),
),
DrawContent::PolygonTextured {
vertices,
uvs,
handle,
color: _,
} => Self::PolygonTextured {
handle: handle.id(),
vertices: vertices
.into_iter()
.map(|Vec2 { x, y }| [OrderedFloat(x), OrderedFloat(y)])
.collect(),
uvs: uvs
.into_iter()
.map(|Vec2 { x, y }| [OrderedFloat(x), OrderedFloat(y)])
.collect(),
},
}
}
}