Skip to content

Commit

Permalink
Merge pull request bevyengine#154 from OptimisticPeach/master
Browse files Browse the repository at this point in the history
Add Icospheres mesh generation
  • Loading branch information
cart authored Aug 14, 2020
2 parents 1b2aca4 + 86c20eb commit 95dce3a
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
3 changes: 2 additions & 1 deletion crates/bevy_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ once_cell = "1.4.0"
downcast-rs = "1.1.1"
thiserror = "1.0"
anyhow = "1.0"
hexasphere = "0.1.5"

[features]
png = ["image/png"]
hdr = ["image/hdr"]
hdr = ["image/hdr"]
73 changes: 73 additions & 0 deletions crates/bevy_render/src/mesh/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,16 @@ impl Mesh {
}
}

/// Generation for some primitive shape meshes.
pub mod shape {
use super::{Mesh, VertexAttribute};
use crate::pipeline::PrimitiveTopology;
use bevy_math::*;
use hexasphere::Hexasphere;

/// A cube.
pub struct Cube {
/// Half the side length of the cube.
pub size: f32,
}

Expand Down Expand Up @@ -246,8 +250,11 @@ pub mod shape {
}
}

/// A rectangle on the XY plane.
pub struct Quad {
/// Full width and height of the rectangle.
pub size: Vec2,
/// Flips the texture coords of the resulting vertices.
pub flip: bool,
}

Expand Down Expand Up @@ -341,7 +348,9 @@ pub mod shape {
}
}

/// A square on the XZ plane.
pub struct Plane {
/// The total side length of the square.
pub size: f32,
}

Expand Down Expand Up @@ -378,6 +387,70 @@ pub mod shape {
}
}
}

/// A sphere made from a subdivided Icosahedron.
pub struct Icosphere {
/// The radius of the sphere.
pub radius: f32,
/// The number of subdivisions applied.
pub subdivisions: usize,
}

impl Default for Icosphere {
fn default() -> Self {
Self {
radius: 1.0,
subdivisions: 5,
}
}
}

impl From<Icosphere> for Mesh {
fn from(sphere: Icosphere) -> Self {
let hexasphere = Hexasphere::new(sphere.subdivisions, |point| {
let inclination = point.z().acos();
let azumith = point.y().atan2(point.x());

let norm_inclination = 1.0 - (inclination / std::f32::consts::PI);
let norm_azumith = (azumith / std::f32::consts::PI) * 0.5;

[norm_inclination, norm_azumith]
});

let raw_points = hexasphere.raw_points();

let points = raw_points
.iter()
.map(|&p| {
(p * sphere.radius).into()
})
.collect::<Vec<[f32; 3]>>();

let normals = raw_points
.iter()
.copied()
.map(Into::into)
.collect::<Vec<[f32; 3]>>();

let uvs = hexasphere.raw_data().to_owned();

let mut indices = Vec::with_capacity(hexasphere.indices_per_main_triangle() * 20);

for i in 0..20 {
hexasphere.get_indices(i, &mut indices);
}

Mesh {
primitive_topology: PrimitiveTopology::TriangleList,
attributes: vec![
VertexAttribute::position(points),
VertexAttribute::normal(normals),
VertexAttribute::uv(uvs),
],
indices: Some(indices)
}
}
}
}

fn remove_current_mesh_resources(
Expand Down
7 changes: 7 additions & 0 deletions examples/3d/3d_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ fn setup(
translation: Translation::new(0.0, 1.0, 0.0),
..Default::default()
})
// sphere
.spawn(PbrComponents {
mesh: meshes.add(Mesh::from(shape::Icosphere { subdivisions: 4, radius: 0.5 })),
material: materials.add(Color::rgb(0.1, 0.4, 0.8).into()),
translation: Translation::new(1.5, 1.5, 1.5),
..Default::default()
})
// light
.spawn(LightComponents {
translation: Translation::new(4.0, 8.0, 4.0),
Expand Down

0 comments on commit 95dce3a

Please sign in to comment.