diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-19 16:44:06 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-19 16:44:06 +0100 |
commit | 2d6f319dfccf6339ed1a3bbfb003b8b2dde82383 (patch) | |
tree | 4229b75a26d6e02d1eb15c84096c7020875e650e /client/src/meshops.rs | |
parent | 2c737d660cab38fdf4ff3e940395df396a75f959 (diff) | |
download | weareserver-2d6f319dfccf6339ed1a3bbfb003b8b2dde82383.tar weareserver-2d6f319dfccf6339ed1a3bbfb003b8b2dde82383.tar.bz2 weareserver-2d6f319dfccf6339ed1a3bbfb003b8b2dde82383.tar.zst |
client: normal maps
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!() +} |