use std::iter;
use std::fmt::{Display, Formatter, Result};
#[derive(Debug, Clone, Default)]
pub struct Mesh {
pub format: Format,
pub name: Option<String>,
pub start: usize,
pub vertices: Vec<Vertex>,
pub indices: Vec<[usize; 3]>,
pub normals: Vec<Vertex>,
pub header: Option<[u8; 80]>,
pub color: Option<Color>,
pub colors: Option<Vec<Color>>,
pub attrs: Option<Vec<u16>>,
}
impl Mesh {
pub fn triangles(&self) -> Vec<Triangle> {
self.indices.iter().enumerate().map(|(i, v)| Triangle {
normal: self.normals[i],
vertices: [self.vertices[v[0]], self.vertices[v[1]], self.vertices[v[2]]],
}).collect()
}
pub fn get_positions(&self) -> Vec<[f32; 3]> {
self.vertices.iter().map(|v| {
[v.x, v.z, -v.y]
}).collect()
}
pub fn get_normals(&self) -> Vec<[f32; 3]> {
self.normals.iter().flat_map(|v| {
iter::repeat([v.x, v.z, -v.y]).take(3)
}).collect()
}
pub fn get_indices(&self) -> Vec<u32> {
self.indices.iter().flat_map(|v| [v[0] as u32, v[1] as u32, v[2] as u32]).collect()
}
}
#[derive(Debug, Clone, Default)]
pub enum Format {
#[default]
Ascii,
Binary,
}
impl Display for Format {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
Format::Ascii => write!(f, "ascii"),
Format::Binary => write!(f, "binary"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Triangle {
pub normal: Vertex,
pub vertices: [Vertex; 3],
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vertex {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl From<&[f32; 3]> for Vertex {
fn from(xyz: &[f32; 3]) -> Self {
Self {
x: xyz[0],
y: xyz[1],
z: xyz[2],
}
}
}
impl From<&Vertex> for [f32; 3] {
fn from(v: &Vertex) -> Self {
[v.x, v.y, v.z]
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl From<&[u8; 4]> for Color {
fn from(rgba: &[u8; 4]) -> Self {
Self {
r: rgba[0],
g: rgba[1],
b: rgba[2],
a: rgba[3],
}
}
}