From 353248aacf1b3bdb5067ca8e70bdc65412d4e877 Mon Sep 17 00:00:00 2001 From: Luo Zhihao Date: Mon, 24 Nov 2025 09:26:11 +0800 Subject: [PATCH 1/4] Use u16 indices if possible in mesh primitives --- crates/bevy_math/Cargo.toml | 1 + crates/bevy_mesh/Cargo.toml | 2 +- crates/bevy_mesh/src/index.rs | 9 +++ crates/bevy_mesh/src/primitives/dim2.rs | 61 +++++++++---------- .../bevy_mesh/src/primitives/dim3/capsule.rs | 9 +-- crates/bevy_mesh/src/primitives/dim3/cone.rs | 10 +-- .../src/primitives/dim3/conical_frustum.rs | 12 ++-- .../bevy_mesh/src/primitives/dim3/cuboid.rs | 2 +- .../bevy_mesh/src/primitives/dim3/cylinder.rs | 12 ++-- crates/bevy_mesh/src/primitives/dim3/plane.rs | 4 +- .../src/primitives/dim3/polyline3d.rs | 7 +-- .../src/primitives/dim3/segment3d.rs | 2 +- .../src/primitives/dim3/tetrahedron.rs | 2 +- crates/bevy_mesh/src/primitives/dim3/torus.rs | 4 +- .../src/primitives/dim3/triangle3d.rs | 2 +- crates/bevy_mesh/src/primitives/extrusion.rs | 8 +-- examples/math/custom_primitives.rs | 8 +-- 17 files changed, 74 insertions(+), 81 deletions(-) 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..5dbf5c4dd9048 100644 --- a/crates/bevy_mesh/Cargo.toml +++ b/crates/bevy_mesh/Cargo.toml @@ -13,7 +13,7 @@ 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..5db90926059c0 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 <= [`u16::MAX`], otherwise it will be [`Indices::U32`]. + pub fn new(capacity: usize, vertex_count: u32) -> Self { + if vertex_count <= u16::MAX as u32 { + 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 { diff --git a/crates/bevy_mesh/src/primitives/dim2.rs b/crates/bevy_mesh/src/primitives/dim2.rs index f2a5862c6f390..a2f391348c95f 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::new((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::new((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::new((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::new((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,8 @@ 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::new(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 +766,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::new(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 +804,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 +815,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 +903,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 +980,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 +1060,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 +1146,7 @@ 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::new((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 +1179,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 +1198,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 +1211,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..b04330719de69 100644 --- a/crates/bevy_mesh/src/primitives/dim3/capsule.rs +++ b/crates/bevy_mesh/src/primitives/dim3/capsule.rs @@ -400,12 +400,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, diff --git a/crates/bevy_mesh/src/primitives/dim3/cone.rs b/crates/bevy_mesh/src/primitives/dim3/cone.rs index d06a57f832ea5..6e5c8d2706154 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::new(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..bb1a360c88ff3 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::new(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..b5a8588d37d91 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::new(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..fca920e08cfd4 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::new(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..c08218a90b45b 100644 --- a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs +++ b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs @@ -14,11 +14,8 @@ 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::new(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..e963b7d319ce5 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::new(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..b4970db943f18 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::new(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..498cf5b4711a1 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,7 @@ 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::new(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 +548,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 +556,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) From bf1046bf56501e2428f6fa3fe34210dfa000a385 Mon Sep 17 00:00:00 2001 From: Luo Zhihao Date: Mon, 24 Nov 2025 11:35:12 +0800 Subject: [PATCH 2/4] update --- crates/bevy_mesh/Cargo.toml | 4 +- crates/bevy_mesh/src/index.rs | 24 +++++++++ .../bevy_mesh/src/primitives/dim3/capsule.rs | 53 ++++++++++--------- examples/math/custom_primitives.rs | 2 +- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/crates/bevy_mesh/Cargo.toml b/crates/bevy_mesh/Cargo.toml index 5dbf5c4dd9048..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", features = ["glam_bytemuck"] } +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 5db90926059c0..2955f06dafd17 100644 --- a/crates/bevy_mesh/src/index.rs +++ b/crates/bevy_mesh/src/index.rs @@ -118,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/dim3/capsule.rs b/crates/bevy_mesh/src/primitives/dim3/capsule.rs index b04330719de69..7ede6ba1fe49c 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::new(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; @@ -411,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/examples/math/custom_primitives.rs b/examples/math/custom_primitives.rs index 498cf5b4711a1..7295cc6b78785 100644 --- a/examples/math/custom_primitives.rs +++ b/examples/math/custom_primitives.rs @@ -548,7 +548,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(&[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. From 6464c23fb276e3a526e25439c35418185232f0d1 Mon Sep 17 00:00:00 2001 From: Luo Zhihao Date: Mon, 24 Nov 2025 20:53:47 +0800 Subject: [PATCH 3/4] Rename Indices::new to Indices::with_capacity vertex count <= 65535 + 1 --- crates/bevy_mesh/src/index.rs | 6 +++--- crates/bevy_mesh/src/primitives/dim2.rs | 16 +++++++++------- crates/bevy_mesh/src/primitives/dim3/capsule.rs | 2 +- crates/bevy_mesh/src/primitives/dim3/cone.rs | 2 +- .../src/primitives/dim3/conical_frustum.rs | 2 +- crates/bevy_mesh/src/primitives/dim3/cylinder.rs | 2 +- crates/bevy_mesh/src/primitives/dim3/plane.rs | 2 +- .../bevy_mesh/src/primitives/dim3/polyline3d.rs | 2 +- crates/bevy_mesh/src/primitives/dim3/torus.rs | 2 +- crates/bevy_mesh/src/primitives/extrusion.rs | 2 +- examples/math/custom_primitives.rs | 2 +- 11 files changed, 21 insertions(+), 19 deletions(-) diff --git a/crates/bevy_mesh/src/index.rs b/crates/bevy_mesh/src/index.rs index 2955f06dafd17..09be833c72f7c 100644 --- a/crates/bevy_mesh/src/index.rs +++ b/crates/bevy_mesh/src/index.rs @@ -80,9 +80,9 @@ 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 <= [`u16::MAX`], otherwise it will be [`Indices::U32`]. - pub fn new(capacity: usize, vertex_count: u32) -> Self { - if vertex_count <= u16::MAX as u32 { + /// 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)) diff --git a/crates/bevy_mesh/src/primitives/dim2.rs b/crates/bevy_mesh/src/primitives/dim2.rs index a2f391348c95f..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 = Indices::new((resolution - 1) * 3, (resolution + 1) as u32); + 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); @@ -315,7 +315,7 @@ impl CircularSegmentMeshBuilder { impl MeshBuilder for CircularSegmentMeshBuilder { fn build(&self) -> Mesh { let resolution = self.resolution as usize; - let mut indices = Indices::new((resolution - 1) * 3, (resolution + 1) as u32); + 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); @@ -429,7 +429,7 @@ impl Meshable for ConvexPolygon { impl MeshBuilder for ConvexPolygonMeshBuilder { fn build(&self) -> Mesh { let len = self.vertices.len(); - let mut indices = Indices::new((len - 2) * 3, len as u32); + let mut indices = Indices::with_capacity((len - 2) * 3, len as u32); let mut positions = Vec::with_capacity(len); for vertex in &self.vertices { @@ -578,7 +578,7 @@ impl EllipseMeshBuilder { impl MeshBuilder for EllipseMeshBuilder { fn build(&self) -> Mesh { let resolution = self.resolution as usize; - let mut indices = Indices::new((resolution - 2) * 3, resolution as u32); + 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); @@ -696,7 +696,8 @@ impl MeshBuilder for Polyline2dMeshBuilder { .map(|v| v.extend(0.0)) .collect(); - let mut indices = Indices::new(self.polyline.vertices.len() - 1, positions.len() as u32); + 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()) @@ -766,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 = Indices::new(self.resolution as usize * 6, num_vertices as u32); + 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]; @@ -1146,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 = Indices::new((resolution as usize - 2) * 2 * 3 + 6, vertex_count); + 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); diff --git a/crates/bevy_mesh/src/primitives/dim3/capsule.rs b/crates/bevy_mesh/src/primitives/dim3/capsule.rs index 7ede6ba1fe49c..81ed8101678aa 100644 --- a/crates/bevy_mesh/src/primitives/dim3/capsule.rs +++ b/crates/bevy_mesh/src/primitives/dim3/capsule.rs @@ -295,7 +295,7 @@ 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 = Indices::new(fs_len as usize, vert_len as u32); + let mut tris = Indices::with_capacity(fs_len as usize, vert_len as u32); tris.resize(fs_len as usize, 0); // Polar caps. diff --git a/crates/bevy_mesh/src/primitives/dim3/cone.rs b/crates/bevy_mesh/src/primitives/dim3/cone.rs index 6e5c8d2706154..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 = Indices::new(num_indices, num_vertices as u32); + let mut indices = Indices::with_capacity(num_indices, num_vertices as u32); // Tip positions.push([0.0, half_height, 0.0]); diff --git a/crates/bevy_mesh/src/primitives/dim3/conical_frustum.rs b/crates/bevy_mesh/src/primitives/dim3/conical_frustum.rs index bb1a360c88ff3..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 = Indices::new(num_indices, num_vertices as u32); + 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; diff --git a/crates/bevy_mesh/src/primitives/dim3/cylinder.rs b/crates/bevy_mesh/src/primitives/dim3/cylinder.rs index b5a8588d37d91..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 = Indices::new(num_indices as usize, num_vertices); + 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; diff --git a/crates/bevy_mesh/src/primitives/dim3/plane.rs b/crates/bevy_mesh/src/primitives/dim3/plane.rs index fca920e08cfd4..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 = Indices::new(num_indices, num_vertices as u32); + 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; diff --git a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs index c08218a90b45b..2ad7c43bdc4df 100644 --- a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs +++ b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs @@ -14,7 +14,7 @@ impl MeshBuilder for Polyline3dMeshBuilder { fn build(&self) -> Mesh { let positions: Vec<_> = self.polyline.vertices.clone(); - let mut indices = Indices::new(self.polyline.vertices.len() - 1, positions.len() as u32); + 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()) diff --git a/crates/bevy_mesh/src/primitives/dim3/torus.rs b/crates/bevy_mesh/src/primitives/dim3/torus.rs index e963b7d319ce5..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 = Indices::new(n_indices, n_vertices as u32); + 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 { diff --git a/crates/bevy_mesh/src/primitives/extrusion.rs b/crates/bevy_mesh/src/primitives/extrusion.rs index b4970db943f18..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 = Indices::new(index_count, vert_count as u32); + 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. diff --git a/examples/math/custom_primitives.rs b/examples/math/custom_primitives.rs index 7295cc6b78785..bf5d6aa9f0c47 100644 --- a/examples/math/custom_primitives.rs +++ b/examples/math/custom_primitives.rs @@ -517,7 +517,7 @@ 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 = Indices::new(6 * self.resolution - 9, 2 * self.resolution as u32); + 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]; From 9ba3c33b5e8ce59ccfca0b7dce439e65fc386df9 Mon Sep 17 00:00:00 2001 From: Luo Zhihao Date: Mon, 24 Nov 2025 23:01:42 +0800 Subject: [PATCH 4/4] fmt --- crates/bevy_mesh/src/primitives/dim3/polyline3d.rs | 3 ++- examples/math/custom_primitives.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs index 2ad7c43bdc4df..c86c810745f95 100644 --- a/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs +++ b/crates/bevy_mesh/src/primitives/dim3/polyline3d.rs @@ -14,7 +14,8 @@ impl MeshBuilder for Polyline3dMeshBuilder { fn build(&self) -> Mesh { let positions: Vec<_> = self.polyline.vertices.clone(); - let mut indices = Indices::with_capacity(self.polyline.vertices.len() - 1, positions.len() as u32); + 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()) diff --git a/examples/math/custom_primitives.rs b/examples/math/custom_primitives.rs index bf5d6aa9f0c47..bc5987c0d3c15 100644 --- a/examples/math/custom_primitives.rs +++ b/examples/math/custom_primitives.rs @@ -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 = Indices::with_capacity(6 * self.resolution - 9, 2 * self.resolution as u32); + 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];