229 lines
No EOL
6.1 KiB
Text
229 lines
No EOL
6.1 KiB
Text
use bytemuck::{Pod, Zeroable};
|
|
use rand::Rng;
|
|
use wgpu::{VertexAttribute, VertexBufferLayout};
|
|
use std::{default, vec::Vec};
|
|
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Pos([f32; 3]);
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Col([f32; 3]);
|
|
|
|
impl Pos {
|
|
pub fn new(x: f32, y: f32, z: f32) -> Self {
|
|
Self([x, y, z])
|
|
}
|
|
}
|
|
|
|
unsafe impl Zeroable for Pos {}
|
|
unsafe impl Pod for Pos {}
|
|
|
|
impl Col {
|
|
pub fn new(r: f32, g: f32, b: f32) -> Self {
|
|
Self([r, g, b])
|
|
}
|
|
pub fn random() -> Self {
|
|
Self::new(rand::thread_rng().gen_range(0.0..=1.0), rand::thread_rng().gen_range(0.0..=1.0), rand::thread_rng().gen_range(0.0..=1.0))
|
|
}
|
|
}
|
|
|
|
unsafe impl Zeroable for Col {}
|
|
unsafe impl Pod for Col {}
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Vertex {
|
|
position: Pos,
|
|
color: Col,
|
|
}
|
|
|
|
impl Vertex {
|
|
pub fn new(position: Pos, color: Col) -> Self {
|
|
Vertex { position: position, color: color }
|
|
}
|
|
|
|
pub fn desc() -> wgpu::VertexBufferLayout<'static> {
|
|
wgpu::VertexBufferLayout {
|
|
array_stride: std::mem::size_of::<Self>() as wgpu::BufferAddress,
|
|
step_mode: wgpu::VertexStepMode::Vertex,
|
|
attributes: &[VertexAttribute {
|
|
format: wgpu::VertexFormat::Float32x3,
|
|
offset: 0,
|
|
shader_location: 0,
|
|
},
|
|
VertexAttribute {
|
|
format: wgpu::VertexFormat::Float32x3,
|
|
offset: std::mem::size_of::<[f32; 3]>() as u64,
|
|
shader_location: 1,
|
|
}],
|
|
}
|
|
}
|
|
}
|
|
|
|
unsafe impl Zeroable for Vertex {}
|
|
unsafe impl Pod for Vertex {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
pub enum PolyError {
|
|
NotEnoughSides,
|
|
SidesAndTriangeNumberArentConsistant
|
|
}
|
|
|
|
|
|
#[repr(C)]
|
|
pub struct Polygon{
|
|
triangles: Vec<Triangle>,
|
|
n_sides: usize,
|
|
}
|
|
|
|
impl Polygon {
|
|
pub fn new_from_center(center: Vertex, radius: f32, n_sides: usize) -> Self {
|
|
//let theta = (360.0 / n_sides as f32).to_radians();
|
|
let mut vec_tris: Vec<Triangle> = Vec::with_capacity(n_sides);
|
|
|
|
let center_x = center.position.0[0];
|
|
let center_y = center.position.0[1];
|
|
|
|
for v in 0..n_sides {
|
|
let theta_current = (v as f32 / n_sides as f32) * 2.0 * std::f32::consts::PI;
|
|
let theta_next = ((v+1) as f32 / n_sides as f32) * 2.0 * std::f32::consts::PI;
|
|
let triangle = Triangle::new(Vertex::new(Pos::new((theta_current.cos() * radius) + center_x, (theta_current.sin() * radius) + center_y, 0.0), Col::random()), Vertex::new(Pos::new((theta_next.cos() * radius) + center_x, (theta_next.sin() * radius) + center_y, 0.0), Col::random()), center);
|
|
vec_tris.push(triangle);
|
|
};
|
|
Self::new_from_tris(vec_tris, n_sides).unwrap()
|
|
}
|
|
|
|
|
|
pub fn new_from_side(len_side: f32, n_sides: usize, color: Option<Col>) -> Self {
|
|
todo!();
|
|
// let color = color.unwrap_or(Col::random());
|
|
// let theta = 360.0 / n_sides as f32;
|
|
|
|
// let center = Pos::new(
|
|
// // ((180.0 - theta) / 2.0).to_radians().cos() * radius,
|
|
// // ((180.0 - theta) / 2.0).to_radians().sin() * radius,
|
|
// (theta / 2.0).to_radians().cos() * radius,
|
|
// (theta / 2.0).to_radians().sin() * radius,
|
|
// 0.0
|
|
// );
|
|
|
|
// let nsides_poly = NSides::new(center, radius, n_sides, color).unwrap();
|
|
// nsides_poly.verts.polish_tris(nsides_poly.center, color)
|
|
}
|
|
|
|
fn new_from_tris(triangles: Vec<Triangle>, n_sides: usize) -> Result<Self, PolyError> {
|
|
if triangles.len() != n_sides {
|
|
return Err(PolyError::SidesAndTriangeNumberArentConsistant)
|
|
}
|
|
|
|
Ok(Self {
|
|
triangles,
|
|
n_sides
|
|
})
|
|
}
|
|
|
|
pub fn get_tris(&self) -> Vec<Triangle> {
|
|
self.triangles.clone()
|
|
}
|
|
|
|
pub fn uniform(&self) -> &[u8] {
|
|
self.get_tris();
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Clone)]
|
|
pub struct Triangle([Vertex; 3]);
|
|
|
|
impl Triangle {
|
|
pub fn new(vertex1: Vertex, vertex2: Vertex, vertex3: Vertex) -> Self {
|
|
Self([vertex1, vertex2, vertex3])
|
|
}
|
|
|
|
pub fn verts(&self) -> [Vertex; 3] {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
|
|
pub type VertexVector = Vec<Vertex>;
|
|
|
|
trait VertexVectorMethods {
|
|
fn polish_tris(&self, center_position: Pos, center_color: Col) -> Polygon;
|
|
fn get_next(&self, index: usize) -> Vertex;
|
|
}
|
|
|
|
impl VertexVectorMethods for VertexVector {
|
|
fn polish_tris(&self, center_position: Pos, center_color: Col) -> Polygon {
|
|
let start_verts = self;
|
|
let mut vec_tris = Vec::with_capacity(self.len());
|
|
for (vx, indx) in self.iter().zip(0..self.len()) {
|
|
vec_tris.push(Triangle::new(vx.to_owned(), self.get_next(indx), Vertex { position: center_position, color: Col::random() }));
|
|
};
|
|
Polygon::new_from_tris(vec_tris, self.len()).unwrap()
|
|
}
|
|
|
|
fn get_next(&self, index: usize) -> Vertex {
|
|
if index != self.len()-1 {
|
|
return self[index+1];
|
|
} else {
|
|
return self[0];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#[repr(C)]
|
|
pub struct NSides {
|
|
center: Pos,
|
|
radius: f32,
|
|
n_sides: usize,
|
|
color: Col,
|
|
verts: VertexVector
|
|
}
|
|
|
|
impl NSides {
|
|
#[allow(private_interfaces)]
|
|
pub fn new(center: Pos, radius: f32, n_sides: usize, color: Col) -> Result<Self, PolyError> {
|
|
if n_sides < 3 {
|
|
return Err(PolyError::NotEnoughSides)
|
|
}
|
|
|
|
let verts = Self::calc_vertecies(n_sides, radius, color);
|
|
|
|
return Ok(Self {
|
|
center,
|
|
radius,
|
|
n_sides,
|
|
color,
|
|
verts,
|
|
})
|
|
}
|
|
|
|
pub fn get_verts(&self) -> VertexVector {
|
|
self.verts.clone()
|
|
}
|
|
|
|
#[allow(private_interfaces)]
|
|
fn calc_vertecies(n_sides: usize, radius: f32, color: Col) -> VertexVector{
|
|
let mut verts: Vec<Vertex> = Vec::with_capacity(n_sides);
|
|
let float_sides = n_sides as f32;
|
|
for x in 0..n_sides {
|
|
let x = x as f32;
|
|
let theta = (x / float_sides) * 2.0 * 3.14159265359;
|
|
verts.push(Vertex::new(Pos::new(theta.cos() * radius, theta.sin() * radius, 0.0), color));
|
|
}
|
|
|
|
verts
|
|
}
|
|
} |