/// Calculate tangents for the given set of buffers, based on normals and texture coordinates.
///
/// If zeroed is true, the normals will not be zeroed before hand. If this is falsely set, it is safe, just returns incorrect results.
///
/// # Safety
///
/// The following must be true:
/// - Tangents, positions, normals, and uvs must be the same length.
/// - All indices must be in-bounds for the buffers.
Calculate tangents for the given set of buffers, based on normals and texture coordinates.
If zeroed is true, the normals will not be zeroed before hand. If this is falsely set, it is safe, just returns incorrect results.
Calculate tangents for the given set of buffers based on normals and texture coordinates . If zeroed is true the normals will not be zeroed before hand . If this is falsely set it is safe just returns incorrect results .
pub unsafe fn calculate_tangents_for_buffers(
        tangents: &mut [Vec3],
        positions: &[Vec3],
        normals: &[Vec3],
        uvs: &[Vec2],
        indices: &[u32],
        zeroed: bool,
    ) {
        debug_assert_eq!(tangents.len(), positions.len());
        debug_assert_eq!(uvs.len(), positions.len());
        if !zeroed {
            for tan in tangents.iter_mut() {
                *tan = Vec3::ZERO;
            }
        }
        for idx in indices.chunks_exact(3) {
            let (idx0, idx1, idx2) = match *idx {
                [idx0, idx1, idx2] => (idx0, idx1, idx2),
                // SAFETY: This is guaranteed by chunks_exact(3)
                _ => std::hint::unreachable_unchecked(),
            };
            // SAFETY: The conditions of this function assert all thes indices are in-bounds
            let pos1 = *positions.get_unchecked(idx0 as usize);
            let pos2 = *positions.get_unchecked(idx1 as usize);
            let pos3 = *positions.get_unchecked(idx2 as usize);
            let tex1 = *uvs.get_unchecked(idx0 as usize);
            let tex2 = *uvs.get_unchecked(idx1 as usize);
            let tex3 = *uvs.get_unchecked(idx2 as usize);
            let edge1 = pos2 - pos1;
            let edge2 = pos3 - pos1;
            let uv1 = tex2 - tex1;
            let uv2 = tex3 - tex1;
            let r = 1.0 / (uv1.x * uv2.y - uv1.y * uv2.x);
            let tangent = Vec3::new(
                ((edge1.x * uv2.y) - (edge2.x * uv1.y)) * r,
                ((edge1.y * uv2.y) - (edge2.y * uv1.y)) * r,
                ((edge1.z * uv2.y) - (edge2.z * uv1.y)) * r,
            );
            // SAFETY: The conditions of this function assert all thes indices are in-bounds
            *tangents.get_unchecked_mut(idx0 as usize) += tangent;
            *tangents.get_unchecked_mut(idx1 as usize) += tangent;
            *tangents.get_unchecked_mut(idx2 as usize) += tangent;
        }
        for (tan, norm) in tangents.iter_mut().zip(normals) {
            let t = *tan - (*norm * norm.dot(*tan));
            *tan = t.normalize();
        }
    }
pub unsafe fn calculate_tangents_for_buffers ( tangents : & mut [ Vec3 ] , positions : & [ Vec3 ] , normals : & [ Vec3 ] , uvs : & [ Vec2 ] , indices : & [ u32 ] , zeroed : bool , ) { debug_assert_eq ! ( tangents len ( ) positions len ( ) ) ; debug_assert_eq ! ( uvs len ( ) positions len ( ) ) ; if ! zeroed { for tan in tangents . iter_mut ( ) { * tan = Vec3 :: ZERO ; } } for idx in indices . chunks_exact ( 3 ) { let ( idx0 , idx1 , idx2 ) = match * idx { [ idx0 , idx1 , idx2 ] => ( idx0 , idx1 , idx2 ) , // SAFETY: This is guaranteed by chunks_exact(3) _ => std :: hint :: unreachable_unchecked ( ) , } ; // SAFETY: The conditions of this function assert all thes indices are in-bounds let pos1 = * positions . get_unchecked ( idx0 as usize ) ; let pos2 = * positions . get_unchecked ( idx1 as usize ) ; let pos3 = * positions . get_unchecked ( idx2 as usize ) ; let tex1 = * uvs . get_unchecked ( idx0 as usize ) ; let tex2 = * uvs . get_unchecked ( idx1 as usize ) ; let tex3 = * uvs . get_unchecked ( idx2 as usize ) ; let edge1 = pos2 - pos1 ; let edge2 = pos3 - pos1 ; let uv1 = tex2 - tex1 ; let uv2 = tex3 - tex1 ; let r = 1.0 / ( uv1 . x * uv2 . y - uv1 . y * uv2 . x ) ; let tangent = Vec3 :: new ( ( ( edge1 . x * uv2 . y ) - ( edge2 . x * uv1 . y ) ) * r , ( ( edge1 . y * uv2 . y ) - ( edge2 . y * uv1 . y ) ) * r , ( ( edge1 . z * uv2 . y ) - ( edge2 . z * uv1 . y ) ) * r , ) ; // SAFETY: The conditions of this function assert all thes indices are in-bounds * tangents . get_unchecked_mut ( idx0 as usize ) += tangent ; * tangents . get_unchecked_mut ( idx1 as usize ) += tangent ; * tangents . get_unchecked_mut ( idx2 as usize ) += tangent ; } for ( tan , norm ) in tangents . iter_mut ( ) . zip ( normals ) { let t = * tan - ( * norm * norm . dot ( * tan ) ) ; * tan = t . normalize ( ) ; } }
Calculate tangents for the given set of buffers, based on normals and texture coordinates.
Calculate tangents for the given set of buffers based on normals and texture coordinates .
tangents
&mut [Vec3]
positions
&[Vec3]
normals
&[Vec3]
uvs
&[Vec2]
indices
&[u32]
zeroed
bool
safety
The following must be true:
Tangents, positions, normals, and uvs must be the same length.
All indices must be in-bounds for the buffers.
The following must be true : Tangents positions normals and uvs must be the same length . All indices must be in - bounds for the buffers .