diff options
Diffstat (limited to 'client/src/meshops.rs')
-rw-r--r-- | client/src/meshops.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/client/src/meshops.rs b/client/src/meshops.rs new file mode 100644 index 0000000..e76e02a --- /dev/null +++ b/client/src/meshops.rs @@ -0,0 +1,64 @@ +use glam::{Vec2, Vec3, Vec3A}; + +pub fn generate_normals(index: &[[u32; 3]], position: &[Vec3]) -> Vec<Vec3> { + let mut normal_denom = vec![0; position.len()]; + let mut normal = vec![Vec3::ZERO; position.len()]; + + for &[a, b, c] in index { + let pos_a = position[a as usize]; + let pos_b = position[b as usize]; + let pos_c = position[c as usize]; + + // TODO is this right? + let norm = (pos_b - pos_a).cross(pos_c - pos_a).normalize(); + + normal[a as usize] += norm; + normal[b as usize] += norm; + normal[c as usize] += norm; + normal_denom[a as usize] += 1; + normal_denom[b as usize] += 1; + normal_denom[c as usize] += 1; + } + for (denom, tang) in normal_denom.iter().zip(normal.iter_mut()) { + *tang /= *denom as f32; + } + + normal +} + +pub fn generate_tangents(index: &[[u32; 3]], position: &[Vec3], texcoord: &[Vec2]) -> Vec<Vec3> { + let mut tangent_denom = vec![0; position.len()]; + let mut tangent = vec![Vec3::ZERO; position.len()]; + + for &[a, b, c] in index { + let (pos_a, uv_a) = (position[a as usize], texcoord[a as usize]); + let (pos_b, uv_b) = (position[b as usize], texcoord[b as usize]); + let (pos_c, uv_c) = (position[c as usize], texcoord[c as usize]); + + let pd_ba = pos_b - pos_a; + let pd_ca = pos_c - pos_a; + let td_ba = uv_b - uv_a; + let td_ca = uv_c - uv_a; + + let face_tangent = + (pd_ba * td_ca.y - pd_ca * td_ba.y) * (td_ba.x * td_ca.y - td_ba.y * td_ca.x); + + tangent[a as usize] += face_tangent; + tangent[b as usize] += face_tangent; + tangent[c as usize] += face_tangent; + tangent_denom[a as usize] += 1; + tangent_denom[b as usize] += 1; + tangent_denom[c as usize] += 1; + } + for (denom, tang) in tangent_denom.iter().zip(tangent.iter_mut()) { + *tang /= *denom as f32; + } + + tangent +} + +pub fn generate_texcoords(index: &[[u32; 3]], position: &[Vec3A]) -> Vec<Vec2> { + let _ = (index, position); + // TODO implement equirectangular projection + todo!() +} |