initial commit of headless i guess
This commit is contained in:
parent
ffb009b737
commit
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