bevy_render/mesh/primitives/dim3/
cuboid.rs

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