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 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<Icosphere> 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<Icosphere> for Mesh {
type Error = FromIcosphereError;
fn try_from(sphere: Icosphere) -> Result<Self, Self::Error> {
if sphere.subdivisions >= 80 {
/*
Number of triangles:
@ -53,12 +65,10 @@ impl From<Icosphere> 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<Icosphere> 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)
}
}

View file

@ -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()),
];

View file

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

View file

@ -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 {
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 {
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

View file

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

View file

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

View file

@ -26,10 +26,13 @@ fn setup(
});
// transparent sphere, uses `alpha_mode: Mask(f32)`
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
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 {
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 {
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()

View file

@ -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()
},

View file

@ -54,10 +54,13 @@ fn generate_bodies(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let mesh = meshes.add(Mesh::from(shape::Icosphere {
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 {
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.),

View file

@ -67,10 +67,13 @@ fn setup_scene(
});
// sphere
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
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()

View file

@ -47,10 +47,13 @@ fn setup(
const N_LIGHTS: usize = 100_000;
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
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()

View file

@ -40,10 +40,13 @@ fn setup(
// Add an object (sphere) for visualizing scaling.
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
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()