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
use crate::core::*; #[derive(Default, Debug)] pub struct CPUMesh { pub name: String, pub material_name: Option<String>, pub positions: Vec<f32>, pub indices: Option<Vec<u32>>, pub normals: Option<Vec<f32>>, pub uvs: Option<Vec<f32>> } impl CPUMesh { pub fn compute_normals(&mut self) { if let Some(ref ind) = self.indices { self.normals = Some(compute_normals_with_indices(ind, &self.positions)); } else { self.normals = Some(compute_normals(&self.positions)); } } pub fn compute_aabb(&self) -> AxisAlignedBoundingBox { AxisAlignedBoundingBox::new_from_positions(&self.positions) } } fn compute_normals_with_indices(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 } fn compute_normals(positions: &[f32]) -> Vec<f32> { let mut normals = vec![0.0f32; positions.len()]; for face in 0..positions.len()/9 { let index0 = face*3 as usize; let p0 = vec3(positions[index0*3], positions[index0*3+1], positions[index0*3+2]); let index1 = face*3 + 1 as usize; let p1 = vec3(positions[index1*3], positions[index1*3+1], positions[index1*3+2]); let index2 = 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 }