mraphics_core/geometry/
cube.rs1use crate::{Geometry, GeometryIndices, Material, Mesh, Representable, Transformable, Vertices};
2use nalgebra::Vector3;
3
4#[derive(Clone)]
5pub struct Cube {
6 pub width: f32,
7 pub height: f32,
8 pub depth: f32,
9
10 pub vertices: Vertices,
11}
12
13impl Cube {
14 pub fn new() -> Self {
15 Self::default()
16 }
17}
18
19impl Default for Cube {
20 fn default() -> Self {
21 Self {
22 width: 1.0,
23 height: 1.0,
24 depth: 1.0,
25
26 vertices: Vertices::new(),
27 }
28 }
29}
30
31impl Geometry for Cube {
32 fn init_view(&self, view: &mut super::GeometryView) {
33 view.add_attribute(
34 crate::constants::POSITION_ATTR_LABEL,
35 crate::constants::POSITION_ATTR_INDEX,
36 bytemuck::cast_slice::<f32, u8>(&self.vertices.data.concat()).to_vec(),
37 );
38 }
39
40 fn update_view(&self, view: &mut super::GeometryView) {
41 self.vertices.update_geometry_view(view);
42 view.indices = GeometryIndices::Sequential(self.vertices.data.len() as u32);
43 }
44
45 fn update(&mut self) {
46 let vertices = &mut self.vertices.data;
47
48 fn to_homogeneous(point: &Vector3<f32>, w: f32) -> [f32; 4] {
49 std::array::from_fn(|i| if i < 3 { point[i] } else { w })
50 }
51
52 let mut build_plane =
53 |position: Vector3<f32>, width_len: f32, height_len: f32, normal: Vector3<f32>| {
54 let mut height = normal.yzx();
55 height.set_magnitude(height_len);
56
57 let mut width = height.cross(&normal);
58 width.set_magnitude(width_len);
59
60 vertices.push(to_homogeneous(&position, 1.0));
61 vertices.push(to_homogeneous(&(position + width), 1.0));
62 vertices.push(to_homogeneous(&(position + width + height), 1.0));
63 vertices.push(to_homogeneous(&(position + height), 1.0));
64 vertices.push(to_homogeneous(&position, 1.0));
65 vertices.push(to_homogeneous(&(position + width + height), 1.0));
66 };
67
68 let w = self.width;
69 let h = self.height;
70 let d = self.depth;
71
72 build_plane(
73 Vector3::new(-w / 2.0, -h / 2.0, -d / 2.0),
74 w,
75 h,
76 Vector3::z(),
77 );
78 build_plane(
79 Vector3::new(-w / 2.0, -h / 2.0, d / 2.0),
80 w,
81 h,
82 Vector3::z(),
83 );
84 build_plane(
85 Vector3::new(w / 2.0, -h / 2.0, -d / 2.0),
86 h,
87 d,
88 Vector3::x(),
89 );
90 build_plane(
91 Vector3::new(-w / 2.0, -h / 2.0, d / 2.0),
92 h,
93 d,
94 -Vector3::x(),
95 );
96 build_plane(
97 Vector3::new(-w / 2.0, h / 2.0, -d / 2.0),
98 d,
99 w,
100 Vector3::y(),
101 );
102 build_plane(
103 Vector3::new(w / 2.0, -h / 2.0, -d / 2.0),
104 d,
105 w,
106 -Vector3::y(),
107 );
108 }
109}
110
111impl<M: Material> Representable for Mesh<Cube, M> {
112 type Intermediate = Vertices;
113
114 fn as_intermediate(&self) -> Self::Intermediate {
115 self.geometry.vertices.clone()
116 }
117
118 fn update_from_intermediate(&mut self, repr: &Self::Intermediate) {
119 self.geometry.vertices = repr.clone();
120 }
121}
122
123impl<M: Material> Transformable for Mesh<Cube, M> {
124 fn apply_transform<Trans: Fn(&[f32; 3]) -> [f32; 3]>(
125 &self,
126 transform: Trans,
127 ) -> Self::Intermediate {
128 self.geometry.vertices.apply_transform(|vertex| {
129 let transformed = transform(&[vertex[0], vertex[1], vertex[2]]);
130 [transformed[0], transformed[1], transformed[2], 1.0]
131 })
132 }
133}