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