Repository: AmbientRun/Ambient
File: crates/std/src/uncategorized/mesh.rs (Rust)

Code before:
        if let Some(positions) = &self.positions {
            if positions.is_empty() {
                return None;
            }
            let mut aabb = AABB {
                min: positions[0],
                max: positions[0],
            };
            for &pos in positions.iter().skip(1) {
                aabb.min = aabb.min.min(pos);
                aabb.max = aabb.max.max(pos);
            }
            Some(aabb)
        } else {
            None
        }
    }
    pub fn transform(&mut self, transform: Mat4) {
        if let Some(positions) = &mut self.positions {
            for p in positions {
                *p = transform.project_point3(vec3(p[0], p[1], p[2]));
            }
        }
        if let Some(normals) = &mut self.normals {
            for p in normals {
                *p = transform
                    .transform_vector3(vec3(p[0], p[1], p[2]))
                    .normalize();
            }
        }
    }
    /// Flips indicies so that what was front facing will become back facing and vice versa
    pub fn invert_indicies(&mut self) {
        if let Some(indicies) = &mut self.indices {
            for chunk in indicies.chunks_exact_mut(3) {
                chunk.swap(1, 2);
            }
        }
    }
    pub fn apply_skin(&mut self, joint_matrices: &[Mat4]) {
        if let (Some(positions), Some(weights), Some(indices)) = (
            &mut self.positions,
            &self.joint_weights,
            &self.joint_indices,
        ) {
            for ((position, weight), index) in
                positions.iter_mut().zip(weights.iter()).zip(indices.iter())
            {
                let mat = joint_matrices[index.x as usize] * weight.x
                    + joint_matrices[index.y as usize] * weight.y
                    + joint_matrices[index.z as usize] * weight.z

Review comment (suggestion):
We could use `zip_eq` here if we expect them to be of the same length.

If not, we could use `izip!`to not have nested tuples

Code after:
        };
        for &pos in &self.positions[1..] {
            aabb.min = aabb.min.min(pos);
            aabb.max = aabb.max.max(pos);
        }
        Some(aabb)
    }
    pub fn transform(&mut self, transform: Mat4) {
        for p in &mut self.positions {
            *p = transform.project_point3(vec3(p[0], p[1], p[2]));
        }
        if let Some(normals) = &mut self.normals {
            for p in normals {
                *p = transform
                    .transform_vector3(vec3(p[0], p[1], p[2]))
                    .normalize();
            }
        }
    }
    pub fn flip_winding(&mut self) {
        for chunk in self.indices.chunks_exact_mut(3) {
            chunk.swap(1, 2);
        }
    }
    pub fn apply_skin(&mut self, joint_matrices: &[Mat4]) {
        if let (Some(weights), Some(indices)) = (&self.joint_weights, &self.joint_indices) {
            for ((position, weight), index) in self
                .positions
                .iter_mut()
                .zip(weights.iter())
                .zip(indices.iter())
            {
                let mat = joint_matrices[index.x as usize] * weight.x
                    + joint_matrices[index.y as usize] * weight.y
                    + joint_matrices[index.z as usize] * weight.z
                    + joint_matrices[index.w as usize] * weight.w;
                *position = mat.transform_point3(*position);
            }
        }
    }

    #[ambient_profiling::function]
    pub fn append(&mut self, mut mesh: Mesh) {
        let indices_offset = self.positions.len() as u32;
        self.positions.extend(mesh.positions);
        if let Some(x) = &mut self.colors {
            x.extend(mesh.colors.unwrap());
        }
        if let Some(x) = &mut self.normals {
            x.extend(mesh.normals.unwrap());
        }