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