Use u32 for resolution/subdivision in primitive meshing (#13930)

# Objective

- Make primitive meshing behavior consisten across platforms
- Avoid using sizes bigger than `u32` since these aren't even supported
for meshes

## Solution

- Use `u32` instead of `usize` for resolution/subdivisions/segments/etc
fields

---

## Changelog

- Change resolutions in primitive mesh builders from `usize` to `u32`

## Migration Guide

- All primitive mesh builders now take `u32` instead of `usize` for
their resolution/subdivision/segment counts
This commit is contained in:
NiseVoid 2024-06-20 02:58:21 +02:00 committed by GitHub
parent 4d3f43131e
commit 38c8dc27c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 135 additions and 133 deletions

View file

@ -23,7 +23,7 @@ pub struct CircleMeshBuilder {
/// The number of vertices used for the circle mesh.
/// The default is `32`.
#[doc(alias = "vertices")]
pub resolution: usize,
pub resolution: u32,
}
impl Default for CircleMeshBuilder {
@ -38,7 +38,7 @@ impl Default for CircleMeshBuilder {
impl CircleMeshBuilder {
/// Creates a new [`CircleMeshBuilder`] from a given radius and vertex count.
#[inline]
pub const fn new(radius: f32, resolution: usize) -> Self {
pub const fn new(radius: f32, resolution: u32) -> Self {
Self {
circle: Circle { radius },
resolution,
@ -48,7 +48,7 @@ impl CircleMeshBuilder {
/// Sets the number of vertices used for the circle mesh.
#[inline]
#[doc(alias = "vertices")]
pub const fn resolution(mut self, resolution: usize) -> Self {
pub const fn resolution(mut self, resolution: u32) -> Self {
self.resolution = resolution;
self
}
@ -68,7 +68,7 @@ impl Extrudable for CircleMeshBuilder {
vec![PerimeterSegment::Smooth {
first_normal: Vec2::Y,
last_normal: Vec2::Y,
indices: (0..self.resolution as u32).chain([0]).collect(),
indices: (0..self.resolution).chain([0]).collect(),
}]
}
}
@ -127,7 +127,7 @@ pub struct CircularSectorMeshBuilder {
/// The number of vertices used for the arc portion of the sector mesh.
/// The default is `32`.
#[doc(alias = "vertices")]
pub resolution: usize,
pub resolution: u32,
/// The UV mapping mode
pub uv_mode: CircularMeshUvMode,
}
@ -155,7 +155,7 @@ impl CircularSectorMeshBuilder {
/// Sets the number of vertices used for the sector mesh.
#[inline]
#[doc(alias = "vertices")]
pub const fn resolution(mut self, resolution: usize) -> Self {
pub const fn resolution(mut self, resolution: u32) -> Self {
self.resolution = resolution;
self
}
@ -170,10 +170,11 @@ impl CircularSectorMeshBuilder {
impl MeshBuilder for CircularSectorMeshBuilder {
fn build(&self) -> Mesh {
let mut indices = Vec::with_capacity((self.resolution - 1) * 3);
let mut positions = Vec::with_capacity(self.resolution + 1);
let normals = vec![[0.0, 0.0, 1.0]; self.resolution + 1];
let mut uvs = Vec::with_capacity(self.resolution + 1);
let resolution = self.resolution as usize;
let mut indices = Vec::with_capacity((resolution - 1) * 3);
let mut positions = Vec::with_capacity(resolution + 1);
let normals = vec![[0.0, 0.0, 1.0]; resolution + 1];
let mut uvs = Vec::with_capacity(resolution + 1);
let CircularMeshUvMode::Mask { angle: uv_angle } = self.uv_mode;
@ -198,7 +199,7 @@ impl MeshBuilder for CircularSectorMeshBuilder {
uvs.push([uv.x, uv.y]);
}
for i in 1..(self.resolution as u32) {
for i in 1..self.resolution {
// Index 0 is the center.
indices.extend_from_slice(&[0, i, i + 1]);
}
@ -216,18 +217,17 @@ impl MeshBuilder for CircularSectorMeshBuilder {
impl Extrudable for CircularSectorMeshBuilder {
fn perimeter(&self) -> Vec<PerimeterSegment> {
let resolution = self.resolution as u32;
let (sin, cos) = self.sector.arc.half_angle.sin_cos();
let first_normal = Vec2::new(sin, cos);
let last_normal = Vec2::new(-sin, cos);
vec![
PerimeterSegment::Flat {
indices: vec![resolution, 0, 1],
indices: vec![self.resolution, 0, 1],
},
PerimeterSegment::Smooth {
first_normal,
last_normal,
indices: (1..=resolution).collect(),
indices: (1..=self.resolution).collect(),
},
]
}
@ -264,7 +264,7 @@ pub struct CircularSegmentMeshBuilder {
/// The number of vertices used for the arc portion of the segment mesh.
/// The default is `32`.
#[doc(alias = "vertices")]
pub resolution: usize,
pub resolution: u32,
/// The UV mapping mode
pub uv_mode: CircularMeshUvMode,
}
@ -292,7 +292,7 @@ impl CircularSegmentMeshBuilder {
/// Sets the number of vertices used for the segment mesh.
#[inline]
#[doc(alias = "vertices")]
pub const fn resolution(mut self, resolution: usize) -> Self {
pub const fn resolution(mut self, resolution: u32) -> Self {
self.resolution = resolution;
self
}
@ -307,10 +307,11 @@ impl CircularSegmentMeshBuilder {
impl MeshBuilder for CircularSegmentMeshBuilder {
fn build(&self) -> Mesh {
let mut indices = Vec::with_capacity((self.resolution - 1) * 3);
let mut positions = Vec::with_capacity(self.resolution + 1);
let normals = vec![[0.0, 0.0, 1.0]; self.resolution + 1];
let mut uvs = Vec::with_capacity(self.resolution + 1);
let resolution = self.resolution as usize;
let mut indices = Vec::with_capacity((resolution - 1) * 3);
let mut positions = Vec::with_capacity(resolution + 1);
let normals = vec![[0.0, 0.0, 1.0]; resolution + 1];
let mut uvs = Vec::with_capacity(resolution + 1);
let CircularMeshUvMode::Mask { angle: uv_angle } = self.uv_mode;
@ -344,7 +345,7 @@ impl MeshBuilder for CircularSegmentMeshBuilder {
uvs.push([uv.x, uv.y]);
}
for i in 1..(self.resolution as u32) {
for i in 1..self.resolution {
// Index 0 is the midpoint of the chord.
indices.extend_from_slice(&[0, i, i + 1]);
}
@ -362,18 +363,17 @@ impl MeshBuilder for CircularSegmentMeshBuilder {
impl Extrudable for CircularSegmentMeshBuilder {
fn perimeter(&self) -> Vec<PerimeterSegment> {
let resolution = self.resolution as u32;
let (sin, cos) = self.segment.arc.half_angle.sin_cos();
let first_normal = Vec2::new(sin, cos);
let last_normal = Vec2::new(-sin, cos);
vec![
PerimeterSegment::Flat {
indices: vec![resolution, 0, 1],
indices: vec![self.resolution, 0, 1],
},
PerimeterSegment::Smooth {
first_normal,
last_normal,
indices: (1..=resolution).collect(),
indices: (1..=self.resolution).collect(),
},
]
}
@ -420,7 +420,7 @@ impl MeshBuilder for RegularPolygonMeshBuilder {
// The ellipse mesh is just a regular polygon with two radii
Ellipse::new(self.circumradius, self.circumradius)
.mesh()
.resolution(self.sides as usize)
.resolution(self.sides)
.build()
}
}
@ -447,7 +447,7 @@ pub struct EllipseMeshBuilder {
/// The number of vertices used for the ellipse mesh.
/// The default is `32`.
#[doc(alias = "vertices")]
pub resolution: usize,
pub resolution: u32,
}
impl Default for EllipseMeshBuilder {
@ -462,7 +462,7 @@ impl Default for EllipseMeshBuilder {
impl EllipseMeshBuilder {
/// Creates a new [`EllipseMeshBuilder`] from a given half width and half height and a vertex count.
#[inline]
pub const fn new(half_width: f32, half_height: f32, resolution: usize) -> Self {
pub const fn new(half_width: f32, half_height: f32, resolution: u32) -> Self {
Self {
ellipse: Ellipse::new(half_width, half_height),
resolution,
@ -472,7 +472,7 @@ impl EllipseMeshBuilder {
/// Sets the number of vertices used for the ellipse mesh.
#[inline]
#[doc(alias = "vertices")]
pub const fn resolution(mut self, resolution: usize) -> Self {
pub const fn resolution(mut self, resolution: u32) -> Self {
self.resolution = resolution;
self
}
@ -480,10 +480,11 @@ impl EllipseMeshBuilder {
impl MeshBuilder for EllipseMeshBuilder {
fn build(&self) -> Mesh {
let mut indices = Vec::with_capacity((self.resolution - 2) * 3);
let mut positions = Vec::with_capacity(self.resolution);
let normals = vec![[0.0, 0.0, 1.0]; self.resolution];
let mut uvs = Vec::with_capacity(self.resolution);
let resolution = self.resolution as usize;
let mut indices = Vec::with_capacity((resolution - 2) * 3);
let mut positions = Vec::with_capacity(resolution);
let normals = vec![[0.0, 0.0, 1.0]; resolution];
let mut uvs = Vec::with_capacity(resolution);
// Add pi/2 so that there is a vertex at the top (sin is 1.0 and cos is 0.0)
let start_angle = std::f32::consts::FRAC_PI_2;
@ -500,7 +501,7 @@ impl MeshBuilder for EllipseMeshBuilder {
uvs.push([0.5 * (cos + 1.0), 1.0 - 0.5 * (sin + 1.0)]);
}
for i in 1..(self.resolution as u32 - 1) {
for i in 1..(self.resolution - 1) {
indices.extend_from_slice(&[0, i, i + 1]);
}
@ -520,7 +521,7 @@ impl Extrudable for EllipseMeshBuilder {
vec![PerimeterSegment::Smooth {
first_normal: Vec2::Y,
last_normal: Vec2::Y,
indices: (0..self.resolution as u32).chain([0]).collect(),
indices: (0..self.resolution).chain([0]).collect(),
}]
}
}
@ -549,7 +550,7 @@ pub struct AnnulusMeshBuilder {
/// The number of vertices used in constructing each concentric circle of the annulus mesh.
/// The default is `32`.
pub resolution: usize,
pub resolution: u32,
}
impl Default for AnnulusMeshBuilder {
@ -564,7 +565,7 @@ impl Default for AnnulusMeshBuilder {
impl AnnulusMeshBuilder {
/// Create an [`AnnulusMeshBuilder`] with the given inner radius, outer radius, and angular vertex count.
#[inline]
pub fn new(inner_radius: f32, outer_radius: f32, resolution: usize) -> Self {
pub fn new(inner_radius: f32, outer_radius: f32, resolution: u32) -> Self {
Self {
annulus: Annulus::new(inner_radius, outer_radius),
resolution,
@ -573,7 +574,7 @@ impl AnnulusMeshBuilder {
/// Sets the number of vertices used in constructing the concentric circles of the annulus mesh.
#[inline]
pub fn resolution(mut self, resolution: usize) -> Self {
pub fn resolution(mut self, resolution: u32) -> Self {
self.resolution = resolution;
self
}
@ -584,8 +585,8 @@ impl MeshBuilder for AnnulusMeshBuilder {
let inner_radius = self.annulus.inner_circle.radius;
let outer_radius = self.annulus.outer_circle.radius;
let num_vertices = (self.resolution + 1) * 2;
let mut indices = Vec::with_capacity(self.resolution * 6);
let num_vertices = (self.resolution as usize + 1) * 2;
let mut indices = Vec::with_capacity(self.resolution as usize * 6);
let mut positions = Vec::with_capacity(num_vertices);
let mut uvs = Vec::with_capacity(num_vertices);
let normals = vec![[0.0, 0.0, 1.0]; num_vertices];
@ -618,7 +619,7 @@ impl MeshBuilder for AnnulusMeshBuilder {
// we are just making sure that they both have the right orientation,
// which is the CCW order of
// `inner_vertex` -> `outer_vertex` -> `next_outer` -> `next_inner`
for i in 0..(self.resolution as u32) {
for i in 0..self.resolution {
let inner_vertex = 2 * i;
let outer_vertex = 2 * i + 1;
let next_inner = inner_vertex + 2;
@ -640,7 +641,7 @@ impl MeshBuilder for AnnulusMeshBuilder {
impl Extrudable for AnnulusMeshBuilder {
fn perimeter(&self) -> Vec<PerimeterSegment> {
let vert_count = 2 * self.resolution as u32;
let vert_count = 2 * self.resolution;
vec![
PerimeterSegment::Smooth {
first_normal: Vec2::NEG_Y,
@ -851,7 +852,7 @@ pub struct Capsule2dMeshBuilder {
/// The total number of vertices for the capsule mesh will be two times the resolution.
///
/// The default is `16`.
pub resolution: usize,
pub resolution: u32,
}
impl Default for Capsule2dMeshBuilder {
@ -867,7 +868,7 @@ impl Capsule2dMeshBuilder {
/// Creates a new [`Capsule2dMeshBuilder`] from a given radius, length, and the number of vertices
/// used for one hemicircle. The total number of vertices for the capsule mesh will be two times the resolution.
#[inline]
pub fn new(radius: f32, length: f32, resolution: usize) -> Self {
pub fn new(radius: f32, length: f32, resolution: u32) -> Self {
Self {
capsule: Capsule2d::new(radius, length),
resolution,
@ -877,7 +878,7 @@ impl Capsule2dMeshBuilder {
/// Sets the number of vertices used for one hemicircle.
/// The total number of vertices for the capsule mesh will be two times the resolution.
#[inline]
pub const fn resolution(mut self, resolution: usize) -> Self {
pub const fn resolution(mut self, resolution: u32) -> Self {
self.resolution = resolution;
self
}
@ -886,14 +887,14 @@ impl Capsule2dMeshBuilder {
impl MeshBuilder for Capsule2dMeshBuilder {
fn build(&self) -> Mesh {
// The resolution is the number of vertices for one semicircle
let resolution = self.resolution as u32;
let vertex_count = 2 * self.resolution;
let resolution = self.resolution;
let vertex_count = 2 * resolution;
// Six extra indices for the two triangles between the hemicircles
let mut indices = Vec::with_capacity((self.resolution - 2) * 2 * 3 + 6);
let mut positions = Vec::with_capacity(vertex_count);
let normals = vec![[0.0, 0.0, 1.0]; vertex_count];
let mut uvs = Vec::with_capacity(vertex_count);
let mut indices = Vec::with_capacity((resolution as usize - 2) * 2 * 3 + 6);
let mut positions = Vec::with_capacity(vertex_count as usize);
let normals = vec![[0.0, 0.0, 1.0]; vertex_count as usize];
let mut uvs = Vec::with_capacity(vertex_count as usize);
let radius = self.capsule.radius;
let step = std::f32::consts::TAU / vertex_count as f32;
@ -930,7 +931,7 @@ impl MeshBuilder for Capsule2dMeshBuilder {
indices.extend_from_slice(&[0, resolution - 1, resolution]);
// Create bottom semicircle
for i in resolution..vertex_count as u32 {
for i in resolution..vertex_count {
// Compute vertex position at angle theta
let theta = start_angle + i as f32 * step;
let (sin, cos) = theta.sin_cos();
@ -946,7 +947,7 @@ impl MeshBuilder for Capsule2dMeshBuilder {
}
// Add indices for bottom right triangle of the part between the hemicircles
indices.extend_from_slice(&[resolution, vertex_count as u32 - 1, 0]);
indices.extend_from_slice(&[resolution, vertex_count - 1, 0]);
Mesh::new(
PrimitiveTopology::TriangleList,
@ -961,7 +962,7 @@ impl MeshBuilder for Capsule2dMeshBuilder {
impl Extrudable for Capsule2dMeshBuilder {
fn perimeter(&self) -> Vec<PerimeterSegment> {
let resolution = self.resolution as u32;
let resolution = self.resolution;
let top_semi_indices = (0..resolution).collect();
let bottom_semi_indices = (resolution..(2 * resolution)).collect();
vec![

View file

@ -25,13 +25,13 @@ pub struct Capsule3dMeshBuilder {
pub capsule: Capsule3d,
/// The number of horizontal lines subdividing the cylindrical part of the capsule.
/// The default is `0`.
pub rings: usize,
pub rings: u32,
/// The number of vertical lines subdividing the hemispheres of the capsule.
/// The default is `32`.
pub longitudes: usize,
pub longitudes: u32,
/// The number of horizontal lines subdividing the hemispheres of the capsule.
/// The default is `16`.
pub latitudes: usize,
pub latitudes: u32,
/// The manner in which UV coordinates are distributed vertically.
/// The default is [`CapsuleUvProfile::Aspect`].
pub uv_profile: CapsuleUvProfile,
@ -55,7 +55,7 @@ impl Capsule3dMeshBuilder {
/// Note that `height` is the distance between the centers of the hemispheres.
/// `radius` will be added to both ends to get the real height of the mesh.
#[inline]
pub fn new(radius: f32, height: f32, longitudes: usize, latitudes: usize) -> Self {
pub fn new(radius: f32, height: f32, longitudes: u32, latitudes: u32) -> Self {
Self {
capsule: Capsule3d::new(radius, height),
longitudes,
@ -66,21 +66,21 @@ impl Capsule3dMeshBuilder {
/// Sets the number of horizontal lines subdividing the cylindrical part of the capsule.
#[inline]
pub const fn rings(mut self, rings: usize) -> Self {
pub const fn rings(mut self, rings: u32) -> Self {
self.rings = rings;
self
}
/// Sets the number of vertical lines subdividing the hemispheres of the capsule.
#[inline]
pub const fn longitudes(mut self, longitudes: usize) -> Self {
pub const fn longitudes(mut self, longitudes: u32) -> Self {
self.longitudes = longitudes;
self
}
/// Sets the number of horizontal lines subdividing the hemispheres of the capsule.
#[inline]
pub const fn latitudes(mut self, latitudes: usize) -> Self {
pub const fn latitudes(mut self, latitudes: u32) -> Self {
self.latitudes = latitudes;
self
}
@ -130,7 +130,7 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let vert_offset_south_cap = vert_offset_south_polar + lonsp1;
// Initialize arrays.
let vert_len = vert_offset_south_cap + longitudes;
let vert_len = (vert_offset_south_cap + longitudes) as usize;
let mut vs: Vec<Vec3> = vec![Vec3::ZERO; vert_len];
let mut vts: Vec<Vec2> = vec![Vec2::ZERO; vert_len];
@ -149,11 +149,11 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let vt_aspect_north = 1.0 - vt_aspect_ratio;
let vt_aspect_south = vt_aspect_ratio;
let mut theta_cartesian: Vec<Vec2> = vec![Vec2::ZERO; longitudes];
let mut rho_theta_cartesian: Vec<Vec2> = vec![Vec2::ZERO; longitudes];
let mut s_texture_cache: Vec<f32> = vec![0.0; lonsp1];
let mut theta_cartesian: Vec<Vec2> = vec![Vec2::ZERO; longitudes as usize];
let mut rho_theta_cartesian: Vec<Vec2> = vec![Vec2::ZERO; longitudes as usize];
let mut s_texture_cache: Vec<f32> = vec![0.0; lonsp1 as usize];
for j in 0..longitudes {
for j in 0..longitudes as usize {
let jf = j as f32;
let s_texture_polar = 1.0 - ((jf + 0.5) * to_tex_horizontal);
let theta = jf * to_theta;
@ -170,30 +170,30 @@ impl MeshBuilder for Capsule3dMeshBuilder {
vns[j] = Vec3::Y;
// South.
let idx = vert_offset_south_cap + j;
let idx = vert_offset_south_cap as usize + j;
vs[idx] = Vec3::new(0.0, -summit, 0.0);
vts[idx] = Vec2::new(s_texture_polar, 0.0);
vns[idx] = Vec3::new(0.0, -1.0, 0.0);
}
// Equatorial vertices.
for (j, s_texture_cache_j) in s_texture_cache.iter_mut().enumerate().take(lonsp1) {
for (j, s_texture_cache_j) in s_texture_cache.iter_mut().enumerate().take(lonsp1 as usize) {
let s_texture = 1.0 - j as f32 * to_tex_horizontal;
*s_texture_cache_j = s_texture;
// Wrap to first element upon reaching last.
let j_mod = j % longitudes;
let j_mod = j % longitudes as usize;
let tc = theta_cartesian[j_mod];
let rtc = rho_theta_cartesian[j_mod];
// North equator.
let idxn = vert_offset_north_equator + j;
let idxn = vert_offset_north_equator as usize + j;
vs[idxn] = Vec3::new(rtc.x, half_length, -rtc.y);
vts[idxn] = Vec2::new(s_texture, vt_aspect_north);
vns[idxn] = Vec3::new(tc.x, 0.0, -tc.y);
// South equator.
let idxs = vert_offset_south_equator + j;
let idxs = vert_offset_south_equator as usize + j;
vs[idxs] = Vec3::new(rtc.x, -half_length, -rtc.y);
vts[idxs] = Vec2::new(s_texture, vt_aspect_south);
vns[idxs] = Vec3::new(tc.x, 0.0, -tc.y);
@ -231,13 +231,13 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let vert_curr_lat_north = vert_offset_north_hemi + i_lonsp1;
let vert_curr_lat_south = vert_offset_south_hemi + i_lonsp1;
for (j, s_texture) in s_texture_cache.iter().enumerate().take(lonsp1) {
let j_mod = j % longitudes;
for (j, s_texture) in s_texture_cache.iter().enumerate().take(lonsp1 as usize) {
let j_mod = j % longitudes as usize;
let tc = theta_cartesian[j_mod];
// North hemisphere.
let idxn = vert_curr_lat_north + j;
let idxn = vert_curr_lat_north as usize + j;
vs[idxn] = Vec3::new(
rho_cos_phi_north * tc.x,
z_offset_north,
@ -247,7 +247,7 @@ impl MeshBuilder for Capsule3dMeshBuilder {
vns[idxn] = Vec3::new(cos_phi_north * tc.x, -sin_phi_north, -cos_phi_north * tc.y);
// South hemisphere.
let idxs = vert_curr_lat_south + j;
let idxs = vert_curr_lat_south as usize + j;
vs[idxs] = Vec3::new(
rho_cos_phi_south * tc.x,
z_offset_sout,
@ -263,7 +263,7 @@ impl MeshBuilder for Capsule3dMeshBuilder {
// Exclude both origin and destination edges
// (North and South equators) from the interpolation.
let to_fac = 1.0 / ringsp1 as f32;
let mut idx_cyl_lat = vert_offset_cylinder;
let mut idx_cyl_lat = vert_offset_cylinder as usize;
for h in 1..ringsp1 {
let fac = h as f32 * to_fac;
@ -271,8 +271,8 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let t_texture = cmpl_fac * vt_aspect_north + fac * vt_aspect_south;
let z = half_length - 2.0 * half_length * fac;
for (j, s_texture) in s_texture_cache.iter().enumerate().take(lonsp1) {
let j_mod = j % longitudes;
for (j, s_texture) in s_texture_cache.iter().enumerate().take(lonsp1 as usize) {
let j_mod = j % longitudes as usize;
let tc = theta_cartesian[j_mod];
let rtc = rho_theta_cartesian[j_mod];
@ -299,22 +299,22 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let tri_offset_south_cap = tri_offset_south_hemi + hemi_lons;
let fs_len = tri_offset_south_cap + lons3;
let mut tris: Vec<u32> = vec![0; fs_len];
let mut tris: Vec<u32> = vec![0; fs_len as usize];
// Polar caps.
let mut i = 0;
let mut k = 0;
let mut m = tri_offset_south_cap;
let mut m = tri_offset_south_cap as usize;
while i < longitudes {
// North.
tris[k] = i as u32;
tris[k + 1] = (vert_offset_north_hemi + i) as u32;
tris[k + 2] = (vert_offset_north_hemi + i + 1) as u32;
tris[k] = i;
tris[k + 1] = vert_offset_north_hemi + i;
tris[k + 2] = vert_offset_north_hemi + i + 1;
// South.
tris[m] = (vert_offset_south_cap + i) as u32;
tris[m + 1] = (vert_offset_south_polar + i + 1) as u32;
tris[m + 2] = (vert_offset_south_polar + i) as u32;
tris[m] = vert_offset_south_cap + i;
tris[m + 1] = vert_offset_south_polar + i + 1;
tris[m + 2] = vert_offset_south_polar + i;
i += 1;
k += 3;
@ -324,8 +324,8 @@ impl MeshBuilder for Capsule3dMeshBuilder {
// Hemispheres.
let mut i = 0;
let mut k = tri_offset_north_hemi;
let mut m = tri_offset_south_hemi;
let mut k = tri_offset_north_hemi as usize;
let mut m = tri_offset_south_hemi as usize;
while i < half_latsn1 {
let i_lonsp1 = i * lonsp1;
@ -344,13 +344,13 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let north11 = vert_next_lat_north + j + 1;
let north10 = vert_curr_lat_north + j + 1;
tris[k] = north00 as u32;
tris[k + 1] = north11 as u32;
tris[k + 2] = north10 as u32;
tris[k] = north00;
tris[k + 1] = north11;
tris[k + 2] = north10;
tris[k + 3] = north00 as u32;
tris[k + 4] = north01 as u32;
tris[k + 5] = north11 as u32;
tris[k + 3] = north00;
tris[k + 4] = north01;
tris[k + 5] = north11;
// South.
let south00 = vert_curr_lat_south + j;
@ -358,13 +358,13 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let south11 = vert_next_lat_south + j + 1;
let south10 = vert_curr_lat_south + j + 1;
tris[m] = south00 as u32;
tris[m + 1] = south11 as u32;
tris[m + 2] = south10 as u32;
tris[m] = south00;
tris[m + 1] = south11;
tris[m + 2] = south10;
tris[m + 3] = south00 as u32;
tris[m + 4] = south01 as u32;
tris[m + 5] = south11 as u32;
tris[m + 3] = south00;
tris[m + 4] = south01;
tris[m + 5] = south11;
j += 1;
k += 6;
@ -376,7 +376,7 @@ impl MeshBuilder for Capsule3dMeshBuilder {
// Cylinder.
let mut i = 0;
let mut k = tri_offset_cylinder;
let mut k = tri_offset_cylinder as usize;
while i < ringsp1 {
let vert_curr_lat = vert_offset_north_equator + i * lonsp1;
@ -389,13 +389,13 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let cy11 = vert_next_lat + j + 1;
let cy10 = vert_curr_lat + j + 1;
tris[k] = cy00 as u32;
tris[k + 1] = cy11 as u32;
tris[k + 2] = cy10 as u32;
tris[k] = cy00;
tris[k + 1] = cy11;
tris[k + 2] = cy10;
tris[k + 3] = cy00 as u32;
tris[k + 4] = cy01 as u32;
tris[k + 5] = cy11 as u32;
tris[k + 3] = cy00;
tris[k + 4] = cy01;
tris[k + 5] = cy11;
j += 1;
k += 6;
@ -409,7 +409,7 @@ impl MeshBuilder for Capsule3dMeshBuilder {
let vts: Vec<[f32; 2]> = vts.into_iter().map(Into::into).collect();
assert_eq!(vs.len(), vert_len);
assert_eq!(tris.len(), fs_len);
assert_eq!(tris.len(), fs_len as usize);
Mesh::new(
PrimitiveTopology::TriangleList,

View file

@ -16,9 +16,9 @@ pub enum IcosphereError {
#[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 {
/// The number of subdivisions used. 79 is the largest allowed value for a mesh to be generated.
subdivisions: usize,
subdivisions: u32,
/// The number of vertices generated. 65535 is the largest allowed value for a mesh to be generated.
number_of_resulting_points: usize,
number_of_resulting_points: u32,
},
}
@ -29,17 +29,17 @@ pub enum SphereKind {
Ico {
/// The number of subdivisions applied.
/// The number of faces quadruples with each subdivision.
subdivisions: usize,
subdivisions: u32,
},
/// A UV sphere, a spherical mesh that consists of quadrilaterals
/// apart from triangles at the top and bottom.
Uv {
/// The number of longitudinal sectors, aka the horizontal resolution.
#[doc(alias = "horizontal_resolution")]
sectors: usize,
sectors: u32,
/// The number of latitudinal stacks, aka the vertical resolution.
#[doc(alias = "vertical_resolution")]
stacks: usize,
stacks: u32,
},
}
@ -82,7 +82,7 @@ impl SphereMeshBuilder {
/// and an [`IcosphereError`] is returned.
///
/// A good default is `5` subdivisions.
pub fn ico(&self, subdivisions: usize) -> Result<Mesh, IcosphereError> {
pub fn ico(&self, subdivisions: u32) -> Result<Mesh, IcosphereError> {
if subdivisions >= 80 {
/*
Number of triangles:
@ -119,7 +119,7 @@ impl SphereMeshBuilder {
number_of_resulting_points,
});
}
let generated = IcoSphere::new(subdivisions, |point| {
let generated = IcoSphere::new(subdivisions as usize, |point| {
let inclination = point.y.acos();
let azimuth = point.z.atan2(point.x);
@ -166,7 +166,7 @@ impl SphereMeshBuilder {
/// longitudinal sectors and latitudinal stacks, aka horizontal and vertical resolution.
///
/// A good default is `32` sectors and `18` stacks.
pub fn uv(&self, sectors: usize, stacks: usize) -> Mesh {
pub fn uv(&self, sectors: u32, stacks: u32) -> Mesh {
// Largely inspired from http://www.songho.ca/opengl/gl_sphere.html
let sectors_f32 = sectors as f32;
@ -175,10 +175,11 @@ impl SphereMeshBuilder {
let sector_step = 2. * PI / sectors_f32;
let stack_step = PI / stacks_f32;
let mut vertices: Vec<[f32; 3]> = Vec::with_capacity(stacks * sectors);
let mut normals: Vec<[f32; 3]> = Vec::with_capacity(stacks * sectors);
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(stacks * sectors);
let mut indices: Vec<u32> = Vec::with_capacity(stacks * sectors * 2 * 3);
let n_vertices = (stacks * sectors) as usize;
let mut vertices: Vec<[f32; 3]> = Vec::with_capacity(n_vertices);
let mut normals: Vec<[f32; 3]> = Vec::with_capacity(n_vertices);
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(n_vertices);
let mut indices: Vec<u32> = Vec::with_capacity(n_vertices * 2 * 3);
for i in 0..stacks + 1 {
let stack_angle = PI / 2. - (i as f32) * stack_step;
@ -206,14 +207,14 @@ impl SphereMeshBuilder {
let mut k2 = k1 + sectors + 1;
for _j in 0..sectors {
if i != 0 {
indices.push(k1 as u32);
indices.push(k2 as u32);
indices.push((k1 + 1) as u32);
indices.push(k1);
indices.push(k2);
indices.push(k1 + 1);
}
if i != stacks - 1 {
indices.push((k1 + 1) as u32);
indices.push(k2 as u32);
indices.push((k2 + 1) as u32);
indices.push(k1 + 1);
indices.push(k2);
indices.push(k2 + 1);
}
k1 += 1;
k2 += 1;

View file

@ -49,10 +49,10 @@ impl PerimeterSegment {
/// Returns the amount of vertices each 'layer' of the extrusion should include for this perimeter segment.
///
/// A layer is the set of vertices sharing a common Z value or depth.
fn vertices_per_layer(&self) -> usize {
fn vertices_per_layer(&self) -> u32 {
match self {
PerimeterSegment::Smooth { indices, .. } => indices.len(),
PerimeterSegment::Flat { indices } => 2 * (indices.len() - 1),
PerimeterSegment::Smooth { indices, .. } => indices.len() as u32,
PerimeterSegment::Flat { indices } => 2 * (indices.len() as u32 - 1),
}
}
@ -131,7 +131,7 @@ where
impl ExtrusionBuilder<Circle> {
/// Sets the number of vertices used for the circle mesh at each end of the extrusion.
pub fn resolution(mut self, resolution: usize) -> Self {
pub fn resolution(mut self, resolution: u32) -> Self {
self.base_builder.resolution = resolution;
self
}
@ -139,7 +139,7 @@ impl ExtrusionBuilder<Circle> {
impl ExtrusionBuilder<Ellipse> {
/// Sets the number of vertices used for the ellipse mesh at each end of the extrusion.
pub fn resolution(mut self, resolution: usize) -> Self {
pub fn resolution(mut self, resolution: u32) -> Self {
self.base_builder.resolution = resolution;
self
}
@ -147,7 +147,7 @@ impl ExtrusionBuilder<Ellipse> {
impl ExtrusionBuilder<Annulus> {
/// Sets the number of vertices used in constructing the concentric circles of the annulus mesh at each end of the extrusion.
pub fn resolution(mut self, resolution: usize) -> Self {
pub fn resolution(mut self, resolution: u32) -> Self {
self.base_builder.resolution = resolution;
self
}
@ -155,7 +155,7 @@ impl ExtrusionBuilder<Annulus> {
impl ExtrusionBuilder<Capsule2d> {
/// Sets the number of vertices used for each hemicircle at the ends of the extrusion.
pub fn resolution(mut self, resolution: usize) -> Self {
pub fn resolution(mut self, resolution: u32) -> Self {
self.base_builder.resolution = resolution;
self
}
@ -239,7 +239,7 @@ where
.iter()
.fold((0, 0), |(verts, indices), perimeter| {
(
verts + layers * perimeter.vertices_per_layer(),
verts + layers * perimeter.vertices_per_layer() as usize,
indices + self.segments * perimeter.indices_per_segment(),
)
});