#[allow(dead_code)]
use ui::{self, Vertex};
const BRDR_Z_OFFSET: f32 = ui::SUBSUBDEPTH;
#[derive(Clone, Copy)]
struct Line {
pub x: f32,
pub y: f32,
pub m: f32,
}
#[derive(Clone, Debug)]
pub struct Shape2d {
pub vertices: Vec<Vertex>,
pub indices: Vec<u16>,
pub perim: Vec<u16>,
pub radii: (f32, f32),
pub color: [f32; 4],
}
impl Shape2d {
pub fn rectangle(height: f32, width: f32, depth: f32, color: [f32; 4],
) -> Shape2d
{
let top = height / 2.0;
let bot = -height / 2.0;
let left = -width / 2.0;
let right = width / 2.0;
let xy_normal = [0.0, 0.0];
let vertices = vec![
Vertex::new([ 0.0, 0.0, depth], color, xy_normal, false),
Vertex::new([ left, top, depth], color, xy_normal, true),
Vertex::new([ right, top, depth], color, xy_normal, true),
Vertex::new([ right, bot, depth], color, xy_normal, true),
Vertex::new([ left, bot, depth], color, xy_normal, true),
];
let indices = vec![
0, 1, 2,
2, 3, 0,
0, 3, 4,
4, 1, 0,
];
let perim = vec![
1, 2, 3, 4,
];
let radii = (right, top);
Shape2d { vertices: vertices, indices: indices, perim: perim, radii: radii,
color: color }
}
pub fn hexagon_panel(height: f32, ew: f32, depth: f32, color: [f32; 4],
) -> Shape2d
{
let sqrt_3_inv = 1.732050808;
let a = height / 2.0;
let s = 1.0 / sqrt_3_inv; let hs = s * 0.5;
let vertices = vec![
Vertex::new([ 0.0, 0.0, depth], color, [0.0, 0.0], false),
Vertex::new([-(hs + ew), a, depth], color, [0.0, 0.0], true),
Vertex::new([ hs + ew, a, depth], color, [0.0, 0.0], true),
Vertex::new([ s + ew, 0.0, depth], color, [0.0, 0.0], true),
Vertex::new([ hs + ew, -a, depth], color, [0.0, 0.0], true),
Vertex::new([-(hs + ew), -a, depth], color, [0.0, 0.0], true),
Vertex::new([-(s + ew), 0.0, depth], color, [0.0, 0.0], true),
];
let indices = vec![
0, 1, 2,
2, 3, 0,
0, 3, 4,
4, 5, 0,
0, 5, 6,
6, 1, 0u16,
];
let perim = vec![
1, 2, 3, 4, 5, 6,
];
let radii = (ew + (s * 0.75), a);
Shape2d { vertices: vertices, indices: indices, perim: perim, radii: radii,
color: color }
}
pub fn perim_edges(&self) -> Vec<(usize, (u16, u16))> {
(0..self.perim.len()).into_iter()
.map(|edge_idx| {
let v_1 = if edge_idx == 0 {
self.perim[self.perim.len() - 1]
} else {
self.perim[edge_idx - 1]
};
let v_2 = self.perim[edge_idx];
(self.perim[edge_idx] as usize, (v_1, v_2))
})
.collect()
}
pub fn as_border(&self, t: f32, color: [f32; 4]) -> Shape2d {
let perim_edges = self.perim_edges();
let mut border_lines = Vec::<Line>::with_capacity(perim_edges.len());
for edge in perim_edges.iter() {
let pos1_3d = self.vertices[(edge.1).0 as usize].position();
let pos2_3d = self.vertices[(edge.1).1 as usize].position();
let p1 = (pos1_3d[0], pos1_3d[1]);
let p2 = (pos2_3d[0], pos2_3d[1]);
let m = (p2.1 - p1.1) / (p2.0 - p1.0);
let m_inv = 1.0 / m;
let p = ((p1.0 + p2.0) / 2.0, (p1.1 + p2.1) / 2.0);
let x_ofs = m_inv.atan().cos().abs() * t;
let y_ofs = m_inv.atan().sin().abs() * t;
let q = ((p.0 + (x_ofs * p.0.signum())),
(p.1 + (y_ofs * p.1.signum())));
border_lines.push(Line { x: q.0, y: q.1, m: m });
}
let mut border_vertices: Vec<(f32, f32)> = Vec::with_capacity(perim_edges.len());
for l_idx in 0..border_lines.len() {
let l1 = if l_idx == 0 {
border_lines[border_lines.len() - 1]
} else {
border_lines[l_idx - 1]
};
let l2 = border_lines[l_idx];
let (x, y) = if l1.m.is_infinite() {
(l1.x, l2.y)
} else if l2.m.is_infinite() {
(l2.x, l1.y)
} else {
let x = ((l1.m * l1.x) - (l2.m * l2.x) - l1.y + l2.y) / (l1.m - l2.m);
let y = (l1.m * (x - l1.x)) + l1.y;
debug_assert!(((l2.m * (x - l2.x)) + l2.y) - y < 0.0001);
(x, y)
};
border_vertices.push((x, y));
}
let mut vertices = self.vertices.clone();
vertices[0] = self.vertices[0].color(color);
for l_idx in 0..border_lines.len() {
let vert_idx = perim_edges[l_idx].0;
let (v_x, v_y) = border_vertices[l_idx];
vertices[vert_idx] =
Vertex::new([v_x, v_y, self.vertices[vert_idx].position()[2] + BRDR_Z_OFFSET],
color, [0.0, 0.0], self.vertices[vert_idx].is_perimeter());
}
let new_shape = Shape2d {
vertices: vertices,
indices: self.indices.clone(),
perim: self.perim.clone(),
color: color,
radii: (self.radii.0 + t, self.radii.1 + t),
};
new_shape
}
}