mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
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:
parent
4d3f43131e
commit
38c8dc27c7
4 changed files with 135 additions and 133 deletions
|
@ -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![
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
)
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue