use super::{IndexBuffer, RenderMesh};
use glamx::{Vec2, Vec3};
pub fn quad(width: f32, height: f32, usubdivs: usize, vsubdivs: usize) -> RenderMesh {
let mut quad = unit_quad(usubdivs, vsubdivs);
let s = Vec3::new(width, height, 1.0);
quad.scale_by(s);
quad
}
pub fn quad_with_vertices(vertices: &[Vec3], nhpoints: usize, nvpoints: usize) -> RenderMesh {
assert!(
nhpoints > 1 && nvpoints > 1,
"The number of points must be at least 2 in each dimension."
);
let mut res = unit_quad(nhpoints - 1, nvpoints - 1);
for (dest, src) in res.coords.iter_mut().zip(vertices.iter()) {
*dest = *src;
}
res
}
pub fn unit_quad(usubdivs: usize, vsubdivs: usize) -> RenderMesh {
assert!(
usubdivs > 0 && vsubdivs > 0,
"The number of subdivisions cannot be zero"
);
let wstep = 1.0 / (usubdivs as f32);
let hstep = 1.0 / (vsubdivs as f32);
let cw = 0.5;
let ch = 0.5;
let mut vertices = Vec::new();
let mut normals = Vec::new();
let mut triangles = Vec::new();
let mut tex_coords = Vec::new();
for i in 0usize..vsubdivs + 1 {
for j in 0usize..usubdivs + 1 {
let ni: f32 = i as f32;
let nj: f32 = j as f32;
let v = Vec3::new(nj * wstep - cw, ni * hstep - ch, 0.0);
vertices.push(v);
tex_coords.push(Vec2::new(1.0 - nj * wstep, 1.0 - ni * hstep))
}
}
for _ in 0..(vsubdivs + 1) * (usubdivs + 1) {
normals.push(Vec3::new(1.0, 0.0, 0.0))
}
fn dl_triangle(i: u32, j: u32, ws: u32) -> [u32; 3] {
[(i + 1) * ws + j, i * ws + j, (i + 1) * ws + j + 1]
}
fn ur_triangle(i: u32, j: u32, ws: u32) -> [u32; 3] {
[i * ws + j, i * ws + (j + 1), (i + 1) * ws + j + 1]
}
for i in 0usize..vsubdivs {
for j in 0usize..usubdivs {
triangles.push(dl_triangle(i as u32, j as u32, (usubdivs + 1) as u32));
triangles.push(ur_triangle(i as u32, j as u32, (usubdivs + 1) as u32));
}
}
RenderMesh::new(
vertices,
Some(normals),
Some(tex_coords),
Some(IndexBuffer::Unified(triangles)),
)
}