Compare commits
1 commit
master
...
headless-d
Author | SHA1 | Date | |
---|---|---|---|
|
2b647c3abc |
19 changed files with 2945 additions and 578 deletions
2275
Cargo.lock
generated
Normal file
2275
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "library-maths"
|
name = "testing"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
@ -16,4 +16,4 @@ rand = "*"
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 2
|
opt-level = 2
|
||||||
|
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
A functional-enough regular polygon generator. Not really useful for anything currently, but it can make data.
|
||||||
|
|
||||||
|
This is deterministic, hence its used in [`askiiart/disk-read-benchmark`](https://git.askiiart.net/askiiart/disk-read-benchmark)
|
|
@ -1,95 +0,0 @@
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
use winit::{event::{self, ElementState, Event, KeyEvent, WindowEvent}, event_loop::{EventLoop, EventLoopWindowTarget}, keyboard::{KeyCode, PhysicalKey}, window::{self, WindowBuilder}};
|
|
||||||
|
|
||||||
use crate::{state::state::State, structure::{enums::{micellaneous::Shape, Resolution}, structs::Vertex, traits::Drawable}};
|
|
||||||
|
|
||||||
pub struct Canvas {
|
|
||||||
pub(crate) added: Vec<Box<dyn Drawable>>,
|
|
||||||
pub(crate) resolution: Resolution
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Canvas {
|
|
||||||
pub fn new(resolution: Resolution) -> Self {
|
|
||||||
Canvas {
|
|
||||||
added: vec![],
|
|
||||||
resolution
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add(&mut self, added: Shape) {
|
|
||||||
match added {
|
|
||||||
Shape::Regular(polygon) => self.added.push(Box::new(polygon)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run(&self) {
|
|
||||||
let event_loop = EventLoop::new().unwrap();
|
|
||||||
let window = WindowBuilder::new().with_title("ciao").build(&event_loop).unwrap();
|
|
||||||
|
|
||||||
let mut verts = vec![];
|
|
||||||
self.uniform(&mut verts);
|
|
||||||
|
|
||||||
let mut state = State::new(&window, Some(bytemuck::cast_slice(&verts)), self.resolution).await;
|
|
||||||
|
|
||||||
event_loop
|
|
||||||
.run(move |event, control_flow| match event {
|
|
||||||
Event::WindowEvent {
|
|
||||||
ref event,
|
|
||||||
window_id,
|
|
||||||
} if window_id == state.window().id() => {
|
|
||||||
if !state.input(event) {
|
|
||||||
match event {
|
|
||||||
WindowEvent::CloseRequested
|
|
||||||
| WindowEvent::KeyboardInput {
|
|
||||||
event:
|
|
||||||
KeyEvent {
|
|
||||||
state: ElementState::Pressed,
|
|
||||||
physical_key: PhysicalKey::Code(KeyCode::Escape),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} => control_flow.exit(),
|
|
||||||
|
|
||||||
WindowEvent::Resized(size) => {
|
|
||||||
state.resize(*size);
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowEvent::RedrawRequested => {
|
|
||||||
state.window().request_redraw();
|
|
||||||
/*
|
|
||||||
if !surface_configured {
|
|
||||||
return;
|
|
||||||
} ??????
|
|
||||||
*/
|
|
||||||
|
|
||||||
state.update();
|
|
||||||
|
|
||||||
match state.render() {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
|
|
||||||
state.resize(state.size);
|
|
||||||
}
|
|
||||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
|
||||||
log::error!("OutOfMemory");
|
|
||||||
control_flow.exit();
|
|
||||||
}
|
|
||||||
Err(wgpu::SurfaceError::Timeout) => {
|
|
||||||
log::warn!("Surface Timeout")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn uniform(&self, vector: &mut Vec<Vertex>) {
|
|
||||||
vector.extend(self.added.iter().flat_map(|d| d.uniform()));
|
|
||||||
}
|
|
||||||
}
|
|
5
src/front/enums.rs
Normal file
5
src/front/enums.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pub enum Rotation{
|
||||||
|
HorizontalAlign,
|
||||||
|
VerticalAlign,
|
||||||
|
Custom(f32)
|
||||||
|
}
|
6
src/front/front_errors.rs
Normal file
6
src/front/front_errors.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum PolyError {
|
||||||
|
NotEnoughSides,
|
||||||
|
SidesAndTriangleNumberArentConsistant,
|
||||||
|
}
|
3
src/front/mod.rs
Normal file
3
src/front/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod structs;
|
||||||
|
pub mod front_errors;
|
||||||
|
pub mod enums;
|
229
src/front/old
Normal file
229
src/front/old
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
233
src/front/structs.rs
Normal file
233
src/front/structs.rs
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
use core::f32;
|
||||||
|
use rand::Rng;
|
||||||
|
use std::vec::Vec;
|
||||||
|
use wgpu::VertexAttribute;
|
||||||
|
|
||||||
|
use super::{enums::Rotation, front_errors::PolyError};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Pos([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 {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Col([f32; 3]);
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Zeroable for Vertex {}
|
||||||
|
unsafe impl Pod for Vertex {}
|
||||||
|
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Triangle([Vertex; 3]);
|
||||||
|
|
||||||
|
impl Triangle {
|
||||||
|
pub fn new(vertices: [Vertex; 3]) -> Self {
|
||||||
|
Triangle(vertices)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verts(&self) -> [Vertex; 3] {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Polygon {
|
||||||
|
triangles: Vec<Triangle>,
|
||||||
|
center: Vertex,
|
||||||
|
radius: f32,
|
||||||
|
n_sides: usize,
|
||||||
|
rotation: Rotation,
|
||||||
|
}
|
||||||
|
impl Polygon {
|
||||||
|
/// # USAGE
|
||||||
|
/// quality of life method, alias [Polygon::new_from_radius_with_rotation()] with `rotation == 0.0`
|
||||||
|
pub fn new_from_radius(center: Vertex, radius: f32, n_sides: usize) -> Result<Self, PolyError> {
|
||||||
|
Self::new_from_radius_with_rotation(center, radius, n_sides, Rotation::HorizontalAlign)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # USAGE
|
||||||
|
/// creates a [Polygon] from a center and radius with a rotation.
|
||||||
|
///
|
||||||
|
/// # WARNING
|
||||||
|
/// - the rotation must be given in radiants.
|
||||||
|
pub fn new_from_radius_with_rotation(
|
||||||
|
center: Vertex,
|
||||||
|
radius: f32,
|
||||||
|
n_sides: usize,
|
||||||
|
rotation: Rotation,
|
||||||
|
) -> Result<Self, PolyError> {
|
||||||
|
if n_sides < 3 {
|
||||||
|
return Err(PolyError::NotEnoughSides);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rotation_rad = match rotation {
|
||||||
|
Rotation::HorizontalAlign => {
|
||||||
|
if n_sides % 6 == 0 {
|
||||||
|
0.0
|
||||||
|
} else if n_sides % 4 == 0 {
|
||||||
|
(f32::consts::PI * 2.0 / n_sides as f32) / 2.0
|
||||||
|
} else if n_sides % 3 == 0 {
|
||||||
|
match ((n_sides-3)/6)%2 {
|
||||||
|
1 => (f32::consts::PI * 2.0 / n_sides as f32) / 4.0,
|
||||||
|
0 => (f32::consts::PI * 2.0)- ((f32::consts::PI * 2.0 / n_sides as f32) / 4.0),
|
||||||
|
_ => panic!(), // should never happen, it's a module. ( % 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
} //TODO: add other n_sides
|
||||||
|
},
|
||||||
|
Rotation::VerticalAlign => (f32::consts::PI * 2.0 / n_sides as f32) / 2.0, // TODO
|
||||||
|
Rotation::Custom(rad) => rad,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut vec_tris: Vec<Triangle> = Vec::with_capacity(n_sides); // TODO: add space 4 morph
|
||||||
|
|
||||||
|
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) + rotation_rad;
|
||||||
|
let theta_next =
|
||||||
|
(((v + 1) as f32 / n_sides as f32) * 2.0 * std::f32::consts::PI) + rotation_rad;
|
||||||
|
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_everything_with_rotation(vec_tris, center, radius, n_sides, rotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # USAGE
|
||||||
|
/// quality of life method, alias [Polygon::new_from_everything_with_rotation()] with `rotation == Rotation::HorizontalAlign`
|
||||||
|
fn new_from_everything(
|
||||||
|
triangles: Vec<Triangle>,
|
||||||
|
center: Vertex,
|
||||||
|
radius: f32,
|
||||||
|
n_sides: usize,
|
||||||
|
) -> Result<Self, PolyError> {
|
||||||
|
Self::new_from_everything_with_rotation(
|
||||||
|
triangles,
|
||||||
|
center,
|
||||||
|
radius,
|
||||||
|
n_sides,
|
||||||
|
Rotation::HorizontalAlign,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # USAGE
|
||||||
|
/// creates a [Polygon] from a center and radius with a rotation.
|
||||||
|
///
|
||||||
|
/// # WARNING
|
||||||
|
/// - the rotation must be given in radiants.
|
||||||
|
fn new_from_everything_with_rotation(
|
||||||
|
triangles: Vec<Triangle>,
|
||||||
|
center: Vertex,
|
||||||
|
radius: f32,
|
||||||
|
n_sides: usize,
|
||||||
|
rotation: Rotation,
|
||||||
|
) -> Result<Self, PolyError> {
|
||||||
|
if n_sides < 3 {
|
||||||
|
return Err(PolyError::NotEnoughSides);
|
||||||
|
}
|
||||||
|
|
||||||
|
if triangles.len() != n_sides {
|
||||||
|
return Err(PolyError::SidesAndTriangleNumberArentConsistant);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Polygon {
|
||||||
|
triangles,
|
||||||
|
center,
|
||||||
|
radius,
|
||||||
|
n_sides,
|
||||||
|
rotation,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_triangles(&self) -> Vec<Triangle> {
|
||||||
|
self.triangles.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uniform(&self) -> Vec<Vertex> {
|
||||||
|
self.get_triangles()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|t| t.verts().to_vec())
|
||||||
|
.collect::<Vec<Vertex>>()
|
||||||
|
}
|
||||||
|
}
|
36
src/learn_shading.wgsl
Normal file
36
src/learn_shading.wgsl
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Vertex shader
|
||||||
|
|
||||||
|
struct VertexOutput {
|
||||||
|
@builtin(position) clip_position: vec4<f32>,
|
||||||
|
};
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn vs_main(
|
||||||
|
@builtin(vertex_index) vertex_index: u32,
|
||||||
|
) -> VertexOutput {
|
||||||
|
var out: VertexOutput;
|
||||||
|
var x: f32;
|
||||||
|
var y: f32;
|
||||||
|
if vertex_index == 0 || vertex_index == 4 {
|
||||||
|
x = 0.5 * (10.0/16.0);
|
||||||
|
y = 0.5;
|
||||||
|
} else if vertex_index == 1 {
|
||||||
|
x = -0.5* (10.0/16.0);
|
||||||
|
y = 0.5;
|
||||||
|
} else if vertex_index == 2 {
|
||||||
|
x= -0.5* (10.0/16.0);
|
||||||
|
y= -0.5;
|
||||||
|
} else if vertex_index == 3 {
|
||||||
|
x= 0.5* (10.0/16.0);
|
||||||
|
y= -0.5;
|
||||||
|
}
|
||||||
|
out.clip_position = vec4<f32>(x, y, 0.0, 1.0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment shader
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
|
return vec4<f32>(0.67, 0.47, 0.72, 1.0);
|
||||||
|
}
|
150
src/lib.rs
150
src/lib.rs
|
@ -1,84 +1,94 @@
|
||||||
use state::state::State;
|
pub mod front;
|
||||||
use winit::{event::{ElementState, Event, KeyEvent, WindowEvent}, event_loop::EventLoop, keyboard::{KeyCode, PhysicalKey}, window::WindowBuilder};
|
pub mod state;
|
||||||
|
|
||||||
mod state;
|
use bytemuck::{Pod, Zeroable};
|
||||||
mod structure;
|
use state::State;
|
||||||
mod canvas;
|
use wgpu::VertexAttribute;
|
||||||
|
use winit::{
|
||||||
|
dpi::Size,
|
||||||
|
event::*,
|
||||||
|
event_loop::EventLoop,
|
||||||
|
keyboard::{KeyCode, PhysicalKey},
|
||||||
|
window::WindowBuilder,
|
||||||
|
};
|
||||||
|
|
||||||
// * re-exports
|
// const VERTS: &[Vertex] = &[
|
||||||
pub use canvas::Canvas;
|
// Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] }, // A
|
||||||
pub use structure::enums::Resolution;
|
// Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] }, // B
|
||||||
pub use structure::enums::micellaneous::Shape;
|
// Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] }, // C
|
||||||
pub use structure::structs::baseline::polygon::Polygon;
|
// Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] }, // D
|
||||||
pub use structure::structs::Vertex;
|
// Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] }, // E
|
||||||
pub use structure::structs::{Col, Pos};
|
// ];
|
||||||
// * re-exports
|
|
||||||
|
|
||||||
impl State<'_> {
|
// const INDICES: &[u16] = &[
|
||||||
pub fn run(&mut self) {
|
// 0, 1, 4,
|
||||||
env_logger::init();
|
// 1, 2, 4,
|
||||||
let event_loop = EventLoop::new().unwrap();
|
// 2, 3, 4,
|
||||||
let window = WindowBuilder::new()
|
// ];
|
||||||
.with_title("uhhhhh")
|
|
||||||
.build(&event_loop)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
event_loop
|
pub async fn run() {
|
||||||
.run(move |event, control_flow| match event {
|
env_logger::init();
|
||||||
Event::WindowEvent {
|
let event_loop = EventLoop::new().unwrap();
|
||||||
ref event,
|
let window = WindowBuilder::new()
|
||||||
window_id,
|
.with_title("uhhhhh")
|
||||||
} if window_id == self.window().id() => {
|
.build(&event_loop)
|
||||||
if !self.input(event) {
|
.unwrap();
|
||||||
match event {
|
|
||||||
WindowEvent::CloseRequested
|
|
||||||
| WindowEvent::KeyboardInput {
|
|
||||||
event:
|
|
||||||
KeyEvent {
|
|
||||||
state: ElementState::Pressed,
|
|
||||||
physical_key: PhysicalKey::Code(KeyCode::Escape),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} => control_flow.exit(),
|
|
||||||
|
|
||||||
WindowEvent::Resized(size) => {
|
let mut state = State::new(&window).await;
|
||||||
self.resize(*size);
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowEvent::RedrawRequested => {
|
event_loop
|
||||||
self.window().request_redraw();
|
.run(move |event, control_flow| match event {
|
||||||
/*
|
Event::WindowEvent {
|
||||||
if !surface_configured {
|
ref event,
|
||||||
return;
|
window_id,
|
||||||
} ??????
|
} if window_id == state.window().id() => {
|
||||||
*/
|
if !state.input(event) {
|
||||||
|
match event {
|
||||||
|
WindowEvent::CloseRequested
|
||||||
|
| WindowEvent::KeyboardInput {
|
||||||
|
event:
|
||||||
|
KeyEvent {
|
||||||
|
state: ElementState::Pressed,
|
||||||
|
physical_key: PhysicalKey::Code(KeyCode::Escape),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => control_flow.exit(),
|
||||||
|
|
||||||
self.update();
|
WindowEvent::Resized(size) => {
|
||||||
|
state.resize(*size);
|
||||||
|
}
|
||||||
|
|
||||||
match self.render() {
|
WindowEvent::RedrawRequested => {
|
||||||
Ok(_) => (),
|
state.window().request_redraw();
|
||||||
Err(
|
/*
|
||||||
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
if !surface_configured {
|
||||||
) => {
|
return;
|
||||||
self.resize(self.size);
|
} ??????
|
||||||
}
|
*/
|
||||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
|
||||||
log::error!("OutOfMemory");
|
state.update();
|
||||||
control_flow.exit();
|
|
||||||
}
|
match state.render() {
|
||||||
Err(wgpu::SurfaceError::Timeout) => {
|
Ok(_) => (),
|
||||||
log::warn!("Surface Timeout")
|
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
|
||||||
}
|
state.resize(state.size);
|
||||||
|
}
|
||||||
|
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||||
|
log::error!("OutOfMemory");
|
||||||
|
control_flow.exit();
|
||||||
|
}
|
||||||
|
Err(wgpu::SurfaceError::Timeout) => {
|
||||||
|
log::warn!("Surface Timeout")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
})
|
_ => {}
|
||||||
.unwrap();
|
})
|
||||||
}
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
11
src/main.rs
Normal file
11
src/main.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
use tokio;
|
||||||
|
use testing::front::{structs::*, enums::*};
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
// the number of sides for the regular polygon; must be >= 3
|
||||||
|
// ~25M sides = 8 GB of RAM usage
|
||||||
|
let sides = 100_000_000;
|
||||||
|
let verts = Polygon::new_from_radius_with_rotation(Vertex::new(Pos::new(0.0, 0.0, 0.0), Col::new(0.1, 0.2, 0.3)), 0.5, sides, Rotation::Custom(0.0)).unwrap().uniform();
|
||||||
|
std::fs::write("output", format!("{:?}", verts)).unwrap();
|
||||||
|
}
|
|
@ -1,41 +1,32 @@
|
||||||
use super::super::structure::{enums::Resolution, structs::Vertex};
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use wgpu::{
|
use wgpu::{
|
||||||
util::{BufferInitDescriptor, DeviceExt},
|
naga::back::INDENT, util::DeviceExt, Buffer, BufferUsages, Color, PipelineLayout, PipelineLayoutDescriptor, RenderPassColorAttachment, RenderPipelineDescriptor, ShaderModuleDescriptor, VertexState
|
||||||
BufferUsages, Color, PipelineLayout, PipelineLayoutDescriptor, RenderPassColorAttachment,
|
|
||||||
RenderPipelineDescriptor, ShaderModuleDescriptor, VertexBufferLayout, VertexState,
|
|
||||||
};
|
|
||||||
use winit::{
|
|
||||||
event::WindowEvent,
|
|
||||||
event_loop::{self, EventLoop},
|
|
||||||
window::{Window, WindowBuilder},
|
|
||||||
};
|
};
|
||||||
|
use winit::{event::WindowEvent, window::Window};
|
||||||
|
|
||||||
|
use crate::front::structs::{Col, Polygon, Pos, Vertex};
|
||||||
|
|
||||||
pub struct State<'a> {
|
pub struct State<'a> {
|
||||||
pub clear_color: wgpu::Color,
|
pub surface: wgpu::Surface<'a>,
|
||||||
pub(crate) config: wgpu::SurfaceConfiguration,
|
pub device: wgpu::Device,
|
||||||
pub(crate) device: wgpu::Device,
|
pub queue: wgpu::Queue,
|
||||||
//pub index_buffer: wgpu::Buffer,
|
pub config: wgpu::SurfaceConfiguration,
|
||||||
pub num_index: u32,
|
pub size: winit::dpi::PhysicalSize<u32>,
|
||||||
pub(crate) queue: wgpu::Queue,
|
|
||||||
pub(crate) render_pipeline: wgpu::RenderPipeline,
|
|
||||||
pub resolution: Resolution,
|
|
||||||
pub(crate) size: winit::dpi::PhysicalSize<u32>,
|
|
||||||
pub(crate) surface: wgpu::Surface<'a>,
|
|
||||||
pub(crate) vertex_buffer: wgpu::Buffer,
|
|
||||||
// The window must be declared after the surface so
|
// The window must be declared after the surface so
|
||||||
// it gets dropped after it as the surface contains
|
// it gets dropped after it as the surface contains
|
||||||
// unsafe references to the window's resources.
|
// unsafe references to the window's resources.
|
||||||
pub(crate) window: &'a Window
|
pub window: &'a Window,
|
||||||
|
pub clear_color: wgpu::Color,
|
||||||
|
pub render_pipeline: wgpu::RenderPipeline,
|
||||||
|
pub vertex_buffer: wgpu::Buffer,
|
||||||
|
//pub index_buffer: wgpu::Buffer,
|
||||||
|
pub num_index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> State<'a> {
|
impl<'a> State<'a> {
|
||||||
// Creating some of the wgpu types requires async code
|
// Creating some of the wgpu types requires async code
|
||||||
pub async fn new(
|
pub async fn new(window: &'a Window) -> State<'a> {
|
||||||
window: &'a Window,
|
|
||||||
verts: Option<&[u8]>,
|
|
||||||
resolution: Resolution,
|
|
||||||
) -> State<'a> {
|
|
||||||
|
|
||||||
// * ---------- SIZE ----------
|
// * ---------- SIZE ----------
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
// * ---------- SIZE ----------
|
// * ---------- SIZE ----------
|
||||||
|
@ -119,68 +110,59 @@ impl<'a> State<'a> {
|
||||||
let shader: wgpu::ShaderModule = device.create_shader_module(ShaderModuleDescriptor {
|
let shader: wgpu::ShaderModule = device.create_shader_module(ShaderModuleDescriptor {
|
||||||
label: Some("shader"),
|
label: Some("shader"),
|
||||||
// source: wgpu::ShaderSource::Wgsl(include_str!("learn_shading.wgsl").into()),
|
// source: wgpu::ShaderSource::Wgsl(include_str!("learn_shading.wgsl").into()),
|
||||||
source: wgpu::ShaderSource::Wgsl(include_str!("../shaders/shader.wgsl").into()),
|
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
|
||||||
});
|
});
|
||||||
|
|
||||||
let render_pipeline_layout: PipelineLayout =
|
let render_pipeline_layout: PipelineLayout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
|
||||||
device.create_pipeline_layout(&PipelineLayoutDescriptor {
|
label: Some("Render Pipeline Layout"),
|
||||||
label: Some("Render Pipeline Layout"),
|
bind_group_layouts: &[],
|
||||||
bind_group_layouts: &[],
|
push_constant_ranges: &[],
|
||||||
push_constant_ranges: &[],
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let render_pipeline: wgpu::RenderPipeline =
|
let render_pipeline: wgpu::RenderPipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
|
||||||
device.create_render_pipeline(&RenderPipelineDescriptor {
|
label: Some("Pipeline"),
|
||||||
label: Some("Pipeline"),
|
layout: Some(&render_pipeline_layout),
|
||||||
layout: Some(&render_pipeline_layout),
|
vertex: VertexState {
|
||||||
vertex: VertexState {
|
module: &shader,
|
||||||
module: &shader,
|
entry_point: "vs_main",
|
||||||
entry_point: "vs_main",
|
compilation_options: Default::default(),
|
||||||
compilation_options: Default::default(),
|
buffers: &[
|
||||||
buffers: &[Vertex::desc()],
|
Vertex::desc(),
|
||||||
},
|
],
|
||||||
fragment: Some(wgpu::FragmentState {
|
},
|
||||||
module: &shader,
|
fragment: Some(wgpu::FragmentState {
|
||||||
entry_point: "fs_main",
|
module: &shader,
|
||||||
compilation_options: Default::default(),
|
entry_point: "fs_main",
|
||||||
targets: &[Some(wgpu::ColorTargetState {
|
compilation_options: Default::default(),
|
||||||
format: config.format,
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
blend: Some(wgpu::BlendState::REPLACE),
|
format: config.format,
|
||||||
write_mask: wgpu::ColorWrites::ALL,
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
})],
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
}),
|
})],
|
||||||
primitive: wgpu::PrimitiveState {
|
}),
|
||||||
topology: wgpu::PrimitiveTopology::TriangleStrip,
|
primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleStrip, strip_index_format: None, front_face: wgpu::FrontFace::Ccw, cull_mode: Some(wgpu::Face::Back), unclipped_depth: false, polygon_mode: wgpu::PolygonMode::Fill, conservative: false },
|
||||||
strip_index_format: None,
|
depth_stencil: None,
|
||||||
front_face: wgpu::FrontFace::Ccw,
|
multisample: wgpu::MultisampleState { count: 1, mask: !0, alpha_to_coverage_enabled: false },
|
||||||
cull_mode: Some(wgpu::Face::Back),
|
multiview: None,
|
||||||
unclipped_depth: false,
|
cache: None
|
||||||
polygon_mode: wgpu::PolygonMode::Fill,
|
});
|
||||||
conservative: false,
|
|
||||||
},
|
|
||||||
depth_stencil: None,
|
|
||||||
multisample: wgpu::MultisampleState {
|
|
||||||
count: 1,
|
|
||||||
mask: !0,
|
|
||||||
alpha_to_coverage_enabled: false,
|
|
||||||
},
|
|
||||||
multiview: None,
|
|
||||||
cache: None,
|
|
||||||
});
|
|
||||||
// * ---------- PIPELINE ----------
|
// * ---------- PIPELINE ----------
|
||||||
|
|
||||||
let verts_final = match verts {
|
let verts = Polygon::new_from_radius_with_rotation(Vertex::new(Pos::new(0.0, 0.0, 0.0), Col::new(0.2, 0.4, 0.6)), 0.5, 268435456, crate::front::enums::Rotation::HorizontalAlign).unwrap().uniform();
|
||||||
Some(v) => v,
|
|
||||||
None => &[],
|
let something: &[u8] = bytemuck::cast_slice(&verts);
|
||||||
};
|
|
||||||
|
//println!("{:?}", verts);
|
||||||
|
std::fs::write("stuff", format!("{:?}", verts)).unwrap();
|
||||||
|
|
||||||
// ! ---------- VERT BUFFER ----------
|
// ! ---------- VERT BUFFER ----------
|
||||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
|
||||||
label: Some("Vertex Buffer"),
|
label: Some("Vertex Buffer"),
|
||||||
contents: verts_final,
|
// contents: bytemuck::cast_slice(&VERTS),
|
||||||
|
contents: something,
|
||||||
usage: BufferUsages::VERTEX,
|
usage: BufferUsages::VERTEX,
|
||||||
});
|
});
|
||||||
let num_index = (verts_final.len() / std::mem::size_of::<Vertex>()) as u32;
|
let num_index = verts.len() as u32;
|
||||||
// ! ---------- VERT BUFFER ----------
|
// ! ---------- VERT BUFFER ----------
|
||||||
|
|
||||||
// // ! ---------- INDEX BUFFER ----------
|
// // ! ---------- INDEX BUFFER ----------
|
||||||
|
@ -194,7 +176,6 @@ impl<'a> State<'a> {
|
||||||
let clear_color = Color::WHITE;
|
let clear_color = Color::WHITE;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
resolution,
|
|
||||||
window,
|
window,
|
||||||
surface,
|
surface,
|
||||||
device,
|
device,
|
||||||
|
@ -274,7 +255,7 @@ impl<'a> State<'a> {
|
||||||
label: Some("encoder"),
|
label: Some("encoder"),
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut render_pass= encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
label: Some("Render Pass"),
|
label: Some("Render Pass"),
|
||||||
color_attachments: &[Some(RenderPassColorAttachment {
|
color_attachments: &[Some(RenderPassColorAttachment {
|
||||||
view: &view,
|
view: &view,
|
||||||
|
@ -302,14 +283,4 @@ impl<'a> State<'a> {
|
||||||
output.present();
|
output.present();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn modify_vert_buffer(&mut self, verts: Vec<Vertex>) {
|
|
||||||
self.vertex_buffer = self.device.create_buffer_init(&BufferInitDescriptor {
|
|
||||||
label: Some("Vertex Buffer"),
|
|
||||||
// contents: bytemuck::cast_slice(&VERTS),
|
|
||||||
contents: bytemuck::cast_slice(&verts),
|
|
||||||
usage: BufferUsages::VERTEX,
|
|
||||||
});
|
|
||||||
self.num_index = verts.len() as u32;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1 +0,0 @@
|
||||||
pub mod state;
|
|
|
@ -1,39 +0,0 @@
|
||||||
pub use micellaneous::Resolution;
|
|
||||||
|
|
||||||
|
|
||||||
pub mod micellaneous {
|
|
||||||
use crate::structure::structs::baseline::polygon::Polygon;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum Resolution {
|
|
||||||
Res_16_10,
|
|
||||||
Res_16_9,
|
|
||||||
Res_4_3,
|
|
||||||
Res_21_9,
|
|
||||||
Res_32_9,
|
|
||||||
Res_5_4,
|
|
||||||
Custom((u16, u16)),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum Rotation {
|
|
||||||
HorizontalAlign,
|
|
||||||
VerticalAlign,
|
|
||||||
Custom(f32),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum Shape {
|
|
||||||
Regular(Polygon),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod errors {
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum PolyError {
|
|
||||||
NotEnoughSides,
|
|
||||||
SidesAndTriangleNumberArentConsistant,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub mod structs;
|
|
||||||
pub mod enums;
|
|
||||||
pub mod traits;
|
|
|
@ -1,270 +0,0 @@
|
||||||
pub use baseline::color::Col;
|
|
||||||
pub use baseline::position::Pos;
|
|
||||||
pub use baseline::vertex::Vertex;
|
|
||||||
|
|
||||||
pub mod baseline {
|
|
||||||
pub mod position {
|
|
||||||
use bytemuck::{bytes_of, Pod, Zeroable};
|
|
||||||
|
|
||||||
use crate::structure::traits::Drawable;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Pos(pub(crate) [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 {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod color {
|
|
||||||
use bytemuck::{Pod, Zeroable};
|
|
||||||
use rand::Rng;
|
|
||||||
|
|
||||||
use crate::structure::traits::Drawable;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Col(pub(crate) [f32; 3]);
|
|
||||||
|
|
||||||
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 {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod vertex {
|
|
||||||
use crate::structure::traits::Drawable;
|
|
||||||
use bytemuck::{NoUninit, Pod, Zeroable};
|
|
||||||
use wgpu::VertexAttribute;
|
|
||||||
|
|
||||||
use super::super::*;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Vertex {
|
|
||||||
pub(crate) position: Pos,
|
|
||||||
pub(crate) color: Col,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Zeroable for Vertex {}
|
|
||||||
unsafe impl Pod for Vertex {}
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod triangle {
|
|
||||||
use super::vertex::Vertex;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Triangle([Vertex; 3]);
|
|
||||||
|
|
||||||
impl Triangle {
|
|
||||||
pub fn new(vertices: [Vertex; 3]) -> Self {
|
|
||||||
Triangle(vertices)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn verts(&self) -> [Vertex; 3] {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod polygon {
|
|
||||||
use crate::structure::{enums::{errors::PolyError, micellaneous::Rotation}, traits::Drawable};
|
|
||||||
|
|
||||||
use super::{color::Col, position::Pos, triangle::Triangle, vertex::Vertex};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Polygon {
|
|
||||||
triangles: Vec<Triangle>,
|
|
||||||
center: Vertex,
|
|
||||||
radius: f32,
|
|
||||||
n_sides: usize,
|
|
||||||
rotation: Rotation,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Polygon {
|
|
||||||
/// # USAGE
|
|
||||||
/// quality of life method, alias [Polygon::new_from_radius_with_rotation()] with `rotation == 0.0`
|
|
||||||
pub fn new_from_radius(center: Vertex, radius: f32, n_sides: usize) -> Result<Self, PolyError> {
|
|
||||||
Self::new_from_radius_with_rotation(center, radius, n_sides, Rotation::HorizontalAlign)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # USAGE
|
|
||||||
/// creates a [Polygon] from a center and radius with a rotation.
|
|
||||||
///
|
|
||||||
/// # WARNING
|
|
||||||
/// - the rotation must be given in radiants.
|
|
||||||
pub fn new_from_radius_with_rotation(
|
|
||||||
center: Vertex,
|
|
||||||
radius: f32,
|
|
||||||
n_sides: usize,
|
|
||||||
rotation: Rotation,
|
|
||||||
) -> Result<Self, PolyError> {
|
|
||||||
if n_sides < 3 {
|
|
||||||
return Err(PolyError::NotEnoughSides);
|
|
||||||
}
|
|
||||||
|
|
||||||
let rotation_rad = match rotation {
|
|
||||||
Rotation::HorizontalAlign => {
|
|
||||||
if n_sides % 6 == 0 {
|
|
||||||
0.0
|
|
||||||
} else if n_sides % 4 == 0 {
|
|
||||||
(std::f32::consts::PI * 2.0 / n_sides as f32) / 2.0
|
|
||||||
} else if n_sides % 3 == 0 {
|
|
||||||
match ((n_sides-3)/6)%2 {
|
|
||||||
1 => (std::f32::consts::PI * 2.0 / n_sides as f32) / 4.0,
|
|
||||||
0 => (std::f32::consts::PI * 2.0)- ((std::f32::consts::PI * 2.0 / n_sides as f32) / 4.0),
|
|
||||||
_ => panic!(), // should never happen, it's a module. ( % 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
0.0
|
|
||||||
} //TODO: add other n_sides
|
|
||||||
},
|
|
||||||
Rotation::VerticalAlign => (std::f32::consts::PI * 2.0 / n_sides as f32) / 2.0, // TODO
|
|
||||||
Rotation::Custom(rad) => rad,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut vec_tris: Vec<Triangle> = Vec::with_capacity(n_sides); // TODO: add space 4 morph
|
|
||||||
|
|
||||||
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) + rotation_rad;
|
|
||||||
let theta_next =
|
|
||||||
(((v + 1) as f32 / n_sides as f32) * 2.0 * std::f32::consts::PI) + rotation_rad;
|
|
||||||
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_everything_with_rotation(vec_tris, center, radius, n_sides, rotation)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # USAGE
|
|
||||||
/// quality of life method, alias [Polygon::new_from_everything_with_rotation()] with `rotation == Rotation::HorizontalAlign`
|
|
||||||
fn new_from_everything(
|
|
||||||
triangles: Vec<Triangle>,
|
|
||||||
center: Vertex,
|
|
||||||
radius: f32,
|
|
||||||
n_sides: usize,
|
|
||||||
) -> Result<Self, PolyError> {
|
|
||||||
Self::new_from_everything_with_rotation(
|
|
||||||
triangles,
|
|
||||||
center,
|
|
||||||
radius,
|
|
||||||
n_sides,
|
|
||||||
Rotation::HorizontalAlign,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// # USAGE
|
|
||||||
/// creates a [Polygon] from a center and radius with a rotation.
|
|
||||||
///
|
|
||||||
/// # WARNING
|
|
||||||
/// - the rotation must be given in radiants.
|
|
||||||
fn new_from_everything_with_rotation(
|
|
||||||
triangles: Vec<Triangle>,
|
|
||||||
center: Vertex,
|
|
||||||
radius: f32,
|
|
||||||
n_sides: usize,
|
|
||||||
rotation: Rotation,
|
|
||||||
) -> Result<Self, PolyError> {
|
|
||||||
if n_sides < 3 {
|
|
||||||
return Err(PolyError::NotEnoughSides);
|
|
||||||
}
|
|
||||||
|
|
||||||
if triangles.len() != n_sides {
|
|
||||||
return Err(PolyError::SidesAndTriangleNumberArentConsistant);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Polygon {
|
|
||||||
triangles,
|
|
||||||
center,
|
|
||||||
radius,
|
|
||||||
n_sides,
|
|
||||||
rotation,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_triangles(&self) -> Vec<Triangle> {
|
|
||||||
self.triangles.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn uniform(&self) -> Vec<Vertex> {
|
|
||||||
self.get_triangles()
|
|
||||||
.iter()
|
|
||||||
.flat_map(|t| t.verts().to_vec())
|
|
||||||
.collect::<Vec<Vertex>>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drawable for Polygon {
|
|
||||||
fn uniform(&self) -> Vec<Vertex> {
|
|
||||||
self.uniform()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
use bytemuck::NoUninit;
|
|
||||||
|
|
||||||
use super::structs::Vertex;
|
|
||||||
|
|
||||||
pub trait Drawable {
|
|
||||||
fn uniform(&self) -> Vec<Vertex>;
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue