Skip to content

Commit 95dce3a

Browse files
authored
Merge pull request #154 from OptimisticPeach/master
Add Icospheres mesh generation
2 parents 1b2aca4 + 86c20eb commit 95dce3a

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

crates/bevy_render/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ once_cell = "1.4.0"
3838
downcast-rs = "1.1.1"
3939
thiserror = "1.0"
4040
anyhow = "1.0"
41+
hexasphere = "0.1.5"
4142

4243
[features]
4344
png = ["image/png"]
44-
hdr = ["image/hdr"]
45+
hdr = ["image/hdr"]

crates/bevy_render/src/mesh/mesh.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,16 @@ impl Mesh {
165165
}
166166
}
167167

168+
/// Generation for some primitive shape meshes.
168169
pub mod shape {
169170
use super::{Mesh, VertexAttribute};
170171
use crate::pipeline::PrimitiveTopology;
171172
use bevy_math::*;
173+
use hexasphere::Hexasphere;
172174

175+
/// A cube.
173176
pub struct Cube {
177+
/// Half the side length of the cube.
174178
pub size: f32,
175179
}
176180

@@ -246,8 +250,11 @@ pub mod shape {
246250
}
247251
}
248252

253+
/// A rectangle on the XY plane.
249254
pub struct Quad {
255+
/// Full width and height of the rectangle.
250256
pub size: Vec2,
257+
/// Flips the texture coords of the resulting vertices.
251258
pub flip: bool,
252259
}
253260

@@ -341,7 +348,9 @@ pub mod shape {
341348
}
342349
}
343350

351+
/// A square on the XZ plane.
344352
pub struct Plane {
353+
/// The total side length of the square.
345354
pub size: f32,
346355
}
347356

@@ -378,6 +387,70 @@ pub mod shape {
378387
}
379388
}
380389
}
390+
391+
/// A sphere made from a subdivided Icosahedron.
392+
pub struct Icosphere {
393+
/// The radius of the sphere.
394+
pub radius: f32,
395+
/// The number of subdivisions applied.
396+
pub subdivisions: usize,
397+
}
398+
399+
impl Default for Icosphere {
400+
fn default() -> Self {
401+
Self {
402+
radius: 1.0,
403+
subdivisions: 5,
404+
}
405+
}
406+
}
407+
408+
impl From<Icosphere> for Mesh {
409+
fn from(sphere: Icosphere) -> Self {
410+
let hexasphere = Hexasphere::new(sphere.subdivisions, |point| {
411+
let inclination = point.z().acos();
412+
let azumith = point.y().atan2(point.x());
413+
414+
let norm_inclination = 1.0 - (inclination / std::f32::consts::PI);
415+
let norm_azumith = (azumith / std::f32::consts::PI) * 0.5;
416+
417+
[norm_inclination, norm_azumith]
418+
});
419+
420+
let raw_points = hexasphere.raw_points();
421+
422+
let points = raw_points
423+
.iter()
424+
.map(|&p| {
425+
(p * sphere.radius).into()
426+
})
427+
.collect::<Vec<[f32; 3]>>();
428+
429+
let normals = raw_points
430+
.iter()
431+
.copied()
432+
.map(Into::into)
433+
.collect::<Vec<[f32; 3]>>();
434+
435+
let uvs = hexasphere.raw_data().to_owned();
436+
437+
let mut indices = Vec::with_capacity(hexasphere.indices_per_main_triangle() * 20);
438+
439+
for i in 0..20 {
440+
hexasphere.get_indices(i, &mut indices);
441+
}
442+
443+
Mesh {
444+
primitive_topology: PrimitiveTopology::TriangleList,
445+
attributes: vec![
446+
VertexAttribute::position(points),
447+
VertexAttribute::normal(normals),
448+
VertexAttribute::uv(uvs),
449+
],
450+
indices: Some(indices)
451+
}
452+
}
453+
}
381454
}
382455

383456
fn remove_current_mesh_resources(

examples/3d/3d_scene.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ fn setup(
2929
translation: Translation::new(0.0, 1.0, 0.0),
3030
..Default::default()
3131
})
32+
// sphere
33+
.spawn(PbrComponents {
34+
mesh: meshes.add(Mesh::from(shape::Icosphere { subdivisions: 4, radius: 0.5 })),
35+
material: materials.add(Color::rgb(0.1, 0.4, 0.8).into()),
36+
translation: Translation::new(1.5, 1.5, 1.5),
37+
..Default::default()
38+
})
3239
// light
3340
.spawn(LightComponents {
3441
translation: Translation::new(4.0, 8.0, 4.0),

0 commit comments

Comments
 (0)