1use crate::{Indices, Mesh, MeshBuilder, Meshable, PrimitiveTopology};
2use bevy_asset::RenderAssetUsages;
3use bevy_math::{primitives::Cuboid, Vec3};
4use bevy_reflect::prelude::*;
5
6#[derive(Clone, Copy, Debug, Reflect)]
8#[reflect(Default, Debug, Clone)]
9pub struct CuboidMeshBuilder {
10 half_size: Vec3,
11}
12
13impl Default for CuboidMeshBuilder {
14 fn default() -> Self {
16 Self {
17 half_size: Vec3::splat(0.5),
18 }
19 }
20}
21
22impl MeshBuilder for CuboidMeshBuilder {
23 fn build(&self) -> Mesh {
24 let min = -self.half_size;
25 let max = self.half_size;
26
27 let vertices = &[
29 ([min.x, min.y, max.z], [0.0, 0.0, 1.0], [0.0, 0.0]),
31 ([max.x, min.y, max.z], [0.0, 0.0, 1.0], [1.0, 0.0]),
32 ([max.x, max.y, max.z], [0.0, 0.0, 1.0], [1.0, 1.0]),
33 ([min.x, max.y, max.z], [0.0, 0.0, 1.0], [0.0, 1.0]),
34 ([min.x, max.y, min.z], [0.0, 0.0, -1.0], [1.0, 0.0]),
36 ([max.x, max.y, min.z], [0.0, 0.0, -1.0], [0.0, 0.0]),
37 ([max.x, min.y, min.z], [0.0, 0.0, -1.0], [0.0, 1.0]),
38 ([min.x, min.y, min.z], [0.0, 0.0, -1.0], [1.0, 1.0]),
39 ([max.x, min.y, min.z], [1.0, 0.0, 0.0], [0.0, 0.0]),
41 ([max.x, max.y, min.z], [1.0, 0.0, 0.0], [1.0, 0.0]),
42 ([max.x, max.y, max.z], [1.0, 0.0, 0.0], [1.0, 1.0]),
43 ([max.x, min.y, max.z], [1.0, 0.0, 0.0], [0.0, 1.0]),
44 ([min.x, min.y, max.z], [-1.0, 0.0, 0.0], [1.0, 0.0]),
46 ([min.x, max.y, max.z], [-1.0, 0.0, 0.0], [0.0, 0.0]),
47 ([min.x, max.y, min.z], [-1.0, 0.0, 0.0], [0.0, 1.0]),
48 ([min.x, min.y, min.z], [-1.0, 0.0, 0.0], [1.0, 1.0]),
49 ([max.x, max.y, min.z], [0.0, 1.0, 0.0], [1.0, 0.0]),
51 ([min.x, max.y, min.z], [0.0, 1.0, 0.0], [0.0, 0.0]),
52 ([min.x, max.y, max.z], [0.0, 1.0, 0.0], [0.0, 1.0]),
53 ([max.x, max.y, max.z], [0.0, 1.0, 0.0], [1.0, 1.0]),
54 ([max.x, min.y, max.z], [0.0, -1.0, 0.0], [0.0, 0.0]),
56 ([min.x, min.y, max.z], [0.0, -1.0, 0.0], [1.0, 0.0]),
57 ([min.x, min.y, min.z], [0.0, -1.0, 0.0], [1.0, 1.0]),
58 ([max.x, min.y, min.z], [0.0, -1.0, 0.0], [0.0, 1.0]),
59 ];
60
61 let positions: Vec<_> = vertices.iter().map(|(p, _, _)| *p).collect();
62 let normals: Vec<_> = vertices.iter().map(|(_, n, _)| *n).collect();
63 let uvs: Vec<_> = vertices.iter().map(|(_, _, uv)| *uv).collect();
64
65 let indices = Indices::U32(vec![
66 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9, 10, 10, 11, 8, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22, 23, 20, ]);
73
74 Mesh::new(
75 PrimitiveTopology::TriangleList,
76 RenderAssetUsages::default(),
77 )
78 .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, positions)
79 .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, normals)
80 .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, uvs)
81 .with_inserted_indices(indices)
82 }
83}
84
85impl Meshable for Cuboid {
86 type Output = CuboidMeshBuilder;
87
88 fn mesh(&self) -> Self::Output {
89 CuboidMeshBuilder {
90 half_size: self.half_size,
91 }
92 }
93}
94
95impl From<Cuboid> for Mesh {
96 fn from(cuboid: Cuboid) -> Self {
97 cuboid.mesh().build()
98 }
99}