1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
use crate::*; #[cfg(feature = "3d-io")] #[derive(serde::Serialize, serde::Deserialize, Debug)] pub struct CPUMesh { pub magic_number: u8, pub version: u8, pub indices: Vec<u32>, pub positions: Vec<f32>, pub normals: Vec<f32> } #[cfg(feature = "3d-io")] impl CPUMesh { pub fn new(indices: &[u32], positions: &[f32], normals: &[f32]) -> Result<Self, objects::Error> { Ok(CPUMesh {magic_number: 61, version: 1, indices: indices.to_owned(), positions: positions.to_owned(), normals: normals.to_owned()}) } pub fn new_with_computed_normals(indices: &[u32], positions: &[f32]) -> Result<Self, objects::Error> { Self::new(indices, positions, &compute_normals(indices, positions)) } pub fn from_bytes(bytes: &[u8]) -> Result<CPUMesh, bincode::Error> { let decoded: CPUMesh = bincode::deserialize(bytes)?; if decoded.magic_number != 61 { Err(bincode::Error::new(bincode::ErrorKind::Custom("Corrupt file!".to_string())))?; } Ok(decoded) } #[cfg(not(target_arch = "wasm32"))] pub fn from_file(path: &str) -> Result<CPUMesh, objects::Error> { let mut file = std::fs::File::open(path)?; let mut bytes = Vec::new(); use std::io::prelude::*; file.read_to_end(&mut bytes)?; Ok(Self::from_bytes(&bytes)?) } pub fn to_bytes(&self) -> Result<Vec<u8>, objects::Error> { Ok(bincode::serialize(self)?) } #[cfg(not(target_arch = "wasm32"))] pub fn to_file(&self, path: &str) -> Result<(), objects::Error> { let mut file = std::fs::File::create(path)?; use std::io::prelude::*; file.write_all(&self.to_bytes()?)?; Ok(()) } pub fn to_mesh(&self, gl: &crate::Gl) -> Result<Mesh, objects::Error> { Ok(crate::Mesh::new( &gl, &self.indices, &self.positions, &self.normals)?) } } fn compute_normals(indices: &[u32], positions: &[f32]) -> Vec<f32> { let mut normals = vec![0.0f32; positions.len() * 3]; for face in 0..indices.len()/3 { let index0 = indices[face*3] as usize; let p0 = vec3(positions[index0*3], positions[index0*3+1], positions[index0*3+2]); let index1 = indices[face*3 + 1] as usize; let p1 = vec3(positions[index1*3], positions[index1*3+1], positions[index1*3+2]); let index2 = indices[face*3 + 2] as usize; let p2 = vec3(positions[index2*3], positions[index2*3+1], positions[index2*3+2]); let normal = (p1 - p0).cross(p2 - p0); normals[index0*3] += normal.x; normals[index0*3+1] += normal.y; normals[index0*3+2] += normal.z; normals[index1*3] += normal.x; normals[index1*3+1] += normal.y; normals[index1*3+2] += normal.z; normals[index2*3] += normal.x; normals[index2*3+1] += normal.y; normals[index2*3+2] += normal.z; } for i in 0..normals.len()/3 { let normal = vec3(normals[3*i], normals[3*i+1], normals[3*i+2]).normalize(); normals[3*i] = normal.x; normals[3*i+1] = normal.y; normals[3*i+2] = normal.z; } normals }