mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
Use <[T]>::as_chunks{_mut} for exact size chunks (#23755)
# Objective
- Reduce `unwrap`s and bounds checks.
## Solution
- Replace usages of `<[T]>::chunks{_mut}` and
`<[T]>::chunks_exact{_mut}` where the size is exact with
`<[T]>::as_chunks{_mut}`.
## Testing
- Ran `cargo run -p ci -- compile`
---------
Co-authored-by: Luo Zhihao <luo_zhihao@outlook.com>
This commit is contained in:
@@ -133,9 +133,9 @@ where
|
||||
]
|
||||
.map(|vec3| config.isometry * vec3);
|
||||
|
||||
for chunk in vertices.chunks_exact(3) {
|
||||
for &[a, b, c] in vertices.as_chunks().0 {
|
||||
self.gizmos
|
||||
.short_arc_3d_between(chunk[1], chunk[0], chunk[2], config.color)
|
||||
.short_arc_3d_between(b, a, c, config.color)
|
||||
.resolution(config.arc_resolution);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,10 +105,10 @@ pub fn dds_buffer_to_image(
|
||||
image.data = if let Some(transcode_format) = transcode_format {
|
||||
match transcode_format {
|
||||
TranscodeFormat::Rgb8 => {
|
||||
let data = dds
|
||||
.data
|
||||
.chunks_exact(3)
|
||||
.flat_map(|pixel| [pixel[0], pixel[1], pixel[2], u8::MAX])
|
||||
let (chunks, _) = dds.data.as_chunks();
|
||||
let data = chunks
|
||||
.iter()
|
||||
.flat_map(|&[r, g, b]| [r, g, b, u8::MAX])
|
||||
.collect();
|
||||
Some(data)
|
||||
}
|
||||
|
||||
@@ -112,12 +112,7 @@ impl Image {
|
||||
width as usize * height as usize * format.pixel_size().unwrap_or(0),
|
||||
);
|
||||
|
||||
for pixel in image.into_raw().chunks_exact(3) {
|
||||
// TODO: use the array_chunks method once stabilized
|
||||
// https://github.com/rust-lang/rust/issues/74985
|
||||
let r = pixel[0];
|
||||
let g = pixel[1];
|
||||
let b = pixel[2];
|
||||
for [r, g, b] in image.into_raw().as_chunks().0 {
|
||||
let a = 1f32;
|
||||
|
||||
local_data.extend_from_slice(&r.to_le_bytes());
|
||||
@@ -191,8 +186,8 @@ impl Image {
|
||||
TextureFormat::Bgra8UnormSrgb | TextureFormat::Bgra8Unorm => {
|
||||
ImageBuffer::from_raw(width, height, {
|
||||
let mut data = data;
|
||||
for bgra in data.chunks_exact_mut(4) {
|
||||
bgra.swap(0, 2);
|
||||
for [b, _, r, _] in data.as_chunks_mut().0 {
|
||||
core::mem::swap(b, r);
|
||||
}
|
||||
data
|
||||
})
|
||||
|
||||
@@ -1231,15 +1231,12 @@ impl Mesh {
|
||||
) -> Result<(), MeshWindingInvertError> {
|
||||
match topology {
|
||||
PrimitiveTopology::TriangleList => {
|
||||
// Early return if the index count doesn't match
|
||||
if !indices.len().is_multiple_of(3) {
|
||||
let (chunks, []) = indices.as_chunks_mut() else {
|
||||
// Early return if the index count doesn't match
|
||||
return Err(MeshWindingInvertError::AbruptIndicesEnd);
|
||||
}
|
||||
for chunk in indices.chunks_mut(3) {
|
||||
// This currently can only be optimized away with unsafe, rework this when `feature(slice_as_chunks)` gets stable.
|
||||
let [_, b, c] = chunk else {
|
||||
return Err(MeshWindingInvertError::AbruptIndicesEnd);
|
||||
};
|
||||
};
|
||||
|
||||
for [_, b, c] in chunks {
|
||||
core::mem::swap(b, c);
|
||||
}
|
||||
Ok(())
|
||||
@@ -1353,9 +1350,10 @@ impl Mesh {
|
||||
.expect("`Mesh::ATTRIBUTE_POSITION` vertex attributes should be of type `float3`");
|
||||
|
||||
let normals: Vec<_> = positions
|
||||
.chunks_exact(3)
|
||||
.map(|p| triangle_normal(p[0], p[1], p[2]))
|
||||
.flat_map(|normal| [normal; 3])
|
||||
.as_chunks()
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|&[a, b, c]| [triangle_normal(a, b, c); 3])
|
||||
.collect();
|
||||
|
||||
self.try_insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
|
||||
@@ -1608,11 +1606,14 @@ impl Mesh {
|
||||
|
||||
let mut normals = vec![Vec3::ZERO; positions.len()];
|
||||
|
||||
self.try_indices()?
|
||||
.iter()
|
||||
.collect::<Vec<usize>>()
|
||||
.chunks_exact(3)
|
||||
.for_each(|face| per_triangle([face[0], face[1], face[2]], positions, &mut normals));
|
||||
match self.try_indices()? {
|
||||
Indices::U16(vec) => vec.as_chunks().0.iter().for_each(|&chunk| {
|
||||
per_triangle(chunk.map(|i| i as usize), positions, &mut normals);
|
||||
}),
|
||||
Indices::U32(vec) => vec.as_chunks().0.iter().for_each(|&chunk| {
|
||||
per_triangle(chunk.map(|i| i as usize), positions, &mut normals);
|
||||
}),
|
||||
}
|
||||
|
||||
for normal in &mut normals {
|
||||
*normal = normal.try_normalize().unwrap_or(Vec3::ZERO);
|
||||
@@ -2218,14 +2219,16 @@ impl Mesh {
|
||||
// This implicitly truncates the indices to a multiple of 3.
|
||||
let iterator = match indices {
|
||||
Indices::U16(vec) => FourIterators::First(
|
||||
vec.as_slice()
|
||||
.chunks_exact(3)
|
||||
.flat_map(move |indices| indices_to_triangle(vertices, indices)),
|
||||
vec.as_chunks::<3>()
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|indices| indices_to_triangle(vertices, indices)),
|
||||
),
|
||||
Indices::U32(vec) => FourIterators::Second(
|
||||
vec.as_slice()
|
||||
.chunks_exact(3)
|
||||
.flat_map(move |indices| indices_to_triangle(vertices, indices)),
|
||||
vec.as_chunks::<3>()
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|indices| indices_to_triangle(vertices, indices)),
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
@@ -212,10 +212,14 @@ where
|
||||
match topology {
|
||||
PrimitiveTopology::TriangleList => match indices {
|
||||
Indices::U16(indices) => {
|
||||
indices.chunks_exact_mut(3).for_each(|arr| arr.swap(1, 0));
|
||||
for [a, b, _] in indices.as_chunks_mut().0 {
|
||||
core::mem::swap(a, b);
|
||||
}
|
||||
}
|
||||
Indices::U32(indices) => {
|
||||
indices.chunks_exact_mut(3).for_each(|arr| arr.swap(1, 0));
|
||||
for [a, b, _] in indices.as_chunks_mut().0 {
|
||||
core::mem::swap(a, b);
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
|
||||
@@ -104,16 +104,14 @@ where
|
||||
}
|
||||
|
||||
indices
|
||||
.chunks_exact(3)
|
||||
.as_chunks()
|
||||
.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(
|
||||
(f32::MAX, None),
|
||||
|(closest_distance, closest_hit), (tri_idx, triangle)| {
|
||||
let [Ok(a), Ok(b), Ok(c)] = [
|
||||
triangle[0].try_into(),
|
||||
triangle[1].try_into(),
|
||||
triangle[2].try_into(),
|
||||
] else {
|
||||
|(closest_distance, closest_hit), (tri_idx, &[a, b, c])| {
|
||||
let [Ok(a), Ok(b), Ok(c)] = [a.try_into(), b.try_into(), c.try_into()] else {
|
||||
return (closest_distance, closest_hit);
|
||||
};
|
||||
|
||||
@@ -136,17 +134,14 @@ where
|
||||
.1
|
||||
} else {
|
||||
positions
|
||||
.chunks_exact(3)
|
||||
.as_chunks()
|
||||
.0
|
||||
.iter()
|
||||
.map(|&[a, b, c]| [Vec3::from(a), Vec3::from(b), Vec3::from(c)])
|
||||
.enumerate()
|
||||
.fold(
|
||||
(f32::MAX, None),
|
||||
|(closest_distance, closest_hit), (tri_idx, triangle)| {
|
||||
let tri_vertices = [
|
||||
Vec3::from(triangle[0]),
|
||||
Vec3::from(triangle[1]),
|
||||
Vec3::from(triangle[2]),
|
||||
];
|
||||
|
||||
|(closest_distance, closest_hit), (tri_idx, tri_vertices)| {
|
||||
match ray_triangle_intersection(&ray, &tri_vertices, backface_culling) {
|
||||
Some(hit) if hit.distance >= 0. && hit.distance < closest_distance => {
|
||||
(hit.distance, Some((tri_idx, hit)))
|
||||
|
||||
@@ -581,15 +581,19 @@ impl FrameData {
|
||||
let data = read_buffer.slice(..).get_mapped_range();
|
||||
|
||||
let timestamps = data[..(self.num_timestamps * 8) as usize]
|
||||
.chunks(8)
|
||||
.map(|v| u64::from_le_bytes(v.try_into().unwrap()))
|
||||
.as_chunks()
|
||||
.0
|
||||
.iter()
|
||||
.map(|&v| u64::from_le_bytes(v))
|
||||
.collect::<Vec<u64>>();
|
||||
|
||||
let start = self.pipeline_statistics_buffer_offset as usize;
|
||||
let len = (self.num_pipeline_statistics as usize) * 40;
|
||||
let pipeline_statistics = data[start..start + len]
|
||||
.chunks(8)
|
||||
.map(|v| u64::from_le_bytes(v.try_into().unwrap()))
|
||||
.as_chunks()
|
||||
.0
|
||||
.iter()
|
||||
.map(|&v| u64::from_le_bytes(v))
|
||||
.collect::<Vec<u64>>();
|
||||
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
@@ -90,9 +90,10 @@ pub(crate) fn extract_rgba_pixels(image: &Image) -> Option<Vec<u8>> {
|
||||
| TextureFormat::Rgba8Uint
|
||||
| TextureFormat::Rgba8Sint => Some(image.data.clone()?),
|
||||
TextureFormat::Rgba32Float => image.data.as_ref().map(|data| {
|
||||
data.chunks(4)
|
||||
data.as_chunks()
|
||||
.0
|
||||
.iter()
|
||||
.map(|chunk| {
|
||||
let chunk = chunk.try_into().unwrap();
|
||||
let num = bytemuck::cast_ref::<[u8; 4], f32>(chunk);
|
||||
ops::round(num.clamp(0.0, 1.0) * 255.0) as u8
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user