bevy_mesh/primitives/dim3/
cuboid.rs

1use crate::{Indices, Mesh, MeshBuilder, Meshable};
2use bevy_asset::RenderAssetUsages;
3use bevy_math::{primitives::Cuboid, Vec3};
4use wgpu::PrimitiveTopology;
5
6/// A builder used for creating a [`Mesh`] with a [`Cuboid`] shape.
7pub struct CuboidMeshBuilder {
8    half_size: Vec3,
9}
10
11impl MeshBuilder for CuboidMeshBuilder {
12    fn build(&self) -> Mesh {
13        let min = -self.half_size;
14        let max = self.half_size;
15
16        // Suppose Y-up right hand, and camera look from +Z to -Z
17        let vertices = &[
18            // Front
19            ([min.x, min.y, max.z], [0.0, 0.0, 1.0], [0.0, 0.0]),
20            ([max.x, min.y, max.z], [0.0, 0.0, 1.0], [1.0, 0.0]),
21            ([max.x, max.y, max.z], [0.0, 0.0, 1.0], [1.0, 1.0]),
22            ([min.x, max.y, max.z], [0.0, 0.0, 1.0], [0.0, 1.0]),
23            // Back
24            ([min.x, max.y, min.z], [0.0, 0.0, -1.0], [1.0, 0.0]),
25            ([max.x, max.y, min.z], [0.0, 0.0, -1.0], [0.0, 0.0]),
26            ([max.x, min.y, min.z], [0.0, 0.0, -1.0], [0.0, 1.0]),
27            ([min.x, min.y, min.z], [0.0, 0.0, -1.0], [1.0, 1.0]),
28            // Right
29            ([max.x, min.y, min.z], [1.0, 0.0, 0.0], [0.0, 0.0]),
30            ([max.x, max.y, min.z], [1.0, 0.0, 0.0], [1.0, 0.0]),
31            ([max.x, max.y, max.z], [1.0, 0.0, 0.0], [1.0, 1.0]),
32            ([max.x, min.y, max.z], [1.0, 0.0, 0.0], [0.0, 1.0]),
33            // Left
34            ([min.x, min.y, max.z], [-1.0, 0.0, 0.0], [1.0, 0.0]),
35            ([min.x, max.y, max.z], [-1.0, 0.0, 0.0], [0.0, 0.0]),
36            ([min.x, max.y, min.z], [-1.0, 0.0, 0.0], [0.0, 1.0]),
37            ([min.x, min.y, min.z], [-1.0, 0.0, 0.0], [1.0, 1.0]),
38            // Top
39            ([max.x, max.y, min.z], [0.0, 1.0, 0.0], [1.0, 0.0]),
40            ([min.x, max.y, min.z], [0.0, 1.0, 0.0], [0.0, 0.0]),
41            ([min.x, max.y, max.z], [0.0, 1.0, 0.0], [0.0, 1.0]),
42            ([max.x, max.y, max.z], [0.0, 1.0, 0.0], [1.0, 1.0]),
43            // Bottom
44            ([max.x, min.y, max.z], [0.0, -1.0, 0.0], [0.0, 0.0]),
45            ([min.x, min.y, max.z], [0.0, -1.0, 0.0], [1.0, 0.0]),
46            ([min.x, min.y, min.z], [0.0, -1.0, 0.0], [1.0, 1.0]),
47            ([max.x, min.y, min.z], [0.0, -1.0, 0.0], [0.0, 1.0]),
48        ];
49
50        let positions: Vec<_> = vertices.iter().map(|(p, _, _)| *p).collect();
51        let normals: Vec<_> = vertices.iter().map(|(_, n, _)| *n).collect();
52        let uvs: Vec<_> = vertices.iter().map(|(_, _, uv)| *uv).collect();
53
54        let indices = Indices::U32(vec![
55            0, 1, 2, 2, 3, 0, // front
56            4, 5, 6, 6, 7, 4, // back
57            8, 9, 10, 10, 11, 8, // right
58            12, 13, 14, 14, 15, 12, // left
59            16, 17, 18, 18, 19, 16, // top
60            20, 21, 22, 22, 23, 20, // bottom
61        ]);
62
63        Mesh::new(
64            PrimitiveTopology::TriangleList,
65            RenderAssetUsages::default(),
66        )
67        .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions)
68        .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
69        .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
70        .with_inserted_indices(indices)
71    }
72}
73
74impl Meshable for Cuboid {
75    type Output = CuboidMeshBuilder;
76
77    fn mesh(&self) -> Self::Output {
78        CuboidMeshBuilder {
79            half_size: self.half_size,
80        }
81    }
82}
83
84impl From<Cuboid> for Mesh {
85    fn from(cuboid: Cuboid) -> Self {
86        cuboid.mesh().build()
87    }
88}