Validate vertex attribute format on insert (#5259)

# Objective

- Validate the format of the values with the expected attribute format.
- Currently, if you pass the wrong format, it will crash somewhere unrelated with a very cryptic error message, so it's really hard to debug for beginners.

## Solution

- Compare the format and panic when unexpected format is passed

## Note

- I used a separate `error!()` for a human friendly message because the panic message is very noisy and hard to parse for beginners. I don't mind changing this to only a panic if people prefer that.
- This could potentially be something that runs only in debug mode, but I don't think inserting attributes is done often enough for this to be an issue.


Co-authored-by: Charles <IceSentry@users.noreply.github.com>
This commit is contained in:
Charles 2022-07-11 14:11:31 +00:00
parent fda1fee1bb
commit 6c2f78f449

View file

@ -13,7 +13,7 @@ use bevy_derive::EnumVariantMeta;
use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem};
use bevy_math::*;
use bevy_reflect::TypeUuid;
use bevy_utils::Hashed;
use bevy_utils::{tracing::error, Hashed};
use std::{collections::BTreeMap, hash::Hash, iter::FusedIterator};
use thiserror::Error;
use wgpu::{
@ -101,19 +101,28 @@ impl Mesh {
/// Sets the data for a vertex attribute (position, normal etc.). The name will
/// often be one of the associated constants such as [`Mesh::ATTRIBUTE_POSITION`].
///
/// # Panics
/// Panics when the format of the values does not match the attribute's format.
#[inline]
pub fn insert_attribute(
&mut self,
attribute: MeshVertexAttribute,
values: impl Into<VertexAttributeValues>,
) {
self.attributes.insert(
attribute.id,
MeshAttributeData {
attribute,
values: values.into(),
},
);
let values: VertexAttributeValues = values.into();
let values_format = VertexFormat::from(&values);
if values_format != attribute.format {
error!(
"Invalid attribute format for {}. Given format is {:?} but expected {:?}",
attribute.name, values_format, attribute.format
);
panic!("Failed to insert attribute");
}
self.attributes
.insert(attribute.id, MeshAttributeData { attribute, values });
}
/// Removes the data for a vertex attribute
@ -994,3 +1003,16 @@ fn generate_tangents_for_mesh(mesh: &Mesh) -> Result<Vec<[f32; 4]>, GenerateTang
Ok(mikktspace_mesh.tangents)
}
#[cfg(test)]
mod tests {
use super::Mesh;
use wgpu::PrimitiveTopology;
#[test]
#[should_panic]
fn panic_invalid_format() {
let mut mesh = Mesh::new(PrimitiveTopology::TriangleList);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, vec![[0.0, 0.0, 0.0]]);
}
}