Skip to content

Commit 807d646

Browse files
authored
warn and min for different vertex count (#9699)
# Objective Bevy currently crashes when meshes with different vertex counts for attributes are provided. ## Solution Instead of crashing we can warn and take the min length of all the given attributes.
1 parent cac8442 commit 807d646

File tree

1 file changed

+12
-8
lines changed
  • crates/bevy_render/src/mesh/mesh

1 file changed

+12
-8
lines changed

crates/bevy_render/src/mesh/mesh/mod.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
mod conversions;
22
pub mod skinning;
3+
use bevy_log::warn;
34
pub use wgpu::PrimitiveTopology;
45

56
use crate::{
@@ -323,17 +324,20 @@ impl Mesh {
323324

324325
/// Counts all vertices of the mesh.
325326
///
326-
/// # Panics
327-
/// Panics if the attributes have different vertex counts.
327+
/// If the attributes have different vertex counts, the smallest is returned.
328328
pub fn count_vertices(&self) -> usize {
329329
let mut vertex_count: Option<usize> = None;
330330
for (attribute_id, attribute_data) in &self.attributes {
331331
let attribute_len = attribute_data.values.len();
332332
if let Some(previous_vertex_count) = vertex_count {
333-
assert_eq!(previous_vertex_count, attribute_len,
334-
"{attribute_id:?} has a different vertex count ({attribute_len}) than other attributes ({previous_vertex_count}) in this mesh.");
333+
if previous_vertex_count != attribute_len {
334+
warn!("{attribute_id:?} has a different vertex count ({attribute_len}) than other attributes ({previous_vertex_count}) in this mesh, \
335+
all attributes will be truncated to match the smallest.");
336+
vertex_count = Some(std::cmp::min(previous_vertex_count, attribute_len));
337+
}
338+
} else {
339+
vertex_count = Some(attribute_len);
335340
}
336-
vertex_count = Some(attribute_len);
337341
}
338342

339343
vertex_count.unwrap_or(0)
@@ -343,8 +347,8 @@ impl Mesh {
343347
/// Therefore the attributes are located in the order of their [`MeshVertexAttribute::id`].
344348
/// This is used to transform the vertex data into a GPU friendly format.
345349
///
346-
/// # Panics
347-
/// Panics if the attributes have different vertex counts.
350+
/// If the vertex attributes have different lengths, they are all truncated to
351+
/// the length of the smallest.
348352
pub fn get_vertex_buffer_data(&self) -> Vec<u8> {
349353
let mut vertex_size = 0;
350354
for attribute_data in self.attributes.values() {
@@ -356,7 +360,7 @@ impl Mesh {
356360
let mut attributes_interleaved_buffer = vec![0; vertex_count * vertex_size];
357361
// bundle into interleaved buffers
358362
let mut attribute_offset = 0;
359-
for attribute_data in self.attributes.values() {
363+
for attribute_data in self.attributes.values().take(vertex_count) {
360364
let attribute_size = attribute_data.attribute.format.get_size() as usize;
361365
let attributes_bytes = attribute_data.values.get_bytes();
362366
for (vertex_index, attribute_bytes) in

0 commit comments

Comments
 (0)