Change From<Icosphere> to TryFrom<Icosphere> (#6484)

# Objective

- Fixes  #6476

## Solution

- Return error instead of panic through `TryFrom`
- ~~Add `.except()` in examples~~ 
- Add `.unwrap()` in examples
This commit is contained in:
2ne1ugly 2022-11-14 22:34:27 +00:00
parent 4de4e54755
commit db0d7698e2
12 changed files with 107 additions and 60 deletions

View file

@ -1,5 +1,6 @@
use crate::mesh::{Indices, Mesh}; use crate::mesh::{Indices, Mesh};
use hexasphere::shapes::IcoSphere; use hexasphere::shapes::IcoSphere;
use thiserror::Error;
use wgpu::PrimitiveTopology; use wgpu::PrimitiveTopology;
/// A sphere made from a subdivided Icosahedron. /// A sphere made from a subdivided Icosahedron.
@ -20,8 +21,19 @@ impl Default for Icosphere {
} }
} }
impl From<Icosphere> for Mesh { #[derive(Debug, Clone, Error)]
fn from(sphere: Icosphere) -> Self { 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<Icosphere> for Mesh {
type Error = FromIcosphereError;
fn try_from(sphere: Icosphere) -> Result<Self, Self::Error> {
if sphere.subdivisions >= 80 { if sphere.subdivisions >= 80 {
/* /*
Number of triangles: Number of triangles:
@ -53,12 +65,10 @@ impl From<Icosphere> for Mesh {
*/ */
let temp = sphere.subdivisions + 1; let temp = sphere.subdivisions + 1;
let number_of_resulting_points = temp * temp * 10 + 2; let number_of_resulting_points = temp * temp * 10 + 2;
return Err(FromIcosphereError::TooManyVertices {
panic!( subdivisions: sphere.subdivisions,
"Cannot create an icosphere of {} subdivisions due to there being too many vertices being generated: {}. (Limited to 65535 vertices or 79 subdivisions)", number_of_resulting_points,
sphere.subdivisions, });
number_of_resulting_points
);
} }
let generated = IcoSphere::new(sphere.subdivisions, |point| { let generated = IcoSphere::new(sphere.subdivisions, |point| {
let inclination = point.y.acos(); let inclination = point.y.acos();
@ -98,6 +108,6 @@ impl From<Icosphere> for Mesh {
mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, points); mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, points);
mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals); mesh.insert_attribute(Mesh::ATTRIBUTE_NORMAL, normals);
mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs); mesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, uvs);
mesh Ok(mesh)
} }
} }

View file

@ -38,7 +38,7 @@ fn setup(
meshes.add(shape::Box::default().into()), meshes.add(shape::Box::default().into()),
meshes.add(shape::Capsule::default().into()), meshes.add(shape::Capsule::default().into()),
meshes.add(shape::Torus::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()), meshes.add(shape::UVSphere::default().into()),
]; ];

View file

@ -47,7 +47,8 @@ fn setup_scene(
radius: 0.5, radius: 0.5,
subdivisions: 5, subdivisions: 5,
} }
.into(), .try_into()
.unwrap(),
); );
for x in -10..10 { for x in -10..10 {

View file

@ -22,10 +22,13 @@ fn setup(
let y01 = (y + 2) as f32 / 4.0; let y01 = (y + 2) as f32 / 4.0;
// sphere // sphere
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 0.45, Mesh::try_from(shape::Icosphere {
subdivisions: 32, radius: 0.45,
})), subdivisions: 32,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::hex("ffd891").unwrap(), base_color: Color::hex("ffd891").unwrap(),
// vary key PBR parameters on a grid of spheres to show the effect // vary key PBR parameters on a grid of spheres to show the effect
@ -40,10 +43,13 @@ fn setup(
} }
// unlit sphere // unlit sphere
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 0.45, Mesh::try_from(shape::Icosphere {
subdivisions: 32, radius: 0.45,
})), subdivisions: 32,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::hex("ffd891").unwrap(), base_color: Color::hex("ffd891").unwrap(),
// vary key PBR parameters on a grid of spheres to show the effect // vary key PBR parameters on a grid of spheres to show the effect

View file

@ -42,10 +42,13 @@ fn setup(
perceptual_roughness: 1.0, perceptual_roughness: 1.0,
..default() ..default()
}); });
let sphere_handle = meshes.add(Mesh::from(shape::Icosphere { let sphere_handle = meshes.add(
radius: sphere_radius, Mesh::try_from(shape::Icosphere {
..default() radius: sphere_radius,
})); ..default()
})
.unwrap(),
);
println!("Using DirectionalLight"); println!("Using DirectionalLight");

View file

@ -37,10 +37,13 @@ fn setup(
perceptual_roughness: 1.0, perceptual_roughness: 1.0,
..default() ..default()
}); });
let sphere_handle = meshes.add(Mesh::from(shape::Icosphere { let sphere_handle = meshes.add(
radius: sphere_radius, Mesh::try_from(shape::Icosphere {
..default() radius: sphere_radius,
})); ..default()
})
.unwrap(),
);
// sphere - initially a caster // sphere - initially a caster
commands.spawn(PbrBundle { commands.spawn(PbrBundle {

View file

@ -26,10 +26,13 @@ fn setup(
}); });
// transparent sphere, uses `alpha_mode: Mask(f32)` // transparent sphere, uses `alpha_mode: Mask(f32)`
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 0.5, Mesh::try_from(shape::Icosphere {
subdivisions: 3, radius: 0.5,
})), subdivisions: 3,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
// Alpha channel of the color controls transparency. // Alpha channel of the color controls transparency.
// We set it to 0.0 here, because it will be changed over time in the // 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)` // transparent unlit sphere, uses `alpha_mode: Mask(f32)`
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 0.5, Mesh::try_from(shape::Icosphere {
subdivisions: 3, radius: 0.5,
})), subdivisions: 3,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::rgba(0.2, 0.7, 0.1, 0.0), base_color: Color::rgba(0.2, 0.7, 0.1, 0.0),
alpha_mode: AlphaMode::Mask(0.5), alpha_mode: AlphaMode::Mask(0.5),
@ -71,10 +77,13 @@ fn setup(
}); });
// opaque sphere // opaque sphere
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 0.5, Mesh::try_from(shape::Icosphere {
subdivisions: 3, radius: 0.5,
})), subdivisions: 3,
})
.unwrap(),
),
material: materials.add(Color::rgb(0.7, 0.2, 0.1).into()), material: materials.add(Color::rgb(0.7, 0.2, 0.1).into()),
transform: Transform::from_xyz(0.0, 0.5, -1.5), transform: Transform::from_xyz(0.0, 0.5, -1.5),
..default() ..default()

View file

@ -118,7 +118,7 @@ fn setup(
commands commands
.spawn(( .spawn((
PbrBundle { 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()), material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
..default() ..default()
}, },

View file

@ -54,10 +54,13 @@ fn generate_bodies(
mut meshes: ResMut<Assets<Mesh>>, mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>, mut materials: ResMut<Assets<StandardMaterial>>,
) { ) {
let mesh = meshes.add(Mesh::from(shape::Icosphere { let mesh = meshes.add(
radius: 1.0, Mesh::try_from(shape::Icosphere {
subdivisions: 3, radius: 1.0,
})); subdivisions: 3,
})
.unwrap(),
);
let color_range = 0.5..1.0; let color_range = 0.5..1.0;
let vel_range = -0.5..0.5; let vel_range = -0.5..0.5;
@ -114,10 +117,13 @@ fn generate_bodies(
BodyBundle { BodyBundle {
pbr: PbrBundle { pbr: PbrBundle {
transform: Transform::from_scale(Vec3::splat(star_radius)), transform: Transform::from_scale(Vec3::splat(star_radius)),
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 1.0, Mesh::try_from(shape::Icosphere {
subdivisions: 5, radius: 1.0,
})), subdivisions: 5,
})
.unwrap(),
),
material: materials.add(StandardMaterial { material: materials.add(StandardMaterial {
base_color: Color::ORANGE_RED, base_color: Color::ORANGE_RED,
emissive: (Color::ORANGE_RED * 2.), emissive: (Color::ORANGE_RED * 2.),

View file

@ -67,10 +67,13 @@ fn setup_scene(
}); });
// sphere // sphere
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
subdivisions: 4, Mesh::try_from(shape::Icosphere {
radius: 0.5, subdivisions: 4,
})), radius: 0.5,
})
.unwrap(),
),
material: materials.add(Color::rgb(0.1, 0.4, 0.8).into()), material: materials.add(Color::rgb(0.1, 0.4, 0.8).into()),
transform: Transform::from_xyz(1.5, 1.5, 1.5), transform: Transform::from_xyz(1.5, 1.5, 1.5),
..default() ..default()

View file

@ -47,10 +47,13 @@ fn setup(
const N_LIGHTS: usize = 100_000; const N_LIGHTS: usize = 100_000;
commands.spawn(PbrBundle { commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: RADIUS, Mesh::try_from(shape::Icosphere {
subdivisions: 9, radius: RADIUS,
})), subdivisions: 9,
})
.unwrap(),
),
material: materials.add(StandardMaterial::from(Color::WHITE)), material: materials.add(StandardMaterial::from(Color::WHITE)),
transform: Transform::from_scale(Vec3::NEG_ONE), transform: Transform::from_scale(Vec3::NEG_ONE),
..default() ..default()

View file

@ -40,10 +40,13 @@ fn setup(
// Add an object (sphere) for visualizing scaling. // Add an object (sphere) for visualizing scaling.
commands.spawn(( commands.spawn((
PbrBundle { PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere { mesh: meshes.add(
radius: 3.0, Mesh::try_from(shape::Icosphere {
subdivisions: 32, radius: 3.0,
})), subdivisions: 32,
})
.unwrap(),
),
material: materials.add(Color::YELLOW.into()), material: materials.add(Color::YELLOW.into()),
transform: Transform::from_translation(Vec3::ZERO), transform: Transform::from_translation(Vec3::ZERO),
..default() ..default()