Deprecate shapes in bevy_render::mesh::shape (#11773)

# Objective

#11431 and #11688 implemented meshing support for Bevy's new geometric
primitives. The next step is to deprecate the shapes in
`bevy_render::mesh::shape` and to later remove them completely for 0.14.

## Solution

Deprecate the shapes and reduce code duplication by utilizing the
primitive meshing API for the old shapes where possible.

Note that some shapes have behavior that can't be exactly reproduced
with the new primitives yet:

- `Box` is more of an AABB with min/max extents
- `Plane` supports a subdivision count
- `Quad` has a `flipped` property

These types have not been changed to utilize the new primitives yet.

---

## Changelog

- Deprecated all shapes in `bevy_render::mesh::shape`
- Changed all examples to use new primitives for meshing

## Migration Guide

Bevy has previously used rendering-specific types like `UVSphere` and
`Quad` for primitive mesh shapes. These have now been deprecated to use
the geometric primitives newly introduced in version 0.13.

Some examples:

```rust
let before = meshes.add(shape::Box::new(5.0, 0.15, 5.0));
let after = meshes.add(Cuboid::new(5.0, 0.15, 5.0));

let before = meshes.add(shape::Quad::default());
let after = meshes.add(Rectangle::default());

let before = meshes.add(shape::Plane::from_size(5.0));
// The surface normal can now also be specified when using `new`
let after = meshes.add(Plane3d::default().mesh().size(5.0, 5.0));

let before = meshes.add(
    Mesh::try_from(shape::Icosphere {
        radius: 0.5,
        subdivisions: 5,
    })
    .unwrap(),
);
let after = meshes.add(Sphere::new(0.5).mesh().ico(5).unwrap());
```
This commit is contained in:
Joona Aalto 2024-02-08 20:01:34 +02:00 committed by GitHub
parent 76b6666965
commit 0166db33f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
82 changed files with 294 additions and 1112 deletions

View file

@ -405,3 +405,62 @@ impl From<Capsule2dMeshBuilder> for Mesh {
capsule.build()
}
}
#[cfg(test)]
mod tests {
use bevy_math::primitives::RegularPolygon;
use crate::mesh::{Mesh, VertexAttributeValues};
/// Sin/cos and multiplication computations result in numbers like 0.4999999.
/// Round these to numbers we expect like 0.5.
fn fix_floats<const N: usize>(points: &mut [[f32; N]]) {
for point in points.iter_mut() {
for coord in point.iter_mut() {
let round = (*coord * 2.).round() / 2.;
if (*coord - round).abs() < 0.00001 {
*coord = round;
}
}
}
}
#[test]
fn test_regular_polygon() {
let mut mesh = Mesh::from(RegularPolygon::new(7.0, 4));
let Some(VertexAttributeValues::Float32x3(mut positions)) =
mesh.remove_attribute(Mesh::ATTRIBUTE_POSITION)
else {
panic!("Expected positions f32x3");
};
let Some(VertexAttributeValues::Float32x2(mut uvs)) =
mesh.remove_attribute(Mesh::ATTRIBUTE_UV_0)
else {
panic!("Expected uvs f32x2");
};
let Some(VertexAttributeValues::Float32x3(normals)) =
mesh.remove_attribute(Mesh::ATTRIBUTE_NORMAL)
else {
panic!("Expected normals f32x3");
};
fix_floats(&mut positions);
fix_floats(&mut uvs);
assert_eq!(
[
[0.0, 7.0, 0.0],
[-7.0, 0.0, 0.0],
[0.0, -7.0, 0.0],
[7.0, 0.0, 0.0],
],
&positions[..]
);
// Note V coordinate increases in the opposite direction to the Y coordinate.
assert_eq!([[0.5, 0.0], [0.0, 0.5], [0.5, 1.0], [1.0, 0.5],], &uvs[..]);
assert_eq!(&[[0.0, 0.0, 1.0]; 4], &normals[..]);
}
}

View file

@ -1,11 +1,10 @@
use crate::{
mesh::{Indices, Mesh},
render_asset::RenderAssetUsages,
};
use bevy_math::{Vec2, Vec3};
use wgpu::PrimitiveTopology;
use crate::mesh::{Capsule3dMeshBuilder, CapsuleUvProfile, Mesh};
/// A cylinder with hemispheres at the top and bottom
#[deprecated(
since = "0.13.0",
note = "please use the `Capsule3d` primitive in `bevy_math` instead"
)]
#[derive(Debug, Copy, Clone)]
pub struct Capsule {
/// Radius on the `XZ` plane.
@ -34,346 +33,17 @@ impl Default for Capsule {
}
}
#[derive(Debug, Default, Clone, Copy)]
/// Manner in which UV coordinates are distributed vertically.
pub enum CapsuleUvProfile {
/// UV space is distributed by how much of the capsule consists of the hemispheres.
#[default]
Aspect,
/// Hemispheres get UV space according to the ratio of latitudes to rings.
Uniform,
/// Upper third of the texture goes to the northern hemisphere, middle third to the cylinder
/// and lower third to the southern one.
Fixed,
}
impl From<Capsule> for Mesh {
#[allow(clippy::needless_range_loop)]
fn from(capsule: Capsule) -> Self {
// code adapted from https://behreajj.medium.com/making-a-capsule-mesh-via-script-in-five-3d-environments-c2214abf02db
let Capsule {
radius,
rings,
depth,
latitudes,
longitudes,
uv_profile,
} = capsule;
let calc_middle = rings > 0;
let half_lats = latitudes / 2;
let half_latsn1 = half_lats - 1;
let half_latsn2 = half_lats - 2;
let ringsp1 = rings + 1;
let lonsp1 = longitudes + 1;
let half_depth = depth * 0.5;
let summit = half_depth + radius;
// Vertex index offsets.
let vert_offset_north_hemi = longitudes;
let vert_offset_north_equator = vert_offset_north_hemi + lonsp1 * half_latsn1;
let vert_offset_cylinder = vert_offset_north_equator + lonsp1;
let vert_offset_south_equator = if calc_middle {
vert_offset_cylinder + lonsp1 * rings
} else {
vert_offset_cylinder
};
let vert_offset_south_hemi = vert_offset_south_equator + lonsp1;
let vert_offset_south_polar = vert_offset_south_hemi + lonsp1 * half_latsn2;
let vert_offset_south_cap = vert_offset_south_polar + lonsp1;
// Initialize arrays.
let vert_len = vert_offset_south_cap + longitudes;
let mut vs: Vec<Vec3> = vec![Vec3::ZERO; vert_len];
let mut vts: Vec<Vec2> = vec![Vec2::ZERO; vert_len];
let mut vns: Vec<Vec3> = vec![Vec3::ZERO; vert_len];
let to_theta = 2.0 * std::f32::consts::PI / longitudes as f32;
let to_phi = std::f32::consts::PI / latitudes as f32;
let to_tex_horizontal = 1.0 / longitudes as f32;
let to_tex_vertical = 1.0 / half_lats as f32;
let vt_aspect_ratio = match uv_profile {
CapsuleUvProfile::Aspect => radius / (depth + radius + radius),
CapsuleUvProfile::Uniform => half_lats as f32 / (ringsp1 + latitudes) as f32,
CapsuleUvProfile::Fixed => 1.0 / 3.0,
};
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];
for j in 0..longitudes {
let jf = j as f32;
let s_texture_polar = 1.0 - ((jf + 0.5) * to_tex_horizontal);
let theta = jf * to_theta;
let cos_theta = theta.cos();
let sin_theta = theta.sin();
theta_cartesian[j] = Vec2::new(cos_theta, sin_theta);
rho_theta_cartesian[j] = Vec2::new(radius * cos_theta, radius * sin_theta);
// North.
vs[j] = Vec3::new(0.0, summit, 0.0);
vts[j] = Vec2::new(s_texture_polar, 1.0);
vns[j] = Vec3::Y;
// South.
let idx = vert_offset_south_cap + 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 in 0..lonsp1 {
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 tc = theta_cartesian[j_mod];
let rtc = rho_theta_cartesian[j_mod];
// North equator.
let idxn = vert_offset_north_equator + j;
vs[idxn] = Vec3::new(rtc.x, half_depth, -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;
vs[idxs] = Vec3::new(rtc.x, -half_depth, -rtc.y);
vts[idxs] = Vec2::new(s_texture, vt_aspect_south);
vns[idxs] = Vec3::new(tc.x, 0.0, -tc.y);
}
// Hemisphere vertices.
for i in 0..half_latsn1 {
let ip1f = i as f32 + 1.0;
let phi = ip1f * to_phi;
// For coordinates.
let cos_phi_south = phi.cos();
let sin_phi_south = phi.sin();
// Symmetrical hemispheres mean cosine and sine only needs
// to be calculated once.
let cos_phi_north = sin_phi_south;
let sin_phi_north = -cos_phi_south;
let rho_cos_phi_north = radius * cos_phi_north;
let rho_sin_phi_north = radius * sin_phi_north;
let z_offset_north = half_depth - rho_sin_phi_north;
let rho_cos_phi_south = radius * cos_phi_south;
let rho_sin_phi_south = radius * sin_phi_south;
let z_offset_sout = -half_depth - rho_sin_phi_south;
// For texture coordinates.
let t_tex_fac = ip1f * to_tex_vertical;
let cmpl_tex_fac = 1.0 - t_tex_fac;
let t_tex_north = cmpl_tex_fac + vt_aspect_north * t_tex_fac;
let t_tex_south = cmpl_tex_fac * vt_aspect_south;
let i_lonsp1 = i * lonsp1;
let vert_curr_lat_north = vert_offset_north_hemi + i_lonsp1;
let vert_curr_lat_south = vert_offset_south_hemi + i_lonsp1;
for j in 0..lonsp1 {
let j_mod = j % longitudes;
let s_texture = s_texture_cache[j];
let tc = theta_cartesian[j_mod];
// North hemisphere.
let idxn = vert_curr_lat_north + j;
vs[idxn] = Vec3::new(
rho_cos_phi_north * tc.x,
z_offset_north,
-rho_cos_phi_north * tc.y,
);
vts[idxn] = Vec2::new(s_texture, t_tex_north);
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;
vs[idxs] = Vec3::new(
rho_cos_phi_south * tc.x,
z_offset_sout,
-rho_cos_phi_south * tc.y,
);
vts[idxs] = Vec2::new(s_texture, t_tex_south);
vns[idxs] = Vec3::new(cos_phi_south * tc.x, -sin_phi_south, -cos_phi_south * tc.y);
}
}
// Cylinder vertices.
if calc_middle {
// 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;
for h in 1..ringsp1 {
let fac = h as f32 * to_fac;
let cmpl_fac = 1.0 - fac;
let t_texture = cmpl_fac * vt_aspect_north + fac * vt_aspect_south;
let z = half_depth - depth * fac;
for j in 0..lonsp1 {
let j_mod = j % longitudes;
let tc = theta_cartesian[j_mod];
let rtc = rho_theta_cartesian[j_mod];
let s_texture = s_texture_cache[j];
vs[idx_cyl_lat] = Vec3::new(rtc.x, z, -rtc.y);
vts[idx_cyl_lat] = Vec2::new(s_texture, t_texture);
vns[idx_cyl_lat] = Vec3::new(tc.x, 0.0, -tc.y);
idx_cyl_lat += 1;
}
}
}
// Triangle indices.
// Stride is 3 for polar triangles;
// stride is 6 for two triangles forming a quad.
let lons3 = longitudes * 3;
let lons6 = longitudes * 6;
let hemi_lons = half_latsn1 * lons6;
let tri_offset_north_hemi = lons3;
let tri_offset_cylinder = tri_offset_north_hemi + hemi_lons;
let tri_offset_south_hemi = tri_offset_cylinder + ringsp1 * lons6;
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];
// Polar caps.
let mut i = 0;
let mut k = 0;
let mut m = tri_offset_south_cap;
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;
// 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;
i += 1;
k += 3;
m += 3;
}
// Hemispheres.
let mut i = 0;
let mut k = tri_offset_north_hemi;
let mut m = tri_offset_south_hemi;
while i < half_latsn1 {
let i_lonsp1 = i * lonsp1;
let vert_curr_lat_north = vert_offset_north_hemi + i_lonsp1;
let vert_next_lat_north = vert_curr_lat_north + lonsp1;
let vert_curr_lat_south = vert_offset_south_equator + i_lonsp1;
let vert_next_lat_south = vert_curr_lat_south + lonsp1;
let mut j = 0;
while j < longitudes {
// North.
let north00 = vert_curr_lat_north + j;
let north01 = vert_next_lat_north + j;
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 + 3] = north00 as u32;
tris[k + 4] = north01 as u32;
tris[k + 5] = north11 as u32;
// South.
let south00 = vert_curr_lat_south + j;
let south01 = vert_next_lat_south + j;
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 + 3] = south00 as u32;
tris[m + 4] = south01 as u32;
tris[m + 5] = south11 as u32;
j += 1;
k += 6;
m += 6;
}
i += 1;
}
// Cylinder.
let mut i = 0;
let mut k = tri_offset_cylinder;
while i < ringsp1 {
let vert_curr_lat = vert_offset_north_equator + i * lonsp1;
let vert_next_lat = vert_curr_lat + lonsp1;
let mut j = 0;
while j < longitudes {
let cy00 = vert_curr_lat + j;
let cy01 = vert_next_lat + j;
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 + 3] = cy00 as u32;
tris[k + 4] = cy01 as u32;
tris[k + 5] = cy11 as u32;
j += 1;
k += 6;
}
i += 1;
}
let vs: Vec<[f32; 3]> = vs.into_iter().map(Into::into).collect();
let vns: Vec<[f32; 3]> = vns.into_iter().map(Into::into).collect();
let vts: Vec<[f32; 2]> = vts.into_iter().map(Into::into).collect();
assert_eq!(vs.len(), vert_len);
assert_eq!(tris.len(), fs_len);
Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
Capsule3dMeshBuilder::new(
capsule.radius,
capsule.depth,
capsule.longitudes,
capsule.latitudes,
)
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vs)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, vns)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, vts)
.with_inserted_indices(Indices::U32(tris))
.rings(capsule.rings)
.uv_profile(capsule.uv_profile)
.build()
}
}

View file

@ -1,10 +1,10 @@
use crate::{
mesh::{Indices, Mesh},
render_asset::RenderAssetUsages,
};
use wgpu::PrimitiveTopology;
use crate::mesh::{CylinderMeshBuilder, Mesh};
/// A cylinder which stands on the XZ plane
#[deprecated(
since = "0.13.0",
note = "please use the `Cylinder` primitive in `bevy_math` instead"
)]
#[derive(Clone, Copy, Debug)]
pub struct Cylinder {
/// Radius in the XZ plane.
@ -34,100 +34,8 @@ impl Default for Cylinder {
impl From<Cylinder> for Mesh {
fn from(c: Cylinder) -> Self {
debug_assert!(c.radius > 0.0);
debug_assert!(c.height > 0.0);
debug_assert!(c.resolution > 2);
debug_assert!(c.segments > 0);
let num_rings = c.segments + 1;
let num_vertices = c.resolution * 2 + num_rings * (c.resolution + 1);
let num_faces = c.resolution * (num_rings - 2);
let num_indices = (2 * num_faces + 2 * (c.resolution - 1) * 2) * 3;
let mut positions = Vec::with_capacity(num_vertices as usize);
let mut normals = Vec::with_capacity(num_vertices as usize);
let mut uvs = Vec::with_capacity(num_vertices as usize);
let mut indices = Vec::with_capacity(num_indices as usize);
let step_theta = std::f32::consts::TAU / c.resolution as f32;
let step_y = c.height / c.segments as f32;
// rings
for ring in 0..num_rings {
let y = -c.height / 2.0 + ring as f32 * step_y;
for segment in 0..=c.resolution {
let theta = segment as f32 * step_theta;
let (sin, cos) = theta.sin_cos();
positions.push([c.radius * cos, y, c.radius * sin]);
normals.push([cos, 0., sin]);
uvs.push([
segment as f32 / c.resolution as f32,
ring as f32 / c.segments as f32,
]);
}
}
// barrel skin
for i in 0..c.segments {
let ring = i * (c.resolution + 1);
let next_ring = (i + 1) * (c.resolution + 1);
for j in 0..c.resolution {
indices.extend_from_slice(&[
ring + j,
next_ring + j,
ring + j + 1,
next_ring + j,
next_ring + j + 1,
ring + j + 1,
]);
}
}
// caps
let mut build_cap = |top: bool| {
let offset = positions.len() as u32;
let (y, normal_y, winding) = if top {
(c.height / 2., 1., (1, 0))
} else {
(c.height / -2., -1., (0, 1))
};
for i in 0..c.resolution {
let theta = i as f32 * step_theta;
let (sin, cos) = theta.sin_cos();
positions.push([cos * c.radius, y, sin * c.radius]);
normals.push([0.0, normal_y, 0.0]);
uvs.push([0.5 * (cos + 1.0), 1.0 - 0.5 * (sin + 1.0)]);
}
for i in 1..(c.resolution - 1) {
indices.extend_from_slice(&[
offset,
offset + i + winding.0,
offset + i + winding.1,
]);
}
};
// top
build_cap(true);
build_cap(false);
Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
)
.with_inserted_indices(Indices::U32(indices))
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
CylinderMeshBuilder::new(c.radius, c.height, c.resolution)
.segments(c.segments)
.build()
}
}

View file

@ -1,12 +1,11 @@
use crate::{
mesh::{Indices, Mesh},
render_asset::RenderAssetUsages,
};
use hexasphere::shapes::IcoSphere;
use thiserror::Error;
use wgpu::PrimitiveTopology;
use crate::mesh::{IcosphereError, Mesh, Meshable};
use bevy_math::primitives::Sphere;
/// A sphere made from a subdivided Icosahedron.
#[deprecated(
since = "0.13.0",
note = "please use the `Sphere` primitive in `bevy_math` instead"
)]
#[derive(Debug, Clone, Copy)]
pub struct Icosphere {
/// The radius of the sphere.
@ -24,95 +23,10 @@ impl Default for Icosphere {
}
}
#[derive(Debug, Clone, Error)]
pub enum FromIcosphereError {
#[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 {
subdivisions: usize,
number_of_resulting_points: usize,
},
}
impl TryFrom<Icosphere> for Mesh {
type Error = FromIcosphereError;
type Error = IcosphereError;
fn try_from(sphere: Icosphere) -> Result<Self, Self::Error> {
if sphere.subdivisions >= 80 {
/*
Number of triangles:
N = 20
Number of edges:
E = 30
Number of vertices:
V = 12
Number of points within a triangle (triangular numbers):
inner(s) = (s^2 + s) / 2
Number of points on an edge:
edges(s) = s
Add up all vertices on the surface:
vertices(s) = edges(s) * E + inner(s - 1) * N + V
Expand and simplify. Notice that the triangular number formula has roots at -1, and 0, so translating it one to the right fixes it.
subdivisions(s) = 30s + 20((s^2 - 2s + 1 + s - 1) / 2) + 12
subdivisions(s) = 30s + 10s^2 - 10s + 12
subdivisions(s) = 10(s^2 + 2s) + 12
Factor an (s + 1) term to simplify in terms of calculation
subdivisions(s) = 10(s + 1)^2 + 12 - 10
resulting_vertices(s) = 10(s + 1)^2 + 2
*/
let temp = sphere.subdivisions + 1;
let number_of_resulting_points = temp * temp * 10 + 2;
return Err(FromIcosphereError::TooManyVertices {
subdivisions: sphere.subdivisions,
number_of_resulting_points,
});
}
let generated = IcoSphere::new(sphere.subdivisions, |point| {
let inclination = point.y.acos();
let azimuth = point.z.atan2(point.x);
let norm_inclination = inclination / std::f32::consts::PI;
let norm_azimuth = 0.5 - (azimuth / std::f32::consts::TAU);
[norm_azimuth, norm_inclination]
});
let raw_points = generated.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 = generated.raw_data().to_owned();
let mut indices = Vec::with_capacity(generated.indices_per_main_triangle() * 20);
for i in 0..20 {
generated.get_indices(i, &mut indices);
}
let indices = Indices::U32(indices);
Ok(Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
)
.with_inserted_indices(indices)
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, points)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs))
Sphere::new(sphere.radius).mesh().ico(sphere.subdivisions)
}
}

View file

@ -1,8 +1,14 @@
#![allow(deprecated)]
use crate::render_asset::RenderAssetUsages;
use super::{Indices, Mesh};
use bevy_math::*;
#[deprecated(
since = "0.13.0",
note = "please use the `Cuboid` primitive for meshing or `Aabb2d` for a bounding volume"
)]
#[derive(Debug, Copy, Clone)]
pub struct Cube {
pub size: f32,
@ -27,6 +33,10 @@ impl From<Cube> for Mesh {
}
/// An axis-aligned box defined by its minimum and maximum point.
#[deprecated(
since = "0.13.0",
note = "please use the `Cuboid` primitive for meshing or `Aabb3d` for a bounding volume"
)]
#[derive(Debug, Copy, Clone)]
pub struct Box {
pub min_x: f32,
@ -134,6 +144,10 @@ impl From<Box> for Mesh {
}
/// A rectangle on the `XY` plane centered at the origin.
#[deprecated(
since = "0.13.0",
note = "please use the `Quad` primitive in `bevy_math` instead"
)]
#[derive(Debug, Copy, Clone)]
pub struct Quad {
/// Full width and height of the rectangle.
@ -189,6 +203,10 @@ impl From<Quad> for Mesh {
}
/// A square on the `XZ` plane centered at the origin.
#[deprecated(
since = "0.13.0",
note = "please use the `Plane3d` primitive in `bevy_math` instead"
)]
#[derive(Debug, Copy, Clone)]
pub struct Plane {
/// The total side length of the square.
@ -279,7 +297,7 @@ mod regular_polygon;
mod torus;
mod uvsphere;
pub use capsule::{Capsule, CapsuleUvProfile};
pub use capsule::Capsule;
pub use cylinder::Cylinder;
pub use icosphere::Icosphere;
pub use regular_polygon::{Circle, RegularPolygon};

View file

@ -1,10 +1,10 @@
use crate::{
mesh::{Indices, Mesh},
render_asset::RenderAssetUsages,
};
use wgpu::PrimitiveTopology;
use crate::mesh::{Mesh, Meshable};
/// A regular polygon in the `XY` plane
#[deprecated(
since = "0.13.0",
note = "please use the `RegularPolygon` primitive in `bevy_math` instead"
)]
#[derive(Debug, Copy, Clone)]
pub struct RegularPolygon {
/// Circumscribed radius in the `XY` plane.
@ -33,43 +33,15 @@ impl RegularPolygon {
impl From<RegularPolygon> for Mesh {
fn from(polygon: RegularPolygon) -> Self {
let RegularPolygon { radius, sides } = polygon;
debug_assert!(sides > 2, "RegularPolygon requires at least 3 sides.");
let mut positions = Vec::with_capacity(sides);
let mut normals = Vec::with_capacity(sides);
let mut uvs = Vec::with_capacity(sides);
let step = std::f32::consts::TAU / sides as f32;
for i in 0..sides {
let theta = std::f32::consts::FRAC_PI_2 - i as f32 * step;
let (sin, cos) = theta.sin_cos();
positions.push([cos * radius, sin * radius, 0.0]);
normals.push([0.0, 0.0, 1.0]);
uvs.push([0.5 * (cos + 1.0), 1.0 - 0.5 * (sin + 1.0)]);
}
let mut indices = Vec::with_capacity((sides - 2) * 3);
for i in 1..(sides as u32 - 1) {
// Vertices are generated in CW order above, hence the reversed indices here
// to emit triangle vertices in CCW order.
indices.extend_from_slice(&[0, i + 1, i]);
}
Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
)
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
.with_inserted_indices(Indices::U32(indices))
bevy_math::primitives::RegularPolygon::new(polygon.radius, polygon.sides).mesh()
}
}
/// A circle in the `XY` plane
#[deprecated(
since = "0.13.0",
note = "please use the `Circle` primitive in `bevy_math` instead"
)]
#[derive(Debug, Copy, Clone)]
pub struct Circle {
/// Inscribed radius in the `XY` plane.
@ -111,64 +83,3 @@ impl From<Circle> for Mesh {
Mesh::from(RegularPolygon::from(circle))
}
}
#[cfg(test)]
mod tests {
use crate::mesh::shape::RegularPolygon;
use crate::mesh::{Mesh, VertexAttributeValues};
/// Sin/cos and multiplication computations result in numbers like 0.4999999.
/// Round these to numbers we expect like 0.5.
fn fix_floats<const N: usize>(points: &mut [[f32; N]]) {
for point in points.iter_mut() {
for coord in point.iter_mut() {
let round = (*coord * 2.).round() / 2.;
if (*coord - round).abs() < 0.00001 {
*coord = round;
}
}
}
}
#[test]
fn test_regular_polygon() {
let mut mesh = Mesh::from(RegularPolygon {
radius: 7.,
sides: 4,
});
let Some(VertexAttributeValues::Float32x3(mut positions)) =
mesh.remove_attribute(Mesh::ATTRIBUTE_POSITION)
else {
panic!("Expected positions f32x3");
};
let Some(VertexAttributeValues::Float32x2(mut uvs)) =
mesh.remove_attribute(Mesh::ATTRIBUTE_UV_0)
else {
panic!("Expected uvs f32x2");
};
let Some(VertexAttributeValues::Float32x3(normals)) =
mesh.remove_attribute(Mesh::ATTRIBUTE_NORMAL)
else {
panic!("Expected normals f32x3");
};
fix_floats(&mut positions);
fix_floats(&mut uvs);
assert_eq!(
[
[0.0, 7.0, 0.0],
[7.0, 0.0, 0.0],
[0.0, -7.0, 0.0],
[-7.0, 0.0, 0.0],
],
&positions[..]
);
// Note V coordinate increases in the opposite direction to the Y coordinate.
assert_eq!([[0.5, 0.0], [1.0, 0.5], [0.5, 1.0], [0.0, 0.5]], &uvs[..]);
assert_eq!(&[[0.0, 0.0, 1.0]; 4], &normals[..]);
}
}

View file

@ -1,11 +1,10 @@
use crate::{
mesh::{Indices, Mesh},
render_asset::RenderAssetUsages,
};
use bevy_math::Vec3;
use wgpu::PrimitiveTopology;
use crate::mesh::{Mesh, Meshable};
/// A torus (donut) shape.
#[deprecated(
since = "0.13.0",
note = "please use the `Torus` primitive in `bevy_math` instead"
)]
#[derive(Debug, Clone, Copy)]
pub struct Torus {
pub radius: f32,
@ -27,73 +26,13 @@ impl Default for Torus {
impl From<Torus> for Mesh {
fn from(torus: Torus) -> Self {
// code adapted from http://apparat-engine.blogspot.com/2013/04/procedural-meshes-torus.html
// (source code at https://github.com/SEilers/Apparat)
let n_vertices = (torus.subdivisions_segments + 1) * (torus.subdivisions_sides + 1);
let mut positions: 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 segment_stride = 2.0 * std::f32::consts::PI / torus.subdivisions_segments as f32;
let side_stride = 2.0 * std::f32::consts::PI / torus.subdivisions_sides as f32;
for segment in 0..=torus.subdivisions_segments {
let theta = segment_stride * segment as f32;
for side in 0..=torus.subdivisions_sides {
let phi = side_stride * side as f32;
let position = Vec3::new(
theta.cos() * (torus.radius + torus.ring_radius * phi.cos()),
torus.ring_radius * phi.sin(),
theta.sin() * (torus.radius + torus.ring_radius * phi.cos()),
);
let center = Vec3::new(torus.radius * theta.cos(), 0., torus.radius * theta.sin());
let normal = (position - center).normalize();
positions.push(position.into());
normals.push(normal.into());
uvs.push([
segment as f32 / torus.subdivisions_segments as f32,
side as f32 / torus.subdivisions_sides as f32,
]);
}
bevy_math::primitives::Torus {
minor_radius: torus.ring_radius,
major_radius: torus.radius,
}
let n_faces = (torus.subdivisions_segments) * (torus.subdivisions_sides);
let n_triangles = n_faces * 2;
let n_indices = n_triangles * 3;
let mut indices: Vec<u32> = Vec::with_capacity(n_indices);
let n_vertices_per_row = torus.subdivisions_sides + 1;
for segment in 0..torus.subdivisions_segments {
for side in 0..torus.subdivisions_sides {
let lt = side + segment * n_vertices_per_row;
let rt = (side + 1) + segment * n_vertices_per_row;
let lb = side + (segment + 1) * n_vertices_per_row;
let rb = (side + 1) + (segment + 1) * n_vertices_per_row;
indices.push(lt as u32);
indices.push(rt as u32);
indices.push(lb as u32);
indices.push(rt as u32);
indices.push(rb as u32);
indices.push(lb as u32);
}
}
Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
)
.with_inserted_indices(Indices::U32(indices))
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
.mesh()
.minor_resolution(torus.subdivisions_sides)
.major_resolution(torus.subdivisions_segments)
.build()
}
}

View file

@ -1,12 +1,12 @@
use wgpu::PrimitiveTopology;
use bevy_math::primitives::Sphere;
use crate::{
mesh::{Indices, Mesh},
render_asset::RenderAssetUsages,
};
use std::f32::consts::PI;
use crate::mesh::{Mesh, Meshable};
/// A sphere made of sectors and stacks.
#[deprecated(
since = "0.13.0",
note = "please use the `Sphere` primitive in `bevy_math` instead"
)]
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy)]
pub struct UVSphere {
@ -30,66 +30,8 @@ impl Default for UVSphere {
impl From<UVSphere> for Mesh {
fn from(sphere: UVSphere) -> Self {
// Largely inspired from http://www.songho.ca/opengl/gl_sphere.html
let sectors = sphere.sectors as f32;
let stacks = sphere.stacks as f32;
let length_inv = 1. / sphere.radius;
let sector_step = 2. * PI / sectors;
let stack_step = PI / stacks;
let mut vertices: Vec<[f32; 3]> = Vec::with_capacity(sphere.stacks * sphere.sectors);
let mut normals: Vec<[f32; 3]> = Vec::with_capacity(sphere.stacks * sphere.sectors);
let mut uvs: Vec<[f32; 2]> = Vec::with_capacity(sphere.stacks * sphere.sectors);
let mut indices: Vec<u32> = Vec::with_capacity(sphere.stacks * sphere.sectors * 2 * 3);
for i in 0..sphere.stacks + 1 {
let stack_angle = PI / 2. - (i as f32) * stack_step;
let xy = sphere.radius * stack_angle.cos();
let z = sphere.radius * stack_angle.sin();
for j in 0..sphere.sectors + 1 {
let sector_angle = (j as f32) * sector_step;
let x = xy * sector_angle.cos();
let y = xy * sector_angle.sin();
vertices.push([x, y, z]);
normals.push([x * length_inv, y * length_inv, z * length_inv]);
uvs.push([(j as f32) / sectors, (i as f32) / stacks]);
}
}
// indices
// k1--k1+1
// | / |
// | / |
// k2--k2+1
for i in 0..sphere.stacks {
let mut k1 = i * (sphere.sectors + 1);
let mut k2 = k1 + sphere.sectors + 1;
for _j in 0..sphere.sectors {
if i != 0 {
indices.push(k1 as u32);
indices.push(k2 as u32);
indices.push((k1 + 1) as u32);
}
if i != sphere.stacks - 1 {
indices.push((k1 + 1) as u32);
indices.push(k2 as u32);
indices.push((k2 + 1) as u32);
}
k1 += 1;
k2 += 1;
}
}
Mesh::new(
PrimitiveTopology::TriangleList,
RenderAssetUsages::default(),
)
.with_inserted_indices(Indices::U32(indices))
.with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, vertices)
.with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
.with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
Sphere::new(sphere.radius)
.mesh()
.uv(sphere.sectors, sphere.stacks)
}
}

View file

@ -33,7 +33,7 @@ fn setup_cube(
.with_children(|parent| {
// cube
parent.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
@ -80,7 +80,7 @@ fn setup_cube(
.with_children(|parent| {
// cube
parent.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -48,7 +48,7 @@ fn setup(
// Circle mesh
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::new(100.)).into(),
mesh: meshes.add(Circle::new(100.)).into(),
// 4. Put something bright in a dark environment to see the effect
material: materials.add(Color::rgb(7.5, 0.0, 7.5)),
transform: Transform::from_translation(Vec3::new(-200., 0., 0.)),
@ -57,7 +57,7 @@ fn setup(
// Hexagon mesh
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(shape::RegularPolygon::new(100., 6)).into(),
mesh: meshes.add(RegularPolygon::new(100., 6)).into(),
// 4. Put something bright in a dark environment to see the effect
material: materials.add(Color::rgb(6.25, 9.4, 9.1)),
transform: Transform::from_translation(Vec3::new(200., 0., 0.)),

View file

@ -18,7 +18,7 @@ fn setup(
) {
commands.spawn(Camera2dBundle::default());
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(shape::Quad::default()).into(),
mesh: meshes.add(Rectangle::default()).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(Color::PURPLE),
..default()

View file

@ -24,7 +24,7 @@ fn setup(
// Load the Bevy logo as a texture
let texture_handle = asset_server.load("branding/banner.png");
// Build a default quad mesh
let mut mesh = Mesh::from(shape::Quad::default());
let mut mesh = Mesh::from(Rectangle::default());
// Build vertex colors for the quad. One entry per vertex (the corners of the quad)
let vertex_colors: Vec<[f32; 4]> = vec![
Color::RED.as_rgba_f32(),

View file

@ -83,7 +83,7 @@ fn setup_mesh(
) {
commands.spawn((
MaterialMesh2dBundle {
mesh: meshes.add(shape::Capsule::default()).into(),
mesh: meshes.add(Capsule2d::default()).into(),
transform: Transform::from_xyz(40., 0., 2.).with_scale(Vec3::splat(32.)),
material: materials.add(Color::BLACK),
..default()

View file

@ -91,13 +91,13 @@ fn setup(
});
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -17,14 +17,14 @@ fn setup(
) {
// circular base
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Circle::new(4.0)),
mesh: meshes.add(Circle::new(4.0)),
material: materials.add(Color::WHITE),
transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
material: materials.add(Color::rgb_u8(124, 144, 255)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -56,7 +56,7 @@ fn setup(
// plane
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Plane::from_size(20.)),
mesh: meshes.add(Plane3d::default().mesh().size(20., 20.)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
},

View file

@ -29,7 +29,7 @@ fn setup(
},
));
let cube = meshes.add(shape::Cube { size: 0.5 });
let cube = meshes.add(Cuboid::new(0.5, 0.5, 0.5));
for x in -1..2 {
for z in -1..2 {
commands.spawn(PbrBundle {

View file

@ -260,7 +260,7 @@ fn setup(
) {
// Plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(50.0)),
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
material: materials.add(Color::rgb(0.1, 0.2, 0.1)),
..default()
});
@ -273,7 +273,7 @@ fn setup(
// Cubes
for i in 0..5 {
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 0.25 }),
mesh: meshes.add(Cuboid::new(0.25, 0.25, 0.25)),
material: cube_material.clone(),
transform: Transform::from_xyz(i as f32 * 0.25 - 1.0, 0.125, -i as f32 * 0.5),
..default()

View file

@ -80,7 +80,7 @@ fn setup_terrain_scene(
// Sky
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Box::default()),
mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)),
material: materials.add(StandardMaterial {
base_color: Color::hex("888888").unwrap(),
unlit: true,

View file

@ -37,13 +37,7 @@ fn setup(
asset_server: Res<AssetServer>,
) {
let base_color = Color::rgba(0.9, 0.2, 0.3, 1.0);
let icosphere_mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.9,
subdivisions: 7,
})
.unwrap(),
);
let icosphere_mesh = meshes.add(Sphere::new(0.9).mesh().ico(7).unwrap());
// Opaque
let opaque = commands
@ -149,7 +143,7 @@ fn setup(
let black_material = materials.add(Color::BLACK);
let white_material = materials.add(Color::WHITE);
let plane_mesh = meshes.add(shape::Plane::from_size(2.0));
let plane_mesh = meshes.add(Plane3d::default().mesh().size(2.0, 2.0));
for x in -3..4 {
for z in -3..4 {

View file

@ -55,13 +55,7 @@ fn setup_scene(
..default()
});
let mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.5,
subdivisions: 5,
})
.unwrap(),
);
let mesh = meshes.add(Sphere::new(0.5).mesh().ico(5).unwrap());
for x in -5..5 {
for z in -5..5 {

View file

@ -105,16 +105,13 @@ fn setup(
// Plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(50.0)),
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
material: forward_mat_h.clone(),
..default()
});
let cube_h = meshes.add(shape::Cube { size: 0.1 });
let sphere_h = meshes.add(shape::UVSphere {
radius: 0.125,
..default()
});
let cube_h = meshes.add(Cuboid::new(0.1, 0.1, 0.1));
let sphere_h = meshes.add(Sphere::new(0.125).mesh().uv(32, 18));
// Cubes
commands.spawn(PbrBundle {
@ -198,7 +195,7 @@ fn setup(
// sky
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Box::default()),
mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)),
material: materials.add(StandardMaterial {
base_color: Color::hex("888888").unwrap(),
unlit: true,
@ -259,7 +256,7 @@ fn setup_parallax(
let normal_handle = asset_server.load("textures/parallax_example/cube_normal.png");
normal.0 = Some(normal_handle);
let mut cube: Mesh = shape::Cube { size: 0.15 }.into();
let mut cube = Mesh::from(Cuboid::new(0.15, 0.15, 0.15));
// NOTE: for normal maps and depth maps to work, the mesh
// needs tangents generated.

View file

@ -4,7 +4,6 @@
use bevy::app::App;
use bevy::app::Startup;
use bevy::prelude::shape::Plane;
use bevy::prelude::*;
use bevy::render::deterministic::DeterministicRenderingConfig;
@ -38,7 +37,7 @@ fn setup(
..default()
});
let mesh = meshes.add(Plane::from_size(2.0));
let mesh = meshes.add(Plane3d::default().mesh().size(2.0, 2.0));
let nb_plane = 10;
for i in 0..nb_plane {
let color = Color::hsl(i as f32 * 360.0 / nb_plane as f32, 1.0, 0.5);

View file

@ -58,16 +58,9 @@ fn setup_pyramid_scene(
// pillars
for (x, z) in &[(-1.5, -1.5), (1.5, -1.5), (1.5, 1.5), (-1.5, 1.5)] {
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Box {
min_x: -0.5,
max_x: 0.5,
min_z: -0.5,
max_z: 0.5,
min_y: 0.0,
max_y: 3.0,
}),
mesh: meshes.add(Cuboid::new(1.0, 3.0, 1.0)),
material: stone.clone(),
transform: Transform::from_xyz(*x, 0.0, *z),
transform: Transform::from_xyz(*x, 1.5, *z),
..default()
});
}
@ -75,7 +68,7 @@ fn setup_pyramid_scene(
// orb
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::try_from(shape::Icosphere::default()).unwrap()),
mesh: meshes.add(Sphere::default()),
material: materials.add(StandardMaterial {
base_color: Color::hex("126212CC").unwrap(),
reflectance: 1.0,
@ -94,26 +87,19 @@ fn setup_pyramid_scene(
// steps
for i in 0..50 {
let size = i as f32 / 2.0 + 3.0;
let half_size = i as f32 / 2.0 + 3.0;
let y = -i as f32 / 2.0;
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Box {
min_x: -size,
max_x: size,
min_z: -size,
max_z: size,
min_y: 0.0,
max_y: 0.5,
}),
mesh: meshes.add(Cuboid::new(2.0 * half_size, 0.5, 2.0 * half_size)),
material: stone.clone(),
transform: Transform::from_xyz(0.0, y, 0.0),
transform: Transform::from_xyz(0.0, y + 0.25, 0.0),
..default()
});
}
// sky
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Box::default()),
mesh: meshes.add(Cuboid::new(2.0, 1.0, 1.0)),
material: materials.add(StandardMaterial {
base_color: Color::hex("888888").unwrap(),
unlit: true,

View file

@ -17,7 +17,6 @@ use bevy::core_pipeline::Skybox;
use bevy::math::{uvec3, vec3};
use bevy::pbr::irradiance_volume::IrradianceVolume;
use bevy::pbr::{ExtendedMaterial, MaterialExtension, NotShadowCaster};
use bevy::prelude::shape::{Cube, UVSphere};
use bevy::prelude::*;
use bevy::render::render_resource::{AsBindGroup, ShaderRef, ShaderType};
use bevy::window::PrimaryWindow;
@ -527,8 +526,8 @@ impl FromWorld for ExampleAssets {
let skybox = asset_server.load::<Image>("environment_maps/pisa_specular_rgb9e5_zstd.ktx2");
let mut mesh_assets = world.resource_mut::<Assets<Mesh>>();
let main_sphere = mesh_assets.add(UVSphere::default());
let voxel_cube = mesh_assets.add(Cube::default());
let main_sphere = mesh_assets.add(Sphere::default().mesh().uv(32, 18));
let voxel_cube = mesh_assets.add(Cuboid::default());
let mut standard_material_assets = world.resource_mut::<Assets<StandardMaterial>>();
let main_material = standard_material_assets.add(Color::SILVER);

View file

@ -38,7 +38,7 @@ fn setup(
) {
// ground plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(10.0)),
mesh: meshes.add(Plane3d::default().mesh().size(10.0, 10.0)),
material: materials.add(StandardMaterial {
base_color: Color::WHITE,
perceptual_roughness: 1.0,
@ -51,7 +51,7 @@ fn setup(
let mut transform = Transform::from_xyz(2.5, 2.5, 0.0);
transform.rotate_z(PI / 2.);
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Box::new(5.0, 0.15, 5.0)),
mesh: meshes.add(Cuboid::new(5.0, 0.15, 5.0)),
transform,
material: materials.add(StandardMaterial {
base_color: Color::INDIGO,
@ -64,7 +64,7 @@ fn setup(
let mut transform = Transform::from_xyz(0.0, 2.5, -2.5);
transform.rotate_x(PI / 2.);
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Box::new(5.0, 0.15, 5.0)),
mesh: meshes.add(Cuboid::new(5.0, 0.15, 5.0)),
transform,
material: materials.add(StandardMaterial {
base_color: Color::INDIGO,
@ -79,7 +79,7 @@ fn setup(
transform.rotate_y(PI / 8.);
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Quad::new(Vec2::new(2.0, 0.5))),
mesh: meshes.add(Rectangle::new(2.0, 0.5)),
transform,
material: materials.add(StandardMaterial {
base_color_texture: Some(asset_server.load("branding/bevy_logo_light.png")),
@ -96,7 +96,7 @@ fn setup(
// cube
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(StandardMaterial {
base_color: Color::PINK,
..default()
@ -109,10 +109,7 @@ fn setup(
// sphere
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::UVSphere {
radius: 0.5,
..default()
}),
mesh: meshes.add(Sphere::new(0.5).mesh().uv(32, 18)),
material: materials.add(StandardMaterial {
base_color: Color::LIME_GREEN,
..default()
@ -144,10 +141,7 @@ fn setup(
})
.with_children(|builder| {
builder.spawn(PbrBundle {
mesh: meshes.add(shape::UVSphere {
radius: 0.1,
..default()
}),
mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)),
material: materials.add(StandardMaterial {
base_color: Color::RED,
emissive: Color::rgba_linear(7.13, 0.0, 0.0, 0.0),
@ -175,11 +169,7 @@ fn setup(
.with_children(|builder| {
builder.spawn(PbrBundle {
transform: Transform::from_rotation(Quat::from_rotation_x(PI / 2.0)),
mesh: meshes.add(shape::Capsule {
depth: 0.125,
radius: 0.1,
..default()
}),
mesh: meshes.add(Capsule3d::new(0.1, 0.125)),
material: materials.add(StandardMaterial {
base_color: Color::GREEN,
emissive: Color::rgba_linear(0.0, 7.13, 0.0, 0.0),
@ -204,10 +194,7 @@ fn setup(
})
.with_children(|builder| {
builder.spawn(PbrBundle {
mesh: meshes.add(shape::UVSphere {
radius: 0.1,
..default()
}),
mesh: meshes.add(Sphere::new(0.1).mesh().uv(32, 18)),
material: materials.add(StandardMaterial {
base_color: Color::BLUE,
emissive: Color::rgba_linear(0.0, 0.0, 7.13, 0.0),

View file

@ -29,31 +29,31 @@ fn setup(
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cubes
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(1.5, 0.5, 1.5),
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(1.5, 0.5, -1.5),
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(-1.5, 0.5, 1.5),
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(-1.5, 0.5, -1.5),
..default()

View file

@ -232,22 +232,13 @@ fn setup(
})
.with_children(|commands| {
// represent the light source as a sphere
let mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.05,
subdivisions: 3,
})
.unwrap(),
);
let mesh = meshes.add(Sphere::new(0.05).mesh().ico(3).unwrap());
commands.spawn(PbrBundle { mesh, ..default() });
});
// Plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane {
size: 10.0,
subdivisions: 0,
}),
mesh: meshes.add(Plane3d::default().mesh().size(10.0, 10.0)),
material: materials.add(StandardMaterial {
// standard material derived from dark green, but
// with roughness and reflectance set.
@ -279,7 +270,7 @@ fn setup(
mesh: meshes.add(
// NOTE: for normal maps and depth maps to work, the mesh
// needs tangents generated.
Mesh::from(shape::Cube { size: 1.0 })
Mesh::from(Cuboid::default())
.with_generated_tangents()
.unwrap(),
),
@ -290,7 +281,7 @@ fn setup(
));
let background_cube = meshes.add(
Mesh::from(shape::Cube { size: 40.0 })
Mesh::from(Cuboid::new(40.0, 40.0, 40.0))
.with_generated_tangents()
.unwrap(),
);

View file

@ -28,7 +28,7 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let cube_handle = meshes.add(shape::Cube { size: 2.0 });
let cube_handle = meshes.add(Cuboid::new(2.0, 2.0, 2.0));
let cube_material_handle = materials.add(StandardMaterial {
base_color: Color::rgb(0.8, 0.7, 0.6),
..default()

View file

@ -17,13 +17,7 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) {
let sphere_mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.45,
..default()
})
.unwrap(),
);
let sphere_mesh = meshes.add(Sphere::new(0.45));
// add entities to the world
for y in -2..=2 {
for x in -5..=5 {

View file

@ -122,13 +122,7 @@ fn spawn_sphere(
materials: &mut Assets<StandardMaterial>,
) {
// Create a sphere mesh.
let sphere_mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 1.0,
subdivisions: 7,
})
.unwrap(),
);
let sphere_mesh = meshes.add(Sphere::new(1.0).mesh().ico(7).unwrap());
// Create a sphere.
commands.spawn(PbrBundle {

View file

@ -62,7 +62,7 @@ fn setup(
let image_handle = images.add(image);
let cube_handle = meshes.add(shape::Cube { size: 4.0 });
let cube_handle = meshes.add(Cuboid::new(4.0, 4.0, 4.0));
let cube_material_handle = materials.add(StandardMaterial {
base_color: Color::rgb(0.8, 0.7, 0.6),
reflectance: 0.02,
@ -118,7 +118,7 @@ fn setup(
));
let cube_size = 4.0;
let cube_handle = meshes.add(shape::Box::new(cube_size, cube_size, cube_size));
let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size));
// This material has the texture that has been rendered.
let material_handle = materials.add(StandardMaterial {

View file

@ -42,13 +42,7 @@ fn setup(
perceptual_roughness: 1.0,
..default()
});
let sphere_handle = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: sphere_radius,
..default()
})
.unwrap(),
);
let sphere_handle = meshes.add(Sphere::new(sphere_radius));
let light_transform = Transform::from_xyz(5.0, 5.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y);
commands
@ -113,8 +107,9 @@ fn setup(
}
// ground plane
let plane_size = 2.0 * spawn_plane_depth;
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(2.0 * spawn_plane_depth)),
mesh: meshes.add(Plane3d::default().mesh().size(plane_size, plane_size)),
material: white_handle,
..default()
});

View file

@ -36,13 +36,7 @@ fn setup(
perceptual_roughness: 1.0,
..default()
});
let sphere_handle = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: sphere_radius,
..default()
})
.unwrap(),
);
let sphere_handle = meshes.add(Sphere::new(sphere_radius));
// sphere - initially a caster
commands.spawn(PbrBundle {
@ -66,7 +60,7 @@ fn setup(
// floating plane - initially not a shadow receiver and not a caster
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Plane::from_size(20.0)),
mesh: meshes.add(Plane3d::default().mesh().size(20.0, 20.0)),
material: materials.add(Color::GREEN),
transform: Transform::from_xyz(0.0, 1.0, -10.0),
..default()
@ -77,7 +71,7 @@ fn setup(
// lower ground plane - initially a shadow receiver
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(20.0)),
mesh: meshes.add(Plane3d::default().mesh().size(20.0, 20.0)),
material: white_handle,
..default()
});

View file

@ -22,7 +22,7 @@ fn setup(
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(100.0)),
mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
material: materials.add(StandardMaterial {
base_color: Color::rgb(0.2, 0.2, 0.2),
perceptual_roughness: 0.08,
@ -36,11 +36,7 @@ fn setup(
let radius_range = 0.0..0.4;
let pos_len = position_range.end - position_range.start;
let radius_len = radius_range.end - radius_range.start;
let mesh = meshes.add(shape::UVSphere {
sectors: 128,
stacks: 64,
..default()
});
let mesh = meshes.add(Sphere::new(0.5).mesh().uv(120, 64));
for i in 0..COUNT {
let percent = i as f32 / COUNT as f32;

View file

@ -23,7 +23,7 @@ fn setup(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(100.0)),
mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});

View file

@ -36,14 +36,14 @@ fn setup(
) {
// ground plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(100.0)),
mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
material: materials.add(Color::WHITE),
..default()
});
// cubes
let mut rng = StdRng::seed_from_u64(19878367467713);
let cube_mesh = meshes.add(shape::Cube { size: 0.5 });
let cube_mesh = meshes.add(Cuboid::new(0.5, 0.5, 0.5));
let blue = materials.add(Color::rgb_u8(124, 144, 255));
for _ in 0..40 {
let x = rng.gen_range(-5.0..5.0);
@ -60,14 +60,8 @@ fn setup(
));
}
let sphere_mesh = meshes.add(shape::UVSphere {
radius: 0.05,
..default()
});
let sphere_mesh_direction = meshes.add(shape::UVSphere {
radius: 0.1,
..default()
});
let sphere_mesh = meshes.add(Sphere::new(0.05).mesh().uv(32, 18));
let sphere_mesh_direction = meshes.add(Sphere::new(0.1).mesh().uv(32, 18));
let red_emissive = materials.add(StandardMaterial {
base_color: Color::RED,
emissive: Color::rgba_linear(100.0, 0.0, 0.0, 0.0),

View file

@ -48,30 +48,26 @@ fn setup(
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: material.clone(),
transform: Transform::from_xyz(0.0, 0.0, 1.0),
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: material.clone(),
transform: Transform::from_xyz(0.0, -1.0, 0.0),
..default()
});
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material,
transform: Transform::from_xyz(1.0, 0.0, 0.0),
..default()
});
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::UVSphere {
radius: 0.4,
sectors: 72,
stacks: 36,
}),
mesh: meshes.add(Sphere::new(0.4).mesh().uv(72, 36)),
material: materials.add(StandardMaterial {
base_color: Color::rgb(0.4, 0.4, 0.4),
perceptual_roughness: 1.0,

View file

@ -24,7 +24,7 @@ fn setup(
// create a new quad mesh. this is what we will apply the texture to
let quad_width = 8.0;
let quad_handle = meshes.add(shape::Quad::new(Vec2::new(quad_width, quad_width * aspect)));
let quad_handle = meshes.add(Rectangle::new(quad_width, quad_width * aspect));
// this material renders the texture normally
let material_handle = materials.add(StandardMaterial {

View file

@ -2,7 +2,6 @@
use bevy::{
core_pipeline::tonemapping::Tonemapping,
math::vec2,
pbr::CascadeShadowConfigBuilder,
prelude::*,
reflect::TypePath,
@ -109,7 +108,7 @@ fn setup_basic_scene(
// plane
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Plane::from_size(50.0)),
mesh: meshes.add(Plane3d::default().mesh().size(50.0, 50.0)),
material: materials.add(Color::rgb(0.1, 0.2, 0.1)),
..default()
},
@ -122,7 +121,7 @@ fn setup_basic_scene(
..default()
});
let cube_mesh = meshes.add(shape::Cube { size: 0.25 });
let cube_mesh = meshes.add(Cuboid::new(0.25, 0.25, 0.25));
for i in 0..5 {
commands.spawn((
PbrBundle {
@ -136,10 +135,7 @@ fn setup_basic_scene(
}
// spheres
let sphere_mesh = meshes.add(shape::UVSphere {
radius: 0.125,
..default()
});
let sphere_mesh = meshes.add(Sphere::new(0.125).mesh().uv(32, 18));
for i in 0..6 {
let j = i % 3;
let s_val = if i < 3 { 0.0 } else { 0.2 };
@ -228,10 +224,7 @@ fn setup_color_gradient_scene(
commands.spawn((
MaterialMeshBundle {
mesh: meshes.add(shape::Quad {
size: vec2(1.0, 1.0) * 0.7,
flip: false,
}),
mesh: meshes.add(Rectangle::new(0.7, 0.7)),
material: materials.add(ColorGradientMaterial {}),
transform,
visibility: Visibility::Hidden,
@ -253,10 +246,7 @@ fn setup_image_viewer_scene(
// exr/hdr viewer (exr requires enabling bevy feature)
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Quad {
size: vec2(1.0, 1.0),
flip: false,
}),
mesh: meshes.add(Rectangle::default()),
material: materials.add(StandardMaterial {
base_color_texture: None,
unlit: true,
@ -353,7 +343,7 @@ fn resize_image(
let size = image_changed.size_f32().normalize_or_zero() * 1.4;
// Resize Mesh
let quad = Mesh::from(shape::Quad::new(size));
let quad = Mesh::from(Rectangle::from_size(size));
meshes.insert(mesh_h, quad);
}
}

View file

@ -68,24 +68,10 @@ fn setup(
mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
) {
let icosphere_mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.9,
subdivisions: 7,
})
.unwrap(),
);
let cube_mesh = meshes.add(shape::Cube { size: 0.7 });
let plane_mesh = meshes.add(shape::Plane::from_size(2.0));
let cylinder_mesh = meshes.add(shape::Cylinder {
radius: 0.5,
height: 2.0,
resolution: 50,
segments: 1,
});
let icosphere_mesh = meshes.add(Sphere::new(0.9).mesh().ico(7).unwrap());
let cube_mesh = meshes.add(Cuboid::new(0.7, 0.7, 0.7));
let plane_mesh = meshes.add(Plane3d::default().mesh().size(2.0, 2.0));
let cylinder_mesh = meshes.add(Cylinder::new(0.5, 2.0).mesh().resolution(50));
// Cube #1
commands.spawn((

View file

@ -20,19 +20,13 @@ fn setup(
) {
// opaque plane, uses `alpha_mode: Opaque` by default
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(6.0)),
mesh: meshes.add(Plane3d::default().mesh().size(6.0, 6.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// transparent sphere, uses `alpha_mode: Mask(f32)`
commands.spawn(PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()),
material: materials.add(StandardMaterial {
// Alpha channel of the color controls transparency.
// We set it to 0.0 here, because it will be changed over time in the
@ -49,13 +43,7 @@ fn setup(
});
// transparent unlit sphere, uses `alpha_mode: Mask(f32)`
commands.spawn(PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()),
material: materials.add(StandardMaterial {
base_color: Color::rgba(0.2, 0.7, 0.1, 0.0),
alpha_mode: AlphaMode::Mask(0.5),
@ -67,7 +55,7 @@ fn setup(
});
// transparent cube, uses `alpha_mode: Blend`
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
// Notice how there is no need to set the `alpha_mode` explicitly here.
// When converting a color to a material using `into()`, the alpha mode is
// automatically set to `Blend` if the alpha channel is anything lower than 1.0.
@ -77,13 +65,7 @@ fn setup(
});
// opaque sphere
commands.spawn(PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(0.5).mesh().ico(3).unwrap()),
material: materials.add(Color::rgb(0.7, 0.2, 0.1)),
transform: Transform::from_xyz(0.0, 0.5, -1.5),
..default()

View file

@ -17,13 +17,13 @@ fn setup(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -17,13 +17,13 @@ fn setup(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cube
// Assign vertex colors based on vertex positions
let mut colorful_cube = Mesh::from(shape::Cube { size: 1.0 });
let mut colorful_cube = Mesh::from(Cuboid::default());
if let Some(VertexAttributeValues::Float32x3(positions)) =
colorful_cube.attribute(Mesh::ATTRIBUTE_POSITION)
{

View file

@ -54,7 +54,7 @@ fn setup(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::BLUE),
..default()
});
@ -62,7 +62,7 @@ fn setup(
// Red cube: Never renders a wireframe
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::RED),
transform: Transform::from_xyz(-1.0, 0.5, -1.0),
..default()
@ -71,7 +71,7 @@ fn setup(
));
// Orange cube: Follows global wireframe setting
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::ORANGE),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
@ -79,7 +79,7 @@ fn setup(
// Green cube: Always renders a wireframe
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::GREEN),
transform: Transform::from_xyz(1.0, 0.5, 1.0),
..default()

View file

@ -45,7 +45,7 @@ fn setup(
// Plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(500000.0)),
mesh: meshes.add(Plane3d::default().mesh().size(500000.0, 500000.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});

View file

@ -122,7 +122,7 @@ fn setup(
commands
.spawn((
PbrBundle {
mesh: meshes.add(Mesh::try_from(shape::Icosphere::default()).unwrap()),
mesh: meshes.add(Sphere::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
..default()
},
@ -142,7 +142,7 @@ fn setup(
p.spawn((
PbrBundle {
transform: Transform::from_xyz(1.5, 0.0, 0.0),
mesh: meshes.add(shape::Cube { size: 0.5 }),
mesh: meshes.add(Cuboid::new(0.5, 0.5, 0.5)),
material: materials.add(Color::rgb(0.3, 0.9, 0.3)),
..default()
},

View file

@ -38,7 +38,7 @@ fn setup(
// Spawning a cube to experiment on
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube::default()),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::ORANGE),
transform: Transform::from_translation(points[0][0]),
..default()
@ -60,7 +60,7 @@ fn setup(
// ground plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(50.)),
mesh: meshes.add(Plane3d::default().mesh().size(50., 50.)),
material: materials.add(Color::SILVER),
..default()
});

View file

@ -35,7 +35,7 @@ fn add_assets(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let box_mesh_handle = meshes.add(shape::Cube { size: 0.25 });
let box_mesh_handle = meshes.add(Cuboid::new(0.25, 0.25, 0.25));
commands.insert_resource(BoxMeshHandle(box_mesh_handle));
let box_material_handle = materials.add(Color::rgb(1.0, 0.2, 0.3));

View file

@ -34,7 +34,7 @@ fn setup(
// sound emitter
commands.spawn((
MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::new(15.0)).into(),
mesh: meshes.add(Circle::new(15.0)).into(),
material: materials.add(Color::BLUE),
transform: Transform::from_translation(Vec3::new(0.0, 50.0, 0.0)),
..default()

View file

@ -22,10 +22,7 @@ fn setup(
// sound emitter
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::UVSphere {
radius: 0.2,
..default()
}),
mesh: meshes.add(Sphere::new(0.2).mesh().uv(32, 18)),
material: materials.add(Color::BLUE),
transform: Transform::from_xyz(0.0, 0.0, 0.0),
..default()
@ -43,7 +40,7 @@ fn setup(
.with_children(|parent| {
// left ear indicator
parent.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 0.2 }),
mesh: meshes.add(Cuboid::new(0.2, 0.2, 0.2)),
material: materials.add(Color::RED),
transform: Transform::from_translation(listener.left_ear_offset),
..default()
@ -51,7 +48,7 @@ fn setup(
// right ear indicator
parent.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 0.2 }),
mesh: meshes.add(Cuboid::new(0.2, 0.2, 0.2)),
material: materials.add(Color::GREEN),
transform: Transform::from_translation(listener.right_ear_offset),
..default()

View file

@ -43,13 +43,7 @@ fn generate_bodies(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
let mesh = meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 1.0,
subdivisions: 3,
})
.unwrap(),
);
let mesh = meshes.add(Sphere::new(1.0).mesh().ico(3).unwrap());
let color_range = 0.5..1.0;
let vel_range = -0.5..0.5;
@ -103,13 +97,7 @@ fn generate_bodies(
BodyBundle {
pbr: PbrBundle {
transform: Transform::from_scale(Vec3::splat(star_radius)),
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 1.0,
subdivisions: 5,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(1.0).mesh().ico(5).unwrap()),
material: materials.add(StandardMaterial {
base_color: Color::ORANGE_RED,
emissive: (Color::ORANGE_RED * 18.),

View file

@ -218,7 +218,7 @@ fn setup(
// Ball
commands.spawn((
MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::default()).into(),
mesh: meshes.add(Circle::default()).into(),
material: materials.add(BALL_COLOR),
transform: Transform::from_translation(BALL_STARTING_POSITION)
.with_scale(Vec2::splat(BALL_DIAMETER).extend(1.)),

View file

@ -64,26 +64,20 @@ fn setup_scene(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.1, 0.2, 0.1)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.5, 0.4, 0.3)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()
});
// sphere
commands.spawn(PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
subdivisions: 4,
radius: 0.5,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(0.5).mesh().ico(4).unwrap()),
material: materials.add(Color::rgb(0.1, 0.4, 0.8)),
transform: Transform::from_xyz(1.5, 1.5, 1.5),
..default()

View file

@ -21,7 +21,7 @@ fn setup(
) {
// cube
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(CustomMaterial {}),
..default()

View file

@ -78,7 +78,7 @@ fn create_array_texture(
image.reinterpret_stacked_2d_as_array(array_layers);
// Spawn some cubes using the array texture
let mesh_handle = meshes.add(shape::Cube { size: 1.0 });
let mesh_handle = meshes.add(Cuboid::default());
let material_handle = materials.add(ArrayTextureMaterial {
array_texture: loading_texture.handle.clone(),
});

View file

@ -31,7 +31,7 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<CustomMaterial>>,
) {
let mesh = Mesh::from(shape::Cube { size: 1.0 })
let mesh = Mesh::from(Cuboid::default())
// Sets the custom attribute
.with_inserted_attribute(
ATTRIBUTE_BLEND_COLOR,

View file

@ -24,13 +24,7 @@ fn setup(
) {
// sphere
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 1.0,
subdivisions: 5,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(1.0)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(ExtendedMaterial {
base: StandardMaterial {

View file

@ -27,7 +27,7 @@ fn setup(
mut materials: ResMut<Assets<FallbackTestMaterial>>,
) {
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(FallbackTestMaterial {
image_1d: None,
image_2d: None,

View file

@ -325,7 +325,7 @@ fn setup(
// cube
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -27,7 +27,7 @@ fn setup(
) {
// blue cube
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
transform: Transform::from_xyz(-1.0, 0.5, 0.0),
material: materials.add(CustomMaterial {
color: Color::BLUE,
@ -38,7 +38,7 @@ fn setup(
// red cube (with green color overridden by the IS_RED "shader def")
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
transform: Transform::from_xyz(1.0, 0.5, 0.0),
material: materials.add(CustomMaterial {
color: Color::GREEN,

View file

@ -35,7 +35,7 @@ fn main() {
fn setup(mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>) {
commands.spawn((
meshes.add(shape::Cube { size: 0.5 }),
meshes.add(Cuboid::new(0.5, 0.5, 0.5)),
SpatialBundle::INHERITED_IDENTITY,
InstanceMaterialData(
(1..=10)

View file

@ -22,7 +22,7 @@ fn setup(
) {
// cube
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(CustomMaterial {
color: Color::BLUE,

View file

@ -29,7 +29,7 @@ fn setup(
// quad
commands.spawn(MaterialMesh2dBundle {
mesh: meshes.add(shape::Quad::default()).into(),
mesh: meshes.add(Rectangle::default()).into(),
transform: Transform::default().with_scale(Vec3::splat(128.)),
material: materials.add(CustomMaterial {
color: Color::BLUE,

View file

@ -28,7 +28,7 @@ fn setup(
) {
// cube
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: materials.add(CustomMaterial {
color: Color::BLUE,

View file

@ -25,7 +25,7 @@ fn setup(
mut standard_materials: ResMut<Assets<StandardMaterial>>,
) {
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: standard_materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
@ -39,7 +39,7 @@ fn setup(
});
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
material: custom_materials.add(CustomMaterial {
texture: asset_server.load(

View file

@ -61,7 +61,7 @@ fn setup(
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: std_materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
@ -71,7 +71,7 @@ fn setup(
// For a real application, this isn't ideal.
commands.spawn((
MaterialMeshBundle {
mesh: meshes.add(shape::Quad::new(Vec2::new(20.0, 20.0))),
mesh: meshes.add(Rectangle::new(20.0, 20.0)),
material: depth_materials.add(PrepassOutputMaterial {
settings: ShowPrepassSettings::default(),
}),
@ -85,7 +85,7 @@ fn setup(
// Opaque cube
commands.spawn((
MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(CustomMaterial {
color: Color::WHITE,
color_texture: Some(asset_server.load("branding/icon.png")),
@ -99,7 +99,7 @@ fn setup(
// Cube with alpha mask
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: std_materials.add(StandardMaterial {
alpha_mode: AlphaMode::Mask(1.0),
base_color_texture: Some(asset_server.load("branding/icon.png")),
@ -112,7 +112,7 @@ fn setup(
// Cube with alpha blending.
// Transparent materials are ignored by the prepass
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(CustomMaterial {
color: Color::WHITE,
color_texture: Some(asset_server.load("branding/icon.png")),

View file

@ -74,7 +74,7 @@ fn setup(
// a cube with multiple textures
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(BindlessMaterial { textures }),
..default()
});

View file

@ -218,7 +218,7 @@ fn setup(
textures,
materials,
quad: meshes
.add(shape::Quad::new(Vec2::splat(BIRD_TEXTURE_SIZE as f32)))
.add(Rectangle::from_size(Vec2::splat(BIRD_TEXTURE_SIZE as f32)))
.into(),
color_rng: StdRng::seed_from_u64(42),
material_rng: StdRng::seed_from_u64(42),

View file

@ -113,7 +113,7 @@ fn setup(
let images = images.into_inner();
let material_assets = material_assets.into_inner();
let mesh = meshes.add(shape::Cube { size: 1.0 });
let mesh = meshes.add(Cuboid::default());
let material_textures = init_textures(args, images);
let materials = init_materials(args, &material_textures, material_assets);

View file

@ -194,7 +194,7 @@ fn setup(
// Plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5000.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5000.0, 5000.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});

View file

@ -53,19 +53,13 @@ fn setup(
const N_LIGHTS: usize = 100_000;
commands.spawn(PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: RADIUS,
subdivisions: 9,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(RADIUS).mesh().ico(9).unwrap()),
material: materials.add(Color::WHITE),
transform: Transform::from_scale(Vec3::NEG_ONE),
..default()
});
let mesh = meshes.add(shape::Cube { size: 1.0 });
let mesh = meshes.add(Cuboid::default());
let material = materials.add(StandardMaterial {
base_color: Color::PINK,
..default()

View file

@ -70,12 +70,10 @@ impl FromWorld for ButtonMeshes {
fn from_world(world: &mut World) -> Self {
let mut meshes = world.resource_mut::<Assets<Mesh>>();
Self {
circle: meshes.add(shape::Circle::new(BUTTON_RADIUS)).into(),
triangle: meshes
.add(shape::RegularPolygon::new(BUTTON_RADIUS, 3))
.into(),
start_pause: meshes.add(shape::Quad::new(START_SIZE)).into(),
trigger: meshes.add(shape::Quad::new(TRIGGER_SIZE)).into(),
circle: meshes.add(Circle::new(BUTTON_RADIUS)).into(),
triangle: meshes.add(RegularPolygon::new(BUTTON_RADIUS, 3)).into(),
start_pause: meshes.add(Rectangle::from_size(START_SIZE)).into(),
trigger: meshes.add(Rectangle::from_size(TRIGGER_SIZE)).into(),
}
}
}

View file

@ -26,7 +26,7 @@ fn setup(
// Spawn a cube to rotate.
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::WHITE),
transform: Transform::from_translation(Vec3::ZERO),
..default()

View file

@ -42,7 +42,7 @@ fn setup(
// Spawn a cube to scale.
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::WHITE),
transform: Transform::from_rotation(Quat::from_rotation_y(PI / 4.0)),
..default()

View file

@ -46,13 +46,7 @@ fn setup(
// Add an object (sphere) for visualizing scaling.
commands.spawn((
PbrBundle {
mesh: meshes.add(
Mesh::try_from(shape::Icosphere {
radius: 3.0,
subdivisions: 32,
})
.unwrap(),
),
mesh: meshes.add(Sphere::new(3.0).mesh().ico(32).unwrap()),
material: materials.add(Color::YELLOW),
transform: Transform::from_translation(Vec3::ZERO),
..default()
@ -73,7 +67,7 @@ fn setup(
Transform::from_translation(Vec3::Z * -10.0).with_rotation(Quat::from_rotation_y(PI / 2.));
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::WHITE),
transform: cube_spawn,
..default()

View file

@ -40,7 +40,7 @@ fn setup(
let entity_spawn = Vec3::ZERO;
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::WHITE),
transform: Transform::from_translation(entity_spawn),
..default()

View file

@ -109,7 +109,7 @@ fn setup(
});
let cube_size = 4.0;
let cube_handle = meshes.add(Mesh::from(shape::Box::new(cube_size, cube_size, cube_size)));
let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size));
// This material has the texture that has been rendered.
let material_handle = materials.add(StandardMaterial {

View file

@ -150,7 +150,7 @@ pub(crate) mod test_setup {
) {
commands.spawn((
PbrBundle {
mesh: meshes.add(shape::Cube { size: 0.5 }),
mesh: meshes.add(Cuboid::new(0.5, 0.5, 0.5)),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
..default()
},

View file

@ -35,13 +35,13 @@ fn setup(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane::from_size(5.0)),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -35,16 +35,13 @@ fn setup_3d(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane {
size: 5.0,
subdivisions: 0,
}),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()

View file

@ -118,16 +118,13 @@ fn setup_3d(
) {
// plane
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Plane {
size: 5.0,
subdivisions: 0,
}),
mesh: meshes.add(Plane3d::default().mesh().size(5.0, 5.0)),
material: materials.add(Color::rgb(0.3, 0.5, 0.3)),
..default()
});
// cube
commands.spawn(PbrBundle {
mesh: meshes.add(shape::Cube { size: 1.0 }),
mesh: meshes.add(Cuboid::default()),
material: materials.add(Color::rgb(0.8, 0.7, 0.6)),
transform: Transform::from_xyz(0.0, 0.5, 0.0),
..default()