use crate::GeoId;
use uuid::Uuid;
use vek::Mat3;
#[derive(Debug, Clone)]
pub struct Poly2D {
pub id: GeoId,
pub tile_id: Uuid,
pub tile_id2: Option<Uuid>,
pub blend_weights: Vec<f32>, pub vertices: Vec<[f32; 2]>,
pub uvs: Vec<[f32; 2]>,
pub indices: Vec<(usize, usize, usize)>, pub transform: Mat3<f32>, pub layer: i32, pub visible: bool, }
impl Default for Poly2D {
fn default() -> Self {
Self {
id: GeoId::Unknown(0),
tile_id: Uuid::nil(),
tile_id2: None,
blend_weights: Vec::new(),
vertices: Vec::new(),
uvs: Vec::new(),
indices: Vec::new(),
transform: Mat3::identity(),
layer: 0,
visible: true,
}
}
}
impl Poly2D {
pub fn poly(
id: GeoId,
tile_id: Uuid,
vertices: Vec<[f32; 2]>,
uvs: Vec<[f32; 2]>,
indices: Vec<(usize, usize, usize)>,
) -> Self {
Self {
id,
tile_id,
tile_id2: None,
blend_weights: Vec::new(),
vertices,
uvs,
indices,
transform: Mat3::identity(),
layer: 0,
visible: true,
}
}
pub fn line(id: GeoId, tile_id: Uuid, points: Vec<[f32; 2]>, width: f32, layer: i32) -> Self {
let half = 0.5 * width;
let valid_segments = points.len().saturating_sub(1);
let mut vertices: Vec<[f32; 2]> = Vec::with_capacity(valid_segments * 4);
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(valid_segments * 4);
let mut indices: Vec<(usize, usize, usize)> = Vec::with_capacity(valid_segments * 2);
for seg in 0..(points.len() - 1) {
let p0 = points[seg];
let p1 = points[seg + 1];
let dx = p1[0] - p0[0];
let dy = p1[1] - p0[1];
let len = (dx * dx + dy * dy).sqrt();
if len == 0.0 {
continue;
}
let nx = -dy / len; let ny = dx / len;
let ox = nx * half;
let oy = ny * half;
let v0 = [p0[0] - ox, p0[1] - oy]; let v1 = [p0[0] + ox, p0[1] + oy]; let v2 = [p1[0] + ox, p1[1] + oy]; let v3 = [p1[0] - ox, p1[1] - oy];
let base = vertices.len();
vertices.extend_from_slice(&[v0, v1, v2, v3]);
uvs.extend_from_slice(&[[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]]);
indices.extend_from_slice(&[
(base + 0, base + 1, base + 2),
(base + 0, base + 2, base + 3),
]);
}
Self {
id,
tile_id,
tile_id2: None,
blend_weights: Vec::new(),
vertices,
uvs,
indices,
transform: Mat3::identity(),
layer,
visible: true,
}
}
pub fn quad(
id: GeoId,
tile_id: Uuid,
center: [f32; 2],
size: f32,
layer: i32,
visible: bool,
) -> Self {
let half = 0.5 * size;
let (cx, cy) = (center[0], center[1]);
let x0 = cx - half; let x1 = cx + half; let y0 = cy - half; let y1 = cy + half;
let mut vertices = Vec::with_capacity(4);
let mut uvs = Vec::with_capacity(4);
let mut indices = Vec::with_capacity(2);
vertices.extend_from_slice(&[
[x0, y0], [x0, y1], [x1, y1], [x1, y0], ]);
uvs.extend_from_slice(&[[0.0, 0.0], [0.0, 1.0], [1.0, 1.0], [1.0, 0.0]]);
indices.extend_from_slice(&[(0, 1, 2), (0, 2, 3)]);
Self {
id,
tile_id,
tile_id2: None,
blend_weights: Vec::new(),
vertices,
uvs,
indices,
transform: Mat3::identity(),
layer,
visible,
}
}
pub fn with_id(mut self, id: GeoId) -> Self {
self.id = id;
self
}
pub fn with_tile_id(mut self, tile_id: Uuid) -> Self {
self.tile_id = tile_id;
self
}
pub fn with_tile_id2(mut self, tile_id2: Option<Uuid>) -> Self {
self.tile_id2 = tile_id2;
self
}
pub fn with_blend_weights(mut self, blend_weights: Vec<f32>) -> Self {
self.blend_weights = blend_weights;
self
}
pub fn with_vertices(mut self, vertices: Vec<[f32; 2]>) -> Self {
self.vertices = vertices;
self
}
pub fn with_uvs(mut self, uvs: Vec<[f32; 2]>) -> Self {
self.uvs = uvs;
self
}
pub fn with_indices(mut self, indices: Vec<(usize, usize, usize)>) -> Self {
self.indices = indices;
self
}
pub fn with_transform(mut self, transform: Mat3<f32>) -> Self {
self.transform = transform;
self
}
pub fn with_layer(mut self, layer: i32) -> Self {
self.layer = layer;
self
}
pub fn with_visible(mut self, visible: bool) -> Self {
self.visible = visible;
self
}
}