diff --git a/crates/bevy_render/src/mesh/shape/icosphere.rs b/crates/bevy_render/src/mesh/shape/icosphere.rs index 7b0a319622..852ae9eb12 100644 --- a/crates/bevy_render/src/mesh/shape/icosphere.rs +++ b/crates/bevy_render/src/mesh/shape/icosphere.rs @@ -1,5 +1,6 @@ use crate::mesh::{Indices, Mesh}; use hexasphere::shapes::IcoSphere; +use thiserror::Error; use wgpu::PrimitiveTopology; /// A sphere made from a subdivided Icosahedron. @@ -20,8 +21,19 @@ impl Default for Icosphere { } } -impl From for Mesh { - fn from(sphere: Icosphere) -> Self { +#[derive(Debug, Clone, Error)] +pub enum FromIcosphereError { + #[error("Cannot create an icosphere of {subdivisions} subdivisions due to there being too many vertices being generated: {number_of_resulting_points}. (Limited to 65535 vertices or 79 subdivisions)")] + TooManyVertices { + subdivisions: usize, + number_of_resulting_points: usize, + }, +} + +impl TryFrom for Mesh { + type Error = FromIcosphereError; + + fn try_from(sphere: Icosphere) -> Result { if sphere.subdivisions >= 80 { /* Number of triangles: @@ -53,12 +65,10 @@ impl From for Mesh { */ let temp = sphere.subdivisions + 1; let number_of_resulting_points = temp * temp * 10 + 2; - - panic!( - "Cannot create an icosphere of {} subdivisions due to there being too many vertices being generated: {}. (Limited to 65535 vertices or 79 subdivisions)", - sphere.subdivisions, - number_of_resulting_points - ); + return Err(FromIcosphereError::TooManyVertices { + subdivisions: sphere.subdivisions, + number_of_resulting_points, + }); } let generated = IcoSphere::new(sphere.subdivisions, |point| { let inclination = point.y.acos(); @@ -98,6 +108,6 @@ impl From for Mesh { mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, points); mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals); mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs); - mesh + Ok(mesh) } } diff --git a/examples/3d/3d_shapes.rs b/examples/3d/3d_shapes.rs index f9127c730d..61c86bbec9 100644 --- a/examples/3d/3d_shapes.rs +++ b/examples/3d/3d_shapes.rs @@ -38,7 +38,7 @@ fn setup( meshes.add(shape::Box::default().into()), meshes.add(shape::Capsule::default().into()), meshes.add(shape::Torus::default().into()), - meshes.add(shape::Icosphere::default().into()), + meshes.add(shape::Icosphere::default().try_into().unwrap()), meshes.add(shape::UVSphere::default().into()), ]; diff --git a/examples/3d/bloom.rs b/examples/3d/bloom.rs index 3e85a76990..c112ffa9cd 100644 --- a/examples/3d/bloom.rs +++ b/examples/3d/bloom.rs @@ -47,7 +47,8 @@ fn setup_scene( radius: 0.5, subdivisions: 5, } - .into(), + .try_into() + .unwrap(), ); for x in -10..10 { diff --git a/examples/3d/pbr.rs b/examples/3d/pbr.rs index 083b0a619c..926a7eadfb 100644 --- a/examples/3d/pbr.rs +++ b/examples/3d/pbr.rs @@ -22,10 +22,13 @@ fn setup( let y01 = (y + 2) as f32 / 4.0; // sphere commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 0.45, - subdivisions: 32, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 0.45, + subdivisions: 32, + }) + .unwrap(), + ), material: materials.add(StandardMaterial { base_color: Color::hex("ffd891").unwrap(), // vary key PBR parameters on a grid of spheres to show the effect @@ -40,10 +43,13 @@ fn setup( } // unlit sphere commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 0.45, - subdivisions: 32, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 0.45, + subdivisions: 32, + }) + .unwrap(), + ), material: materials.add(StandardMaterial { base_color: Color::hex("ffd891").unwrap(), // vary key PBR parameters on a grid of spheres to show the effect diff --git a/examples/3d/shadow_biases.rs b/examples/3d/shadow_biases.rs index 2392441a95..4ddbde7d97 100644 --- a/examples/3d/shadow_biases.rs +++ b/examples/3d/shadow_biases.rs @@ -42,10 +42,13 @@ fn setup( perceptual_roughness: 1.0, ..default() }); - let sphere_handle = meshes.add(Mesh::from(shape::Icosphere { - radius: sphere_radius, - ..default() - })); + let sphere_handle = meshes.add( + Mesh::try_from(shape::Icosphere { + radius: sphere_radius, + ..default() + }) + .unwrap(), + ); println!("Using DirectionalLight"); diff --git a/examples/3d/shadow_caster_receiver.rs b/examples/3d/shadow_caster_receiver.rs index 6f03cfd50a..d779db77aa 100644 --- a/examples/3d/shadow_caster_receiver.rs +++ b/examples/3d/shadow_caster_receiver.rs @@ -37,10 +37,13 @@ fn setup( perceptual_roughness: 1.0, ..default() }); - let sphere_handle = meshes.add(Mesh::from(shape::Icosphere { - radius: sphere_radius, - ..default() - })); + let sphere_handle = meshes.add( + Mesh::try_from(shape::Icosphere { + radius: sphere_radius, + ..default() + }) + .unwrap(), + ); // sphere - initially a caster commands.spawn(PbrBundle { diff --git a/examples/3d/transparency_3d.rs b/examples/3d/transparency_3d.rs index f257eb8c11..437c291589 100644 --- a/examples/3d/transparency_3d.rs +++ b/examples/3d/transparency_3d.rs @@ -26,10 +26,13 @@ fn setup( }); // transparent sphere, uses `alpha_mode: Mask(f32)` commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 0.5, - subdivisions: 3, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 0.5, + subdivisions: 3, + }) + .unwrap(), + ), material: materials.add(StandardMaterial { // Alpha channel of the color controls transparency. // We set it to 0.0 here, because it will be changed over time in the @@ -46,10 +49,13 @@ fn setup( }); // transparent unlit sphere, uses `alpha_mode: Mask(f32)` commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 0.5, - subdivisions: 3, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 0.5, + subdivisions: 3, + }) + .unwrap(), + ), material: materials.add(StandardMaterial { base_color: Color::rgba(0.2, 0.7, 0.1, 0.0), alpha_mode: AlphaMode::Mask(0.5), @@ -71,10 +77,13 @@ fn setup( }); // opaque sphere commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 0.5, - subdivisions: 3, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 0.5, + subdivisions: 3, + }) + .unwrap(), + ), material: materials.add(Color::rgb(0.7, 0.2, 0.1).into()), transform: Transform::from_xyz(0.0, 0.5, -1.5), ..default() diff --git a/examples/animation/animated_transform.rs b/examples/animation/animated_transform.rs index 19f284aa02..faa090be04 100644 --- a/examples/animation/animated_transform.rs +++ b/examples/animation/animated_transform.rs @@ -118,7 +118,7 @@ fn setup( commands .spawn(( PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere::default())), + mesh: meshes.add(Mesh::try_from(shape::Icosphere::default()).unwrap()), material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), ..default() }, diff --git a/examples/ecs/iter_combinations.rs b/examples/ecs/iter_combinations.rs index fa0ab75419..f16af2f52b 100644 --- a/examples/ecs/iter_combinations.rs +++ b/examples/ecs/iter_combinations.rs @@ -54,10 +54,13 @@ fn generate_bodies( mut meshes: ResMut>, mut materials: ResMut>, ) { - let mesh = meshes.add(Mesh::from(shape::Icosphere { - radius: 1.0, - subdivisions: 3, - })); + let mesh = meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 1.0, + subdivisions: 3, + }) + .unwrap(), + ); let color_range = 0.5..1.0; let vel_range = -0.5..0.5; @@ -114,10 +117,13 @@ fn generate_bodies( BodyBundle { pbr: PbrBundle { transform: Transform::from_scale(Vec3::splat(star_radius)), - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 1.0, - subdivisions: 5, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 1.0, + subdivisions: 5, + }) + .unwrap(), + ), material: materials.add(StandardMaterial { base_color: Color::ORANGE_RED, emissive: (Color::ORANGE_RED * 2.), diff --git a/examples/ios/src/lib.rs b/examples/ios/src/lib.rs index 9924aa62a4..e77085cd67 100644 --- a/examples/ios/src/lib.rs +++ b/examples/ios/src/lib.rs @@ -67,10 +67,13 @@ fn setup_scene( }); // sphere commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - subdivisions: 4, - radius: 0.5, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + subdivisions: 4, + radius: 0.5, + }) + .unwrap(), + ), material: materials.add(Color::rgb(0.1, 0.4, 0.8).into()), transform: Transform::from_xyz(1.5, 1.5, 1.5), ..default() diff --git a/examples/stress_tests/many_lights.rs b/examples/stress_tests/many_lights.rs index 43107e5132..19324a7ff8 100644 --- a/examples/stress_tests/many_lights.rs +++ b/examples/stress_tests/many_lights.rs @@ -47,10 +47,13 @@ fn setup( const N_LIGHTS: usize = 100_000; commands.spawn(PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: RADIUS, - subdivisions: 9, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: RADIUS, + subdivisions: 9, + }) + .unwrap(), + ), material: materials.add(StandardMaterial::from(Color::WHITE)), transform: Transform::from_scale(Vec3::NEG_ONE), ..default() diff --git a/examples/transforms/transform.rs b/examples/transforms/transform.rs index 1fd6e09801..429f154e90 100644 --- a/examples/transforms/transform.rs +++ b/examples/transforms/transform.rs @@ -40,10 +40,13 @@ fn setup( // Add an object (sphere) for visualizing scaling. commands.spawn(( PbrBundle { - mesh: meshes.add(Mesh::from(shape::Icosphere { - radius: 3.0, - subdivisions: 32, - })), + mesh: meshes.add( + Mesh::try_from(shape::Icosphere { + radius: 3.0, + subdivisions: 32, + }) + .unwrap(), + ), material: materials.add(Color::YELLOW.into()), transform: Transform::from_translation(Vec3::ZERO), ..default()