use std::fmt::Display;
use std::ops::Add;
use std::ops::Mul;
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BlockDims {
pub base: [f32; 3],
pub size: f32,
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Block {
pub dims: BlockDims,
pub subdivisions: usize,
}
impl Block {
pub fn from(base: [f32; 3], size: f32, subdivisions: usize) -> Self {
Block {
dims: BlockDims {
base: base,
size: size,
},
subdivisions: subdivisions,
}
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Mesh {
pub positions: Vec<f32>,
pub normals: Vec<f32>,
pub triangle_indices: Vec<usize>,
}
impl Mesh {
pub fn num_tris(&self) -> usize {
self.triangle_indices.len() / 3
}
pub fn tris(&self) -> Vec<Triangle> {
let mut tris: Vec<Triangle> = vec![];
for i in 0..self.num_tris() {
let i1 = self.triangle_indices[3 * i];
let i2 = self.triangle_indices[3 * i + 1];
let i3 = self.triangle_indices[3 * i + 2];
tris.push(Triangle {
vertices: [
Vertex {
position: [
self.positions[3 * i1],
self.positions[3 * i1 + 1],
self.positions[3 * i1 + 2],
],
normal: [
self.normals[3 * i1],
self.normals[3 * i1 + 1],
self.normals[3 * i1 + 2],
],
},
Vertex {
position: [
self.positions[3 * i2],
self.positions[3 * i2 + 1],
self.positions[3 * i2 + 2],
],
normal: [
self.normals[3 * i2],
self.normals[3 * i2 + 1],
self.normals[3 * i2 + 2],
],
},
Vertex {
position: [
self.positions[3 * i3],
self.positions[3 * i3 + 1],
self.positions[3 * i3 + 2],
],
normal: [
self.normals[3 * i3],
self.normals[3 * i3 + 1],
self.normals[3 * i3 + 2],
],
},
],
});
}
return tris;
}
}
#[derive(Debug, Clone, PartialEq, Copy)]
pub struct Triangle {
pub vertices: [Vertex; 3],
}
#[derive(Debug, Clone, PartialEq, Copy)]
pub struct Vertex {
pub position: [f32; 3],
pub normal: [f32; 3],
}
impl Display for Triangle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Triangle:")?;
let [v1, v2, v3] = self.vertices;
writeln!(f, " + Pos {:?} Norm {:?}", v1.position, v1.normal)?;
writeln!(f, " + Pos {:?} Norm {:?}", v2.position, v2.normal)?;
writeln!(f, " + Pos {:?} Norm {:?}", v3.position, v3.normal)?;
Ok(())
}
}
pub struct Position {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl Position {
pub fn interp_toward(&self, other: &Position, factor: f32) -> Position {
Position {
x: self.x + factor * (other.x - self.x),
y: self.y + factor * (other.y - self.y),
z: self.z + factor * (other.z - self.z),
}
}
}
impl Mul<f32> for &Position {
type Output = Position;
fn mul(self, rhs: f32) -> Self::Output {
Position {
x: self.x * rhs,
y: self.y * rhs,
z: self.z * rhs,
}
}
}
impl Add<&[f32; 3]> for &Position {
type Output = Position;
fn add(self, rhs: &[f32; 3]) -> Self::Output {
Position {
x: self.x + rhs[0],
y: self.y + rhs[1],
z: self.z + rhs[2],
}
}
}