use glam::{vec2, vec3, Vec3, Vec4};
use crate::graphics::{Mesh, Vertex};
pub struct Quad{
pub size: Vec3,
pub color: Vec4,
}
impl Quad{
pub fn new(size: Vec3, color: Vec4) -> Self{
Self{
size,
color,
}
}
pub fn mesh(&self) -> Mesh {
let vertices = vec![
Vertex::new(vec3(0.0, 0.0, 0.0), self.color, vec2(0.0, 0.0), vec3(0., 0., 1.)), Vertex::new(vec3(0.0, self.size.y, 0.0), self.color, vec2(0.0, 1.0), vec3(0., 0., 1.)), Vertex::new(vec3(self.size.x, 0.0, 0.0), self.color, vec2(1.0, 0.0), vec3(0., 0., 1.)), Vertex::new(vec3(self.size.x, self.size.y, 0.0), self.color, vec2(1.0, 1.0), vec3(0., 0., 1.)), ];
let indices = vec![0, 2, 1, 2, 3, 1];
Mesh::new(&vertices, &indices)
}
}
pub struct Circle{
pub iterations: i32,
pub radius: f32,
pub color: Vec4,
}
impl Circle {
pub fn new(iterations: i32, radius: f32, color: Vec4) -> Self{
let mut fixed_iterations = iterations;
if iterations <= 3{
fixed_iterations = 4;
}
Self {
iterations: fixed_iterations,
radius,
color,
}
}
pub fn mesh(&self) -> Mesh {
let mut vertices = vec![];
for i in 0..self.iterations {
let angle = 2.0 * std::f32::consts::PI * (i as f32 / self.iterations as f32);
let tex_coord = vec2(f32::cos(angle) * 0.5 + 0.5, f32::sin(angle) * 0.5 + 0.5);
vertices.push(Vertex::new(
vec3(f32::sin(angle), f32::cos(angle), 0.0) * self.radius,
self.color,
tex_coord,
vec3(0., 0., 1.),
));
}
let mut indices = vec![];
for i in 1..=self.iterations-2 {
indices.push(0);
indices.push(i as u32);
indices.push((i % self.iterations + 1) as u32);
}
Mesh::new(&vertices, &indices)
}
}
pub struct Triangle{
pub size: f32,
pub color: Vec4,
}
impl Triangle{
pub fn new(size: f32, color: Vec4) -> Self{
Self {
size,
color,
}
}
pub fn mesh(&self) -> Mesh {
let mut vertices = vec![];
for i in 0..3 {
let angle = 2.0 * std::f32::consts::PI * (i as f32 / 3.0);
let tex_coord = match i {
0 => vec2(0.5, 1.0), 1 => vec2(0.0, 0.0), 2 => vec2(1.0, 0.0), _ => panic!("Unexpected index"),
};
vertices.push(Vertex::new(
vec3(f32::sin(angle), f32::cos(angle), 0.0) * self.size,
self.color,
tex_coord,
vec3(0., 0., 1.),
));
}
let mut indices = vec![];
indices.push(0);
indices.push(1 as u32);
indices.push(2 as u32);
Mesh::new(&vertices, &indices)
}
}
pub struct Cuboid{
pub size: Vec3,
pub color: Vec4,
}
impl Cuboid{
pub fn new(size: Vec3, color: Vec4) -> Self{
Self{
size,
color,
}
}
pub fn mesh(&self) -> Mesh {
let half_size = self.size/2.;
let x = half_size.x;
let y = half_size.y;
let z = half_size.z;
let vertices = vec![
Vertex::new(vec3(-x, -y, z), self.color, vec2(0.0, 0.0), vec3(0.0, 0.0, 1.0)), Vertex::new(vec3(x, -y, z), self.color, vec2(1.0, 0.0), vec3(0.0, 0.0, 1.0)), Vertex::new(vec3(x, y, z), self.color, vec2(1.0, 1.0), vec3(0.0, 0.0, 1.0)), Vertex::new(vec3(-x, y, z), self.color, vec2(0.0, 1.0), vec3(0.0, 0.0, 1.0)),
Vertex::new(vec3(-x, -y, -z), self.color, vec2(0.0, 0.0), vec3(0.0, 0.0, -1.0)), Vertex::new(vec3(x, -y, -z), self.color, vec2(1.0, 0.0), vec3(0.0, 0.0, -1.0)), Vertex::new(vec3(x, y, -z), self.color, vec2(1.0, 1.0), vec3(0.0, 0.0, -1.0)), Vertex::new(vec3(-x, y, -z), self.color, vec2(0.0, 1.0), vec3(0.0, 0.0, -1.0)),
Vertex::new(vec3(-x, -y, -z), self.color, vec2(0.0, 0.0), vec3(-1.0, 0.0, 0.0)), Vertex::new(vec3(-x, -y, z), self.color, vec2(1.0, 0.0), vec3(-1.0, 0.0, 0.0)), Vertex::new(vec3(-x, y, z), self.color, vec2(1.0, 1.0), vec3(-1.0, 0.0, 0.0)), Vertex::new(vec3(-x, y, -z), self.color, vec2(0.0, 1.0), vec3(-1.0, 0.0, 0.0)),
Vertex::new(vec3(x, -y, -z), self.color, vec2(0.0, 0.0), vec3(1.0, 0.0, 0.0)), Vertex::new(vec3(x, -y, z), self.color, vec2(1.0, 0.0), vec3(1.0, 0.0, 0.0)), Vertex::new(vec3(x, y, z), self.color, vec2(1.0, 1.0), vec3(1.0, 0.0, 0.0)), Vertex::new(vec3(x, y, -z), self.color, vec2(0.0, 1.0), vec3(1.0, 0.0, 0.0)),
Vertex::new(vec3(-x, y, -z), self.color, vec2(0.0, 0.0), vec3(0.0, 1.0, 0.0)), Vertex::new(vec3(x, y, -z), self.color, vec2(1.0, 0.0), vec3(0.0, 1.0, 0.0)), Vertex::new(vec3(x, y, z), self.color, vec2(1.0, 1.0), vec3(0.0, 1.0, 0.0)), Vertex::new(vec3(-x, y, z), self.color, vec2(0.0, 1.0), vec3(0.0, 1.0, 0.0)),
Vertex::new(vec3(-x, -y, -z), self.color, vec2(0.0, 0.0), vec3(0.0, -1.0, 0.0)), Vertex::new(vec3(x, -y, -z), self.color, vec2(1.0, 0.0), vec3(0.0, -1.0, 0.0)), Vertex::new(vec3(x, -y, z), self.color, vec2(1.0, 1.0), vec3(0.0, -1.0, 0.0)), Vertex::new(vec3(-x, -y, z), self.color, vec2(0.0, 1.0), vec3(0.0, -1.0, 0.0)), ];
let indices = vec![
0, 3, 2, 2, 1, 0,
4, 5, 6, 6, 7, 4,
8, 11, 10, 10, 9, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 23, 22, 22, 21, 20
];
Mesh::new(&vertices, &indices)
}
}
pub struct Sphere{
pub iterations: i32,
pub radius: f32,
pub color: Vec4,
}
impl Sphere {
pub fn new(iterations: i32, radius: f32, color: Vec4) -> Self{
let mut fixed_iterations = iterations;
if iterations <= 3{
fixed_iterations = 4;
}
Self {
iterations: fixed_iterations,
radius,
color,
}
}
pub fn mesh(&self) -> Mesh {
let mut vertices = vec![];
let pi = std::f32::consts::PI;
for lat in 0..=self.iterations {
let theta = pi * lat as f32 / self.iterations as f32;
let sin_theta = theta.sin();
let cos_theta = theta.cos();
for lon in 0..=self.iterations {
let phi = 2.0 * pi * lon as f32 / self.iterations as f32;
let sin_phi = phi.sin();
let cos_phi = phi.cos();
let x = cos_phi * sin_theta * self.radius;
let y = cos_theta * self.radius;
let z = sin_phi * sin_theta * self.radius;
let s = lon as f32 / self.iterations as f32;
let t = 1.0 - (lat as f32 / self.iterations as f32);
let normal = vec3(x, y, z).normalize();
vertices.push(Vertex::new(vec3(x, y, z), self.color, vec2(s, t), normal));
}
}
let mut indices = vec![];
for lat in 0..self.iterations {
for lon in 0..self.iterations {
let first = lat * (self.iterations + 1) + lon;
let second = first + self.iterations + 1;
indices.push(first as u32);
indices.push(second as u32);
indices.push((first + 1) as u32);
indices.push(second as u32);
indices.push((second + 1) as u32);
indices.push((first + 1) as u32);
}
}
Mesh::new(&vertices, &indices)
}
}