use lotus_proc_macros::Component;
use super::{color::Color, managers::rendering::manager::Vertex};
#[derive(Clone, Debug, Component)]
pub struct Shape {
pub orientation: Orientation,
pub geometry_type: GeometryType,
pub color: Color
}
impl Shape {
pub fn new(orientation: Orientation, geometry_type: GeometryType, color: Color) -> Self {
return Self {
orientation,
geometry_type,
color
};
}
pub fn orientation(&mut self, orientation: Orientation) {
self.orientation = orientation;
}
pub fn geometry_type(&mut self, geometry_type: GeometryType) {
self.geometry_type = geometry_type;
}
pub fn color(&mut self, color: Color) {
self.color = color;
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Circle {
pub number_of_segments: u16,
pub radius: f32
}
impl Circle {
pub fn new(number_of_segments: u16, radius: f32) -> Self {
return Self {
number_of_segments,
radius
};
}
}
impl Default for Circle {
fn default() -> Self {
return Self {
number_of_segments: 64,
radius: 0.5
};
}
}
#[derive(Clone, Debug)]
pub enum Orientation {
Horizontal,
Vertical
}
#[derive(Clone, Debug, PartialEq)]
pub enum GeometryType {
Triangle,
Square,
Rectangle,
Circle(Circle)
}
impl GeometryType {
pub fn to_vertex_array(&self, orientation: Orientation, color: [f32; 4]) -> Vec<Vertex> {
match self {
GeometryType::Triangle => {
vec![
Vertex { position: [0.0, 0.5, 0.0], texture_coordinates: [0.0, 0.0], color }, Vertex { position: [-0.5, -0.5, 0.0], texture_coordinates: [0.0, 0.0], color }, Vertex { position: [0.5, -0.5, 0.0], texture_coordinates: [0.0, 0.0], color } ]
},
GeometryType::Square => {
vec![
Vertex { position: [-1.0, -1.0, 0.0], texture_coordinates: [0.0, 1.0], color }, Vertex { position: [1.0, -1.0, 0.0], texture_coordinates: [1.0, 1.0], color }, Vertex { position: [1.0, 1.0, 0.0], texture_coordinates: [1.0, 0.0], color }, Vertex { position: [-1.0, 1.0, 0.0], texture_coordinates: [0.0, 0.0], color } ]
},
GeometryType::Rectangle => {
match orientation {
Orientation::Horizontal => {
vec![
Vertex { position: [-0.75, -0.25, 0.0], texture_coordinates: [0.0, 1.0], color }, Vertex { position: [0.75, -0.25, 0.0], texture_coordinates: [1.0, 1.0], color }, Vertex { position: [0.75, 0.25, 0.0], texture_coordinates: [1.0, 0.0], color }, Vertex { position: [-0.75, 0.25, 0.0], texture_coordinates: [0.0, 0.0], color } ]
},
Orientation::Vertical => {
vec![
Vertex { position: [-0.25, -0.75, 0.0], texture_coordinates: [0.0, 1.0], color }, Vertex { position: [0.25, -0.75, 0.0], texture_coordinates: [1.0, 1.0], color }, Vertex { position: [0.25, 0.75, 0.0], texture_coordinates: [1.0, 0.0], color }, Vertex { position: [-0.25, 0.75, 0.0], texture_coordinates: [0.0, 0.0], color } ]
}
}
},
GeometryType::Circle(circle) => {
let mut vertices: Vec<Vertex> = Vec::new();
vertices.push(Vertex { position: [0.0, 0.0, 0.0], texture_coordinates: [0.5, 0.5], color });
for i in 0..circle.number_of_segments {
let theta: f32 = 2.0 * std::f32::consts::PI * (i as f32) / (circle.number_of_segments as f32);
let x: f32 = circle.radius * theta.cos();
let y: f32 = circle.radius * theta.sin();
vertices.push(Vertex { position: [x, y, 0.0], texture_coordinates: [0.5 + x, 0.5 + y], color });
}
vertices
}
}
}
pub fn to_index_array(&self) -> Vec<u16> {
match self {
GeometryType::Triangle => vec![0, 1, 2],
GeometryType::Square => {
vec![
0, 1, 2, 2, 3, 0 ]
},
GeometryType::Rectangle => {
vec![
0, 1, 2, 2, 3, 0 ]
},
GeometryType::Circle(circle) => {
let mut indices: Vec<u16> = Vec::new();
for i in 0..circle.number_of_segments {
indices.push(0);
indices.push((i + 1) as u16);
indices.push(((i + 1) % circle.number_of_segments + 1) as u16);
}
indices
}
}
}
}