Skip to content

Commit cae8350

Browse files
committed
Add hemisphere generator
1 parent f93b1d3 commit cae8350

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/models/meshes.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,55 @@ impl Mesh {
6262
Mesh::generate(name, genmesh::generators::SphereUv::new(u, v))
6363
}
6464

65+
/// Constructs a hemisphere (a dome)
66+
///
67+
/// `u` is the number of points across the equator of the sphere
68+
///
69+
/// `v` is the number of points from equator to pole
70+
pub fn hemisphere(name: impl ToString, u: usize, v: usize) -> Self {
71+
use genmesh::generators::{IndexedPolygon, SharedVertex};
72+
use genmesh::Triangulate;
73+
74+
let sphere_generator = genmesh::generators::SphereUv::new(u, 2 * v);
75+
76+
let vertices = sphere_generator.shared_vertex_iter().collect::<Vec<_>>();
77+
let vertices_count = vertices.len();
78+
79+
let mut positions = Vec::with_capacity(vertices_count);
80+
let mut normals = Vec::with_capacity(vertices_count);
81+
let mut tex_uvs = Vec::with_capacity(vertices_count);
82+
83+
for vertex in vertices.into_iter() {
84+
positions.push([vertex.pos.x, vertex.pos.y, vertex.pos.z]);
85+
normals.push([vertex.normal.x, vertex.normal.y, vertex.normal.z]);
86+
tex_uvs.push([(vertex.pos.x + 1.0) / 2.0, (vertex.pos.z + 1.0) / 2.0]);
87+
}
88+
89+
let indices = sphere_generator
90+
.indexed_polygon_iter()
91+
.triangulate()
92+
.filter_map(|triangle| {
93+
let triangle_indices = [triangle.x as u32, triangle.y as u32, triangle.z as u32];
94+
let is_above_equator = triangle_indices
95+
.iter()
96+
.any(|i| positions[*i as usize][2] >= -0.0);
97+
if is_above_equator {
98+
Some(triangle_indices)
99+
} else {
100+
None
101+
}
102+
})
103+
.flatten()
104+
.collect::<Vec<_>>();
105+
106+
let mut mesh = Self::new(name);
107+
mesh.set_vertices::<VertexPosition>(positions);
108+
mesh.set_vertices::<VertexNormal>(normals);
109+
mesh.set_vertices::<VertexTexture>(tex_uvs);
110+
mesh.set_indices(indices);
111+
mesh
112+
}
113+
65114
/// Constructs a cone mesh
66115
///
67116
/// `u` is the number of subdivisions around the radius and it must be greater then 1

0 commit comments

Comments
 (0)