diff --git a/crates/bevy_math/Cargo.toml b/crates/bevy_math/Cargo.toml index 783370fd59b14..3bdd7d8a8d67f 100644 --- a/crates/bevy_math/Cargo.toml +++ b/crates/bevy_math/Cargo.toml @@ -74,6 +74,7 @@ mint = ["glam/mint"] libm = ["dep:libm", "glam/libm"] # Enable assertions to check the validity of parameters passed to glam glam_assert = ["glam/glam-assert"] +glam_bytemuck = ["glam/bytemuck"] # Enable assertions in debug builds to check the validity of parameters passed to glam debug_glam_assert = ["glam/debug-glam-assert"] # Enable the rand dependency for shape_sampling diff --git a/crates/bevy_mesh/Cargo.toml b/crates/bevy_mesh/Cargo.toml index eaa0dc2c574f0..2c7718fe0c9ed 100644 --- a/crates/bevy_mesh/Cargo.toml +++ b/crates/bevy_mesh/Cargo.toml @@ -13,7 +13,9 @@ keywords = ["bevy"] bevy_app = { path = "../bevy_app", version = "0.18.0-dev" } bevy_asset = { path = "../bevy_asset", version = "0.18.0-dev" } bevy_image = { path = "../bevy_image", version = "0.18.0-dev", optional = true } -bevy_math = { path = "../bevy_math", version = "0.18.0-dev" } +bevy_math = { path = "../bevy_math", version = "0.18.0-dev", features = [ + "glam_bytemuck", +] } bevy_reflect = { path = "../bevy_reflect", version = "0.18.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.18.0-dev" } bevy_transform = { path = "../bevy_transform", version = "0.18.0-dev" } diff --git a/crates/bevy_mesh/src/index.rs b/crates/bevy_mesh/src/index.rs index 87d81cc3f2fa2..09be833c72f7c 100644 --- a/crates/bevy_mesh/src/index.rs +++ b/crates/bevy_mesh/src/index.rs @@ -80,6 +80,15 @@ pub enum Indices { } impl Indices { + /// Create a empty indices with the given capacity and vertex count. It will be [`Indices::U16`] if the vertex count <= 65536, otherwise it will be [`Indices::U32`]. + pub fn with_capacity(capacity: usize, vertex_count: u32) -> Self { + if vertex_count <= u16::MAX as u32 + 1 { + Indices::U16(Vec::with_capacity(capacity)) + } else { + Indices::U32(Vec::with_capacity(capacity)) + } + } + /// Returns an iterator over the indices. pub fn iter(&self) -> impl Iterator + '_ { match self { @@ -109,6 +118,30 @@ impl Indices { pub fn push(&mut self, index: u32) { self.extend([index]); } + + /// Resize the indices in place so that `len` is equal to `new_len`. + pub fn resize(&mut self, new_len: usize, value: u32) { + match self { + Indices::U16(indices) => { + indices.resize(new_len, value as u16); + } + Indices::U32(indices) => { + indices.resize(new_len, value); + } + } + } + + /// Set a value of indices at the given index. + pub fn set(&mut self, index: usize, value: u32) { + match self { + Indices::U16(indices) => { + indices[index] = value as u16; + } + Indices::U32(indices) => { + indices[index] = value; + } + } + } } /// Extend the indices with indices from an iterator. diff --git a/crates/bevy_mesh/src/primitives/dim2.rs b/crates/bevy_mesh/src/primitives/dim2.rs index f2a5862c6f390..8c32da2e253f6 100644 --- a/crates/bevy_mesh/src/primitives/dim2.rs +++ b/crates/bevy_mesh/src/primitives/dim2.rs @@ -177,7 +177,7 @@ impl CircularSectorMeshBuilder { impl MeshBuilder for CircularSectorMeshBuilder { fn build(&self) -> Mesh { let resolution = self.resolution as usize; - let mut indices = Vec::with_capacity((resolution - 1) * 3); + let mut indices = Indices::with_capacity((resolution - 1) * 3, (resolution + 1) as u32); let mut positions = Vec::with_capacity(resolution + 1); let normals = vec![[0.0, 0.0, 1.0]; resolution + 1]; let mut uvs = Vec::with_capacity(resolution + 1); @@ -207,7 +207,7 @@ impl MeshBuilder for CircularSectorMeshBuilder { for i in 1..self.resolution { // Index 0 is the center. - indices.extend_from_slice(&[0, i, i + 1]); + indices.extend([0, i, i + 1]); } Mesh::new( @@ -217,7 +217,7 @@ impl MeshBuilder for CircularSectorMeshBuilder { .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) } } @@ -315,7 +315,7 @@ impl CircularSegmentMeshBuilder { impl MeshBuilder for CircularSegmentMeshBuilder { fn build(&self) -> Mesh { let resolution = self.resolution as usize; - let mut indices = Vec::with_capacity((resolution - 1) * 3); + let mut indices = Indices::with_capacity((resolution - 1) * 3, (resolution + 1) as u32); let mut positions = Vec::with_capacity(resolution + 1); let normals = vec![[0.0, 0.0, 1.0]; resolution + 1]; let mut uvs = Vec::with_capacity(resolution + 1); @@ -354,7 +354,7 @@ impl MeshBuilder for CircularSegmentMeshBuilder { for i in 1..self.resolution { // Index 0 is the midpoint of the chord. - indices.extend_from_slice(&[0, i, i + 1]); + indices.extend([0, i, i + 1]); } Mesh::new( @@ -364,7 +364,7 @@ impl MeshBuilder for CircularSegmentMeshBuilder { .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) } } @@ -429,21 +429,21 @@ impl Meshable for ConvexPolygon { impl MeshBuilder for ConvexPolygonMeshBuilder { fn build(&self) -> Mesh { let len = self.vertices.len(); - let mut indices = Vec::with_capacity((len - 2) * 3); + let mut indices = Indices::with_capacity((len - 2) * 3, len as u32); let mut positions = Vec::with_capacity(len); for vertex in &self.vertices { positions.push([vertex.x, vertex.y, 0.0]); } for i in 2..len as u32 { - indices.extend_from_slice(&[0, i - 1, i]); + indices.extend([0, i - 1, i]); } Mesh::new( PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) } } @@ -578,7 +578,7 @@ impl EllipseMeshBuilder { impl MeshBuilder for EllipseMeshBuilder { fn build(&self) -> Mesh { let resolution = self.resolution as usize; - let mut indices = Vec::with_capacity((resolution - 2) * 3); + let mut indices = Indices::with_capacity((resolution - 2) * 3, resolution as u32); let mut positions = Vec::with_capacity(resolution); let normals = vec![[0.0, 0.0, 1.0]; resolution]; let mut uvs = Vec::with_capacity(resolution); @@ -599,7 +599,7 @@ impl MeshBuilder for EllipseMeshBuilder { } for i in 1..(self.resolution - 1) { - indices.extend_from_slice(&[0, i, i + 1]); + indices.extend([0, i, i + 1]); } Mesh::new( @@ -609,7 +609,7 @@ impl MeshBuilder for EllipseMeshBuilder { .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) } } @@ -657,7 +657,7 @@ impl Segment2dMeshBuilder { impl MeshBuilder for Segment2dMeshBuilder { fn build(&self) -> Mesh { let positions = self.segment.vertices.map(|v| v.extend(0.0)).to_vec(); - let indices = Indices::U32(vec![0, 1]); + let indices = Indices::U16(vec![0, 1]); Mesh::new(PrimitiveTopology::LineList, RenderAssetUsages::default()) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) @@ -696,11 +696,9 @@ impl MeshBuilder for Polyline2dMeshBuilder { .map(|v| v.extend(0.0)) .collect(); - let indices = Indices::U32( - (0..self.polyline.vertices.len() as u32 - 1) - .flat_map(|i| [i, i + 1]) - .collect(), - ); + let mut indices = + Indices::with_capacity(self.polyline.vertices.len() - 1, positions.len() as u32); + indices.extend((0..self.polyline.vertices.len() as u32 - 1).flat_map(|i| [i, i + 1])); Mesh::new(PrimitiveTopology::LineList, RenderAssetUsages::default()) .with_inserted_indices(indices) @@ -769,7 +767,7 @@ impl MeshBuilder for AnnulusMeshBuilder { let outer_radius = self.annulus.outer_circle.radius; let num_vertices = (self.resolution as usize + 1) * 2; - let mut indices = Vec::with_capacity(self.resolution as usize * 6); + let mut indices = Indices::with_capacity(self.resolution as usize * 6, num_vertices as u32); let mut positions = Vec::with_capacity(num_vertices); let mut uvs = Vec::with_capacity(num_vertices); let normals = vec![[0.0, 0.0, 1.0]; num_vertices]; @@ -807,8 +805,8 @@ impl MeshBuilder for AnnulusMeshBuilder { let outer_vertex = 2 * i + 1; let next_inner = inner_vertex + 2; let next_outer = outer_vertex + 2; - indices.extend_from_slice(&[inner_vertex, outer_vertex, next_outer]); - indices.extend_from_slice(&[next_outer, next_inner, inner_vertex]); + indices.extend([inner_vertex, outer_vertex, next_outer]); + indices.extend([next_outer, next_inner, inner_vertex]); } Mesh::new( @@ -818,7 +816,7 @@ impl MeshBuilder for AnnulusMeshBuilder { .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) } } @@ -906,7 +904,7 @@ impl MeshBuilder for RhombusMeshBuilder { ]; let normals = vec![[0.0, 0.0, 1.0]; 4]; let uvs = vec![[1.0, 0.5], [0.5, 0.0], [0.0, 0.5], [0.5, 1.0]]; - let indices = Indices::U32(vec![0, 1, 2, 2, 3, 0]); + let indices = Indices::U16(vec![0, 1, 2, 2, 3, 0]); Mesh::new( PrimitiveTopology::TriangleList, @@ -983,9 +981,9 @@ impl MeshBuilder for Triangle2dMeshBuilder { let is_ccw = self.triangle.winding_order() == WindingOrder::CounterClockwise; let indices = if is_ccw { - Indices::U32(vec![0, 1, 2]) + Indices::U16(vec![0, 1, 2]) } else { - Indices::U32(vec![2, 1, 0]) + Indices::U16(vec![2, 1, 0]) }; Mesh::new( @@ -1063,7 +1061,7 @@ impl MeshBuilder for RectangleMeshBuilder { ]; let normals = vec![[0.0, 0.0, 1.0]; 4]; let uvs = vec![[1.0, 0.0], [0.0, 0.0], [0.0, 1.0], [1.0, 1.0]]; - let indices = Indices::U32(vec![0, 1, 2, 0, 2, 3]); + let indices = Indices::U16(vec![0, 1, 2, 0, 2, 3]); Mesh::new( PrimitiveTopology::TriangleList, @@ -1149,7 +1147,8 @@ impl MeshBuilder for Capsule2dMeshBuilder { let vertex_count = 2 * resolution; // Six extra indices for the two triangles between the semicircles - let mut indices = Vec::with_capacity((resolution as usize - 2) * 2 * 3 + 6); + let mut indices = + Indices::with_capacity((resolution as usize - 2) * 2 * 3 + 6, vertex_count); let mut positions = Vec::with_capacity(vertex_count as usize); let normals = vec![[0.0, 0.0, 1.0]; vertex_count as usize]; let mut uvs = Vec::with_capacity(vertex_count as usize); @@ -1182,11 +1181,11 @@ impl MeshBuilder for Capsule2dMeshBuilder { // Add top semicircle indices for i in 1..resolution - 1 { - indices.extend_from_slice(&[0, i, i + 1]); + indices.extend([0, i, i + 1]); } // Add indices for top left triangle of the part between the semicircles - indices.extend_from_slice(&[0, resolution - 1, resolution]); + indices.extend([0, resolution - 1, resolution]); // Create bottom semicircle for i in resolution..vertex_count { @@ -1201,11 +1200,11 @@ impl MeshBuilder for Capsule2dMeshBuilder { // Add bottom semicircle indices for i in 1..resolution - 1 { - indices.extend_from_slice(&[resolution, resolution + i, resolution + i + 1]); + indices.extend([resolution, resolution + i, resolution + i + 1]); } // Add indices for bottom right triangle of the part between the semicircles - indices.extend_from_slice(&[resolution, vertex_count - 1, 0]); + indices.extend([resolution, vertex_count - 1, 0]); Mesh::new( PrimitiveTopology::TriangleList, @@ -1214,7 +1213,7 @@ impl MeshBuilder for Capsule2dMeshBuilder { .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) } } diff --git a/crates/bevy_mesh/src/primitives/dim3/capsule.rs b/crates/bevy_mesh/src/primitives/dim3/capsule.rs index f46ebce0d15a7..81ed8101678aa 100644 --- a/crates/bevy_mesh/src/primitives/dim3/capsule.rs +++ b/crates/bevy_mesh/src/primitives/dim3/capsule.rs @@ -295,7 +295,8 @@ impl MeshBuilder for Capsule3dMeshBuilder { let tri_offset_south_cap = tri_offset_south_hemi + hemi_lons; let fs_len = tri_offset_south_cap + lons3; - let mut tris: Vec = vec![0; fs_len as usize]; + let mut tris = Indices::with_capacity(fs_len as usize, vert_len as u32); + tris.resize(fs_len as usize, 0); // Polar caps. let mut i = 0; @@ -303,14 +304,14 @@ impl MeshBuilder for Capsule3dMeshBuilder { let mut m = tri_offset_south_cap as usize; while i < longitudes { // North. - tris[k] = i; - tris[k + 1] = vert_offset_north_hemi + i; - tris[k + 2] = vert_offset_north_hemi + i + 1; + tris.set(k, i); + tris.set(k + 1, vert_offset_north_hemi + i); + tris.set(k + 2, vert_offset_north_hemi + i + 1); // South. - tris[m] = vert_offset_south_cap + i; - tris[m + 1] = vert_offset_south_polar + i + 1; - tris[m + 2] = vert_offset_south_polar + i; + tris.set(m, vert_offset_south_cap + i); + tris.set(m + 1, vert_offset_south_polar + i + 1); + tris.set(m + 2, vert_offset_south_polar + i); i += 1; k += 3; @@ -340,13 +341,13 @@ impl MeshBuilder for Capsule3dMeshBuilder { let north11 = vert_next_lat_north + j + 1; let north10 = vert_curr_lat_north + j + 1; - tris[k] = north00; - tris[k + 1] = north11; - tris[k + 2] = north10; + tris.set(k, north00); + tris.set(k + 1, north11); + tris.set(k + 2, north10); - tris[k + 3] = north00; - tris[k + 4] = north01; - tris[k + 5] = north11; + tris.set(k + 3, north00); + tris.set(k + 4, north01); + tris.set(k + 5, north11); // South. let south00 = vert_curr_lat_south + j; @@ -354,13 +355,13 @@ impl MeshBuilder for Capsule3dMeshBuilder { let south11 = vert_next_lat_south + j + 1; let south10 = vert_curr_lat_south + j + 1; - tris[m] = south00; - tris[m + 1] = south11; - tris[m + 2] = south10; + tris.set(m, south00); + tris.set(m + 1, south11); + tris.set(m + 2, south10); - tris[m + 3] = south00; - tris[m + 4] = south01; - tris[m + 5] = south11; + tris.set(m + 3, south00); + tris.set(m + 4, south01); + tris.set(m + 5, south11); j += 1; k += 6; @@ -385,13 +386,13 @@ impl MeshBuilder for Capsule3dMeshBuilder { let cy11 = vert_next_lat + j + 1; let cy10 = vert_curr_lat + j + 1; - tris[k] = cy00; - tris[k + 1] = cy11; - tris[k + 2] = cy10; + tris.set(k, cy00); + tris.set(k + 1, cy11); + tris.set(k + 2, cy10); - tris[k + 3] = cy00; - tris[k + 4] = cy01; - tris[k + 5] = cy11; + tris.set(k + 3, cy00); + tris.set(k + 4, cy01); + tris.set(k + 5, cy11); j += 1; k += 6; @@ -400,12 +401,9 @@ impl MeshBuilder for Capsule3dMeshBuilder { i += 1; } - let vs: Vec<[f32; 3]> = vs.into_iter().map(Into::into).collect(); - let vns: Vec<[f32; 3]> = vns.into_iter().map(Into::into).collect(); - let vts: Vec<[f32; 2]> = vts.into_iter().map(Into::into).collect(); - - assert_eq!(vs.len(), vert_len); - assert_eq!(tris.len(), fs_len as usize); + let vs: Vec<[f32; 3]> = bytemuck::cast_vec(vs); + let vns: Vec<[f32; 3]> = bytemuck::cast_vec(vns); + let vts: Vec<[f32; 2]> = bytemuck::cast_vec(vts); Mesh::new( PrimitiveTopology::TriangleList, @@ -414,7 +412,7 @@ impl MeshBuilder for Capsule3dMeshBuilder { .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vs) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vns) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, vts) - .with_inserted_indices(Indices::U32(tris)) + .with_inserted_indices(tris) } } diff --git a/crates/bevy_mesh/src/primitives/dim3/cone.rs b/crates/bevy_mesh/src/primitives/dim3/cone.rs index d06a57f832ea5..045b18e8905ea 100644 --- a/crates/bevy_mesh/src/primitives/dim3/cone.rs +++ b/crates/bevy_mesh/src/primitives/dim3/cone.rs @@ -80,7 +80,7 @@ impl MeshBuilder for ConeMeshBuilder { let mut positions = Vec::with_capacity(num_vertices); let mut normals = Vec::with_capacity(num_vertices); let mut uvs = Vec::with_capacity(num_vertices); - let mut indices = Vec::with_capacity(num_indices); + let mut indices = Indices::with_capacity(num_indices, num_vertices as u32); // Tip positions.push([0.0, half_height, 0.0]); @@ -128,11 +128,11 @@ impl MeshBuilder for ConeMeshBuilder { // Add indices for the lateral surface. Each triangle is formed by the tip // and two vertices at the base. for j in 1..self.resolution { - indices.extend_from_slice(&[0, j + 1, j]); + indices.extend([0, j + 1, j]); } // Close the surface with a triangle between the tip, first base vertex, and last base vertex. - indices.extend_from_slice(&[0, 1, self.resolution]); + indices.extend([0, 1, self.resolution]); // Now we build the actual base of the cone. @@ -150,7 +150,7 @@ impl MeshBuilder for ConeMeshBuilder { // Add base indices. for i in 1..(self.resolution - 1) { - indices.extend_from_slice(&[index_offset, index_offset + i, index_offset + i + 1]); + indices.extend([index_offset, index_offset + i, index_offset + i + 1]); } // Offset the vertex positions Y axis to match the anchor @@ -164,7 +164,7 @@ impl MeshBuilder for ConeMeshBuilder { PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) diff --git a/crates/bevy_mesh/src/primitives/dim3/conical_frustum.rs b/crates/bevy_mesh/src/primitives/dim3/conical_frustum.rs index 8c69378c01e64..70cb4f5e9b471 100644 --- a/crates/bevy_mesh/src/primitives/dim3/conical_frustum.rs +++ b/crates/bevy_mesh/src/primitives/dim3/conical_frustum.rs @@ -80,7 +80,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { let mut positions = Vec::with_capacity(num_vertices); let mut normals = Vec::with_capacity(num_vertices); let mut uvs = Vec::with_capacity(num_vertices); - let mut indices = Vec::with_capacity(num_indices); + let mut indices = Indices::with_capacity(num_indices, num_vertices as u32); let step_theta = core::f32::consts::TAU / self.resolution as f32; let step_y = height / self.segments as f32; @@ -114,7 +114,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { let next_ring = (i + 1) * (self.resolution + 1); for j in 0..self.resolution { - indices.extend_from_slice(&[ + indices.extend([ ring + j, next_ring + j, ring + j + 1, @@ -144,11 +144,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { } for i in 1..(self.resolution - 1) { - indices.extend_from_slice(&[ - offset, - offset + i + winding.0, - offset + i + winding.1, - ]); + indices.extend([offset, offset + i + winding.0, offset + i + winding.1]); } }; @@ -159,7 +155,7 @@ impl MeshBuilder for ConicalFrustumMeshBuilder { PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) diff --git a/crates/bevy_mesh/src/primitives/dim3/cuboid.rs b/crates/bevy_mesh/src/primitives/dim3/cuboid.rs index 40a7cd45d4433..298b40f4855f0 100644 --- a/crates/bevy_mesh/src/primitives/dim3/cuboid.rs +++ b/crates/bevy_mesh/src/primitives/dim3/cuboid.rs @@ -62,7 +62,7 @@ impl MeshBuilder for CuboidMeshBuilder { let normals: Vec<_> = vertices.iter().map(|(_, n, _)| *n).collect(); let uvs: Vec<_> = vertices.iter().map(|(_, _, uv)| *uv).collect(); - let indices = Indices::U32(vec![ + let indices = Indices::U16(vec![ 0, 1, 2, 2, 3, 0, // front 4, 5, 6, 6, 7, 4, // back 8, 9, 10, 10, 11, 8, // right diff --git a/crates/bevy_mesh/src/primitives/dim3/cylinder.rs b/crates/bevy_mesh/src/primitives/dim3/cylinder.rs index 7b1b45974ea62..85926e7de13ab 100644 --- a/crates/bevy_mesh/src/primitives/dim3/cylinder.rs +++ b/crates/bevy_mesh/src/primitives/dim3/cylinder.rs @@ -109,7 +109,7 @@ impl MeshBuilder for CylinderMeshBuilder { let mut positions = Vec::with_capacity(num_vertices as usize); let mut normals = Vec::with_capacity(num_vertices as usize); let mut uvs = Vec::with_capacity(num_vertices as usize); - let mut indices = Vec::with_capacity(num_indices as usize); + let mut indices = Indices::with_capacity(num_indices as usize, num_vertices); let step_theta = core::f32::consts::TAU / resolution as f32; let step_y = 2.0 * self.cylinder.half_height / segments as f32; @@ -139,7 +139,7 @@ impl MeshBuilder for CylinderMeshBuilder { let next_ring = (i + 1) * (resolution + 1); for j in 0..resolution { - indices.extend_from_slice(&[ + indices.extend([ ring + j, next_ring + j, ring + j + 1, @@ -170,11 +170,7 @@ impl MeshBuilder for CylinderMeshBuilder { } for i in 1..(self.resolution - 1) { - indices.extend_from_slice(&[ - offset, - offset + i + winding.0, - offset + i + winding.1, - ]); + indices.extend([offset, offset + i + winding.0, offset + i + winding.1]); } }; @@ -197,7 +193,7 @@ impl MeshBuilder for CylinderMeshBuilder { PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) diff --git a/crates/bevy_mesh/src/primitives/dim3/plane.rs b/crates/bevy_mesh/src/primitives/dim3/plane.rs index fd892469be6af..65f23a82c7e48 100644 --- a/crates/bevy_mesh/src/primitives/dim3/plane.rs +++ b/crates/bevy_mesh/src/primitives/dim3/plane.rs @@ -103,7 +103,7 @@ impl MeshBuilder for PlaneMeshBuilder { let mut positions: Vec = Vec::with_capacity(num_vertices); let mut normals: Vec<[f32; 3]> = Vec::with_capacity(num_vertices); let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(num_vertices); - let mut indices: Vec = Vec::with_capacity(num_indices); + let mut indices = Indices::with_capacity(num_indices, num_vertices as u32); let rotation = Quat::from_rotation_arc(Vec3::Y, *self.plane.normal); let size = self.plane.half_size * 2.0; @@ -135,7 +135,7 @@ impl MeshBuilder for PlaneMeshBuilder { PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) diff --git a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs index 4d13112579f09..c86c810745f95 100644 --- a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs +++ b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs @@ -14,11 +14,9 @@ impl MeshBuilder for Polyline3dMeshBuilder { fn build(&self) -> Mesh { let positions: Vec<_> = self.polyline.vertices.clone(); - let indices = Indices::U32( - (0..self.polyline.vertices.len() as u32 - 1) - .flat_map(|i| [i, i + 1]) - .collect(), - ); + let mut indices = + Indices::with_capacity(self.polyline.vertices.len() - 1, positions.len() as u32); + indices.extend((0..self.polyline.vertices.len() as u32 - 1).flat_map(|i| [i, i + 1])); Mesh::new(PrimitiveTopology::LineList, RenderAssetUsages::default()) .with_inserted_indices(indices) diff --git a/crates/bevy_mesh/src/primitives/dim3/segment3d.rs b/crates/bevy_mesh/src/primitives/dim3/segment3d.rs index d032285283afb..3c6683a3eb9a4 100644 --- a/crates/bevy_mesh/src/primitives/dim3/segment3d.rs +++ b/crates/bevy_mesh/src/primitives/dim3/segment3d.rs @@ -13,7 +13,7 @@ pub struct Segment3dMeshBuilder { impl MeshBuilder for Segment3dMeshBuilder { fn build(&self) -> Mesh { let positions: Vec<_> = self.segment.vertices.into(); - let indices = Indices::U32(vec![0, 1]); + let indices = Indices::U16(vec![0, 1]); Mesh::new(PrimitiveTopology::LineList, RenderAssetUsages::default()) .with_inserted_indices(indices) diff --git a/crates/bevy_mesh/src/primitives/dim3/tetrahedron.rs b/crates/bevy_mesh/src/primitives/dim3/tetrahedron.rs index 529805d9a603f..588ee60655696 100644 --- a/crates/bevy_mesh/src/primitives/dim3/tetrahedron.rs +++ b/crates/bevy_mesh/src/primitives/dim3/tetrahedron.rs @@ -38,7 +38,7 @@ impl MeshBuilder for TetrahedronMeshBuilder { } // There are four faces and none of them share vertices. - let indices = Indices::U32(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); + let indices = Indices::U16(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]); Mesh::new( PrimitiveTopology::TriangleList, diff --git a/crates/bevy_mesh/src/primitives/dim3/torus.rs b/crates/bevy_mesh/src/primitives/dim3/torus.rs index 6f370c13418ca..b902356dcc416 100644 --- a/crates/bevy_mesh/src/primitives/dim3/torus.rs +++ b/crates/bevy_mesh/src/primitives/dim3/torus.rs @@ -126,7 +126,7 @@ impl MeshBuilder for TorusMeshBuilder { let n_triangles = n_faces * 2; let n_indices = n_triangles * 3; - let mut indices: Vec = Vec::with_capacity(n_indices); + let mut indices = Indices::with_capacity(n_indices, n_vertices as u32); let n_vertices_per_row = self.minor_resolution + 1; for segment in 0..self.major_resolution { @@ -151,7 +151,7 @@ impl MeshBuilder for TorusMeshBuilder { PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) diff --git a/crates/bevy_mesh/src/primitives/dim3/triangle3d.rs b/crates/bevy_mesh/src/primitives/dim3/triangle3d.rs index e35f272ab9bb1..2a0cb20d6be9a 100644 --- a/crates/bevy_mesh/src/primitives/dim3/triangle3d.rs +++ b/crates/bevy_mesh/src/primitives/dim3/triangle3d.rs @@ -19,7 +19,7 @@ impl MeshBuilder for Triangle3dMeshBuilder { let normal: Vec3 = normal_vec(&self.triangle); let normals = vec![normal; 3]; - let indices = Indices::U32(vec![0, 1, 2]); + let indices = Indices::U16(vec![0, 1, 2]); Mesh::new( PrimitiveTopology::TriangleList, diff --git a/crates/bevy_mesh/src/primitives/extrusion.rs b/crates/bevy_mesh/src/primitives/extrusion.rs index 091735dc8349c..8855261921b6e 100644 --- a/crates/bevy_mesh/src/primitives/extrusion.rs +++ b/crates/bevy_mesh/src/primitives/extrusion.rs @@ -256,7 +256,7 @@ where }); let mut positions = Vec::with_capacity(vert_count); let mut normals = Vec::with_capacity(vert_count); - let mut indices = Vec::with_capacity(index_count); + let mut indices = Indices::with_capacity(index_count, vert_count as u32); let mut uvs = Vec::with_capacity(vert_count); // Compute the amount of horizontal space allocated to each segment of the perimeter. @@ -301,7 +301,7 @@ where // Add the indices for the vertices created above to the mesh. for i in 0..self.segments as u32 { let base_index = index + 2 * i; - indices.extend_from_slice(&[ + indices.extend([ base_index, base_index + 2, base_index + 1, @@ -399,7 +399,7 @@ where for s in 0..segments { for column in 0..(columns - 1) { let index = base_index + s + column * layers; - indices.extend_from_slice(&[ + indices.extend([ index, index + 1, index + layers, @@ -414,7 +414,7 @@ where } Mesh::new(PrimitiveTopology::TriangleList, front_face.asset_usage) - .with_inserted_indices(Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs) diff --git a/examples/math/custom_primitives.rs b/examples/math/custom_primitives.rs index a7e5777dfd21c..bc5987c0d3c15 100644 --- a/examples/math/custom_primitives.rs +++ b/examples/math/custom_primitives.rs @@ -17,7 +17,7 @@ use bevy::{ }, Isometry2d, }, - mesh::{Extrudable, ExtrusionBuilder, PerimeterSegment}, + mesh::{Extrudable, ExtrusionBuilder, Indices, PerimeterSegment}, prelude::*, }; @@ -517,7 +517,8 @@ impl MeshBuilder for HeartMeshBuilder { // We create buffers for the vertices, their normals and UVs, as well as the indices used to connect the vertices. let mut vertices = Vec::with_capacity(2 * self.resolution); let mut uvs = Vec::with_capacity(2 * self.resolution); - let mut indices = Vec::with_capacity(6 * self.resolution - 9); + let mut indices = + Indices::with_capacity(6 * self.resolution - 9, 2 * self.resolution as u32); // Since the heart is flat, we know all the normals are identical already. let normals = vec![[0f32, 0f32, 1f32]; 2 * self.resolution]; @@ -548,7 +549,7 @@ impl MeshBuilder for HeartMeshBuilder { // This is where we build all the triangles from the points created above. // Each triangle has one corner on the middle point with the other two being adjacent points on the perimeter of the heart. for i in 2..2 * self.resolution as u32 { - indices.extend_from_slice(&[i - 1, i, 0]); + indices.extend([i - 1, i, 0]); } // Here, the actual `Mesh` is created. We set the indices, vertices, normals and UVs created above and specify the topology of the mesh. @@ -556,7 +557,7 @@ impl MeshBuilder for HeartMeshBuilder { bevy::mesh::PrimitiveTopology::TriangleList, RenderAssetUsages::default(), ) - .with_inserted_indices(bevy::mesh::Indices::U32(indices)) + .with_inserted_indices(indices) .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices) .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals) .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)