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]
|
||||
name = "library-maths"
|
||||
name = "testing"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
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);
|
||||
}
|
62
src/lib.rs
62
src/lib.rs
|
@ -1,21 +1,32 @@
|
|||
use state::state::State;
|
||||
use winit::{event::{ElementState, Event, KeyEvent, WindowEvent}, event_loop::EventLoop, keyboard::{KeyCode, PhysicalKey}, window::WindowBuilder};
|
||||
pub mod front;
|
||||
pub mod state;
|
||||
|
||||
mod state;
|
||||
mod structure;
|
||||
mod canvas;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use state::State;
|
||||
use wgpu::VertexAttribute;
|
||||
use winit::{
|
||||
dpi::Size,
|
||||
event::*,
|
||||
event_loop::EventLoop,
|
||||
keyboard::{KeyCode, PhysicalKey},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
|
||||
// * re-exports
|
||||
pub use canvas::Canvas;
|
||||
pub use structure::enums::Resolution;
|
||||
pub use structure::enums::micellaneous::Shape;
|
||||
pub use structure::structs::baseline::polygon::Polygon;
|
||||
pub use structure::structs::Vertex;
|
||||
pub use structure::structs::{Col, Pos};
|
||||
// * re-exports
|
||||
// const VERTS: &[Vertex] = &[
|
||||
// Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] }, // A
|
||||
// Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] }, // B
|
||||
// Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] }, // C
|
||||
// Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] }, // D
|
||||
// Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] }, // E
|
||||
// ];
|
||||
|
||||
impl State<'_> {
|
||||
pub fn run(&mut self) {
|
||||
// const INDICES: &[u16] = &[
|
||||
// 0, 1, 4,
|
||||
// 1, 2, 4,
|
||||
// 2, 3, 4,
|
||||
// ];
|
||||
|
||||
pub async fn run() {
|
||||
env_logger::init();
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
let window = WindowBuilder::new()
|
||||
|
@ -23,13 +34,15 @@ impl State<'_> {
|
|||
.build(&event_loop)
|
||||
.unwrap();
|
||||
|
||||
let mut state = State::new(&window).await;
|
||||
|
||||
event_loop
|
||||
.run(move |event, control_flow| match event {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == self.window().id() => {
|
||||
if !self.input(event) {
|
||||
} if window_id == state.window().id() => {
|
||||
if !state.input(event) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested
|
||||
| WindowEvent::KeyboardInput {
|
||||
|
@ -43,25 +56,23 @@ impl State<'_> {
|
|||
} => control_flow.exit(),
|
||||
|
||||
WindowEvent::Resized(size) => {
|
||||
self.resize(*size);
|
||||
state.resize(*size);
|
||||
}
|
||||
|
||||
WindowEvent::RedrawRequested => {
|
||||
self.window().request_redraw();
|
||||
state.window().request_redraw();
|
||||
/*
|
||||
if !surface_configured {
|
||||
return;
|
||||
} ??????
|
||||
*/
|
||||
|
||||
self.update();
|
||||
state.update();
|
||||
|
||||
match self.render() {
|
||||
match state.render() {
|
||||
Ok(_) => (),
|
||||
Err(
|
||||
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
|
||||
) => {
|
||||
self.resize(self.size);
|
||||
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
|
||||
state.resize(state.size);
|
||||
}
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||
log::error!("OutOfMemory");
|
||||
|
@ -81,4 +92,3 @@ impl State<'_> {
|
|||
})
|
||||
.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::{
|
||||
util::{BufferInitDescriptor, DeviceExt},
|
||||
BufferUsages, Color, PipelineLayout, PipelineLayoutDescriptor, RenderPassColorAttachment,
|
||||
RenderPipelineDescriptor, ShaderModuleDescriptor, VertexBufferLayout, VertexState,
|
||||
};
|
||||
use winit::{
|
||||
event::WindowEvent,
|
||||
event_loop::{self, EventLoop},
|
||||
window::{Window, WindowBuilder},
|
||||
naga::back::INDENT, util::DeviceExt, Buffer, BufferUsages, Color, PipelineLayout, PipelineLayoutDescriptor, RenderPassColorAttachment, RenderPipelineDescriptor, ShaderModuleDescriptor, VertexState
|
||||
};
|
||||
use winit::{event::WindowEvent, window::Window};
|
||||
|
||||
use crate::front::structs::{Col, Polygon, Pos, Vertex};
|
||||
|
||||
pub struct State<'a> {
|
||||
pub clear_color: wgpu::Color,
|
||||
pub(crate) config: wgpu::SurfaceConfiguration,
|
||||
pub(crate) device: wgpu::Device,
|
||||
//pub index_buffer: wgpu::Buffer,
|
||||
pub num_index: 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,
|
||||
pub surface: wgpu::Surface<'a>,
|
||||
pub device: wgpu::Device,
|
||||
pub queue: wgpu::Queue,
|
||||
pub config: wgpu::SurfaceConfiguration,
|
||||
pub size: winit::dpi::PhysicalSize<u32>,
|
||||
// The window must be declared after the surface so
|
||||
// it gets dropped after it as the surface contains
|
||||
// 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> {
|
||||
// Creating some of the wgpu types requires async code
|
||||
pub async fn new(
|
||||
window: &'a Window,
|
||||
verts: Option<&[u8]>,
|
||||
resolution: Resolution,
|
||||
) -> State<'a> {
|
||||
|
||||
pub async fn new(window: &'a Window) -> State<'a> {
|
||||
// * ---------- SIZE ----------
|
||||
let size = window.inner_size();
|
||||
// * ---------- SIZE ----------
|
||||
|
@ -119,25 +110,25 @@ impl<'a> State<'a> {
|
|||
let shader: wgpu::ShaderModule = device.create_shader_module(ShaderModuleDescriptor {
|
||||
label: Some("shader"),
|
||||
// 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 =
|
||||
device.create_pipeline_layout(&PipelineLayoutDescriptor {
|
||||
let render_pipeline_layout: PipelineLayout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
|
||||
label: Some("Render Pipeline Layout"),
|
||||
bind_group_layouts: &[],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
let render_pipeline: wgpu::RenderPipeline =
|
||||
device.create_render_pipeline(&RenderPipelineDescriptor {
|
||||
let render_pipeline: wgpu::RenderPipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
|
||||
label: Some("Pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex: VertexState {
|
||||
module: &shader,
|
||||
entry_point: "vs_main",
|
||||
compilation_options: Default::default(),
|
||||
buffers: &[Vertex::desc()],
|
||||
buffers: &[
|
||||
Vertex::desc(),
|
||||
],
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: &shader,
|
||||
|
@ -149,38 +140,29 @@ impl<'a> State<'a> {
|
|||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})],
|
||||
}),
|
||||
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,
|
||||
},
|
||||
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 },
|
||||
depth_stencil: None,
|
||||
multisample: wgpu::MultisampleState {
|
||||
count: 1,
|
||||
mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
},
|
||||
multisample: wgpu::MultisampleState { count: 1, mask: !0, alpha_to_coverage_enabled: false },
|
||||
multiview: None,
|
||||
cache: None,
|
||||
cache: None
|
||||
});
|
||||
// * ---------- PIPELINE ----------
|
||||
|
||||
let verts_final = match verts {
|
||||
Some(v) => v,
|
||||
None => &[],
|
||||
};
|
||||
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();
|
||||
|
||||
let something: &[u8] = bytemuck::cast_slice(&verts);
|
||||
|
||||
//println!("{:?}", verts);
|
||||
std::fs::write("stuff", format!("{:?}", verts)).unwrap();
|
||||
|
||||
// ! ---------- VERT BUFFER ----------
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
|
||||
label: Some("Vertex Buffer"),
|
||||
contents: verts_final,
|
||||
// contents: bytemuck::cast_slice(&VERTS),
|
||||
contents: something,
|
||||
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 ----------
|
||||
|
||||
// // ! ---------- INDEX BUFFER ----------
|
||||
|
@ -194,7 +176,6 @@ impl<'a> State<'a> {
|
|||
let clear_color = Color::WHITE;
|
||||
|
||||
Self {
|
||||
resolution,
|
||||
window,
|
||||
surface,
|
||||
device,
|
||||
|
@ -302,14 +283,4 @@ impl<'a> State<'a> {
|
|||
output.present();
|
||||
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