Skip to content

Commit

Permalink
Add a test for Mesh::triangles and fix for TriangleStrip (#16026)
Browse files Browse the repository at this point in the history
# Objective

- Illustrate behavior with a test
- Fix a bug revealed by a test

## Solution

- Add a test and fix

## Testing

Test added.
  • Loading branch information
stepancheg authored Oct 21, 2024
1 parent 465d113 commit d0af199
Showing 1 changed file with 106 additions and 10 deletions.
116 changes: 106 additions & 10 deletions crates/bevy_mesh/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,16 +1162,34 @@ impl Mesh {
// If there aren't enough indices to make a triangle, then an empty vector will be
// returned.
let iterator = match indices {
Indices::U16(vec) => FourIterators::Third(
vec.as_slice()
.windows(3)
.flat_map(move |indices| indices_to_triangle(vertices, indices)),
),
Indices::U32(vec) => FourIterators::Fourth(
vec.as_slice()
.windows(3)
.flat_map(move |indices| indices_to_triangle(vertices, indices)),
),
Indices::U16(vec) => {
FourIterators::Third(vec.as_slice().windows(3).enumerate().flat_map(
move |(i, indices)| {
if i % 2 == 0 {
indices_to_triangle(vertices, indices)
} else {
indices_to_triangle(
vertices,
&[indices[1], indices[0], indices[2]],
)
}
},
))
}
Indices::U32(vec) => {
FourIterators::Fourth(vec.as_slice().windows(3).enumerate().flat_map(
move |(i, indices)| {
if i % 2 == 0 {
indices_to_triangle(vertices, indices)
} else {
indices_to_triangle(
vertices,
&[indices[1], indices[0], indices[2]],
)
}
},
))
}
};

return Ok(iterator);
Expand Down Expand Up @@ -1209,6 +1227,7 @@ mod tests {
use super::Mesh;
use crate::mesh::{Indices, MeshWindingInvertError, VertexAttributeValues};
use bevy_asset::RenderAssetUsages;
use bevy_math::primitives::Triangle3d;
use bevy_math::Vec3;
use bevy_transform::components::Transform;
use wgpu::PrimitiveTopology;
Expand Down Expand Up @@ -1398,4 +1417,81 @@ mod tests {
// 3
assert_eq!([1., 0., 0.], normals[3]);
}

#[test]
fn triangles_from_triangle_list() {
let mut mesh = Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
);
mesh.insert_attribute(
Mesh::ATTRIBUTE_POSITION,
vec![[0., 0., 0.], [1., 0., 0.], [1., 1., 0.], [0., 1., 0.]],
);
mesh.insert_indices(Indices::U32(vec![0, 1, 2, 2, 3, 0]));
assert_eq!(
vec![
Triangle3d {
vertices: [
Vec3::new(0., 0., 0.),
Vec3::new(1., 0., 0.),
Vec3::new(1., 1., 0.),
]
},
Triangle3d {
vertices: [
Vec3::new(1., 1., 0.),
Vec3::new(0., 1., 0.),
Vec3::new(0., 0., 0.),
]
}
],
mesh.triangles().unwrap().collect::<Vec<Triangle3d>>()
);
}

#[test]
fn triangles_from_triangle_strip() {
let mut mesh = Mesh::new(
PrimitiveTopology::TriangleStrip,
RenderAssetUsages::default(),
);
// Triangles: (0, 1, 2), (2, 1, 3), (2, 3, 4), (4, 3, 5)
//
// 4 - 5
// | \ |
// 2 - 3
// | \ |
// 0 - 1
let positions: Vec<Vec3> = [
[0., 0., 0.],
[1., 0., 0.],
[0., 1., 0.],
[1., 1., 0.],
[0., 2., 0.],
[1., 2., 0.],
]
.into_iter()
.map(Vec3::from_array)
.collect();
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions.clone());
mesh.insert_indices(Indices::U32(vec![0, 1, 2, 3, 4, 5]));
assert_eq!(
vec![
Triangle3d {
vertices: [positions[0], positions[1], positions[2]]
},
Triangle3d {
vertices: [positions[2], positions[1], positions[3]]
},
Triangle3d {
vertices: [positions[2], positions[3], positions[4]]
},
Triangle3d {
vertices: [positions[4], positions[3], positions[5]]
},
],
mesh.triangles().unwrap().collect::<Vec<Triangle3d>>()
);
}
}

0 comments on commit d0af199

Please sign in to comment.