Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_mesh/src/primitives/dim3/cuboid.rs
6598 views
1
use crate::{Indices, Mesh, MeshBuilder, Meshable, PrimitiveTopology};
2
use bevy_asset::RenderAssetUsages;
3
use bevy_math::{primitives::Cuboid, Vec3};
4
use bevy_reflect::prelude::*;
5
6
/// A builder used for creating a [`Mesh`] with a [`Cuboid`] shape.
7
#[derive(Clone, Copy, Debug, Reflect)]
8
#[reflect(Default, Debug, Clone)]
9
pub struct CuboidMeshBuilder {
10
half_size: Vec3,
11
}
12
13
impl Default for CuboidMeshBuilder {
14
/// Returns the default [`CuboidMeshBuilder`] with a width, height, and depth of `1.0`.
15
fn default() -> Self {
16
Self {
17
half_size: Vec3::splat(0.5),
18
}
19
}
20
}
21
22
impl MeshBuilder for CuboidMeshBuilder {
23
fn build(&self) -> Mesh {
24
let min = -self.half_size;
25
let max = self.half_size;
26
27
// Suppose Y-up right hand, and camera look from +Z to -Z
28
let vertices = &[
29
// Front
30
([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
// Back
35
([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
// Right
40
([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
// Left
45
([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
// Top
50
([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
// Bottom
55
([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, // front
67
4, 5, 6, 6, 7, 4, // back
68
8, 9, 10, 10, 11, 8, // right
69
12, 13, 14, 14, 15, 12, // left
70
16, 17, 18, 18, 19, 16, // top
71
20, 21, 22, 22, 23, 20, // bottom
72
]);
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
85
impl 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
95
impl From<Cuboid> for Mesh {
96
fn from(cuboid: Cuboid) -> Self {
97
cuboid.mesh().build()
98
}
99
}
100
101