use super::utils;
use super::{IndexBuffer, RenderMesh};
use glamx::Vec3;
pub fn cone(diameter: f32, height: f32, nsubdiv: u32) -> RenderMesh {
let mut cone = unit_cone(nsubdiv);
cone.scale_by(Vec3::new(diameter, height, diameter));
cone
}
pub fn unit_cone(nsubdiv: u32) -> RenderMesh {
let two_pi = std::f32::consts::TAU;
let dtheta = two_pi / (nsubdiv as f32);
let mut coords = Vec::new();
let mut indices = Vec::new();
let mut normals: Vec<Vec3>;
utils::push_circle(0.5, nsubdiv, dtheta, -0.5, &mut coords);
normals = coords.clone();
coords.push(Vec3::new(0.0, 0.5, 0.0));
utils::push_degenerate_top_ring_indices(0, coords.len() as u32 - 1, nsubdiv, &mut indices);
utils::push_filled_circle_indices(0, nsubdiv, &mut indices);
let mut indices = utils::split_index_buffer(&indices[..]);
let shift = 0.05f32 / 0.475;
for n in normals.iter_mut() {
n.y += shift;
*n = n.normalize();
}
normals.push(Vec3::new(0.0, -1.0, 0.0));
let ilen = indices.len();
let nlen = normals.len() as u32;
for (id, i) in indices[..ilen - (nsubdiv as usize - 2)]
.iter_mut()
.enumerate()
{
i[1][1] = id as u32;
}
for i in indices[ilen - (nsubdiv as usize - 2)..].iter_mut() {
i[0][1] = nlen - 1;
i[1][1] = nlen - 1;
i[2][1] = nlen - 1;
}
RenderMesh::new(
coords,
Some(normals),
None,
Some(IndexBuffer::Split(indices)),
)
}