solstice_2d/d3/shapes/
box_geometry.rs

1use crate::d3::Vertex3D;
2
3#[derive(Debug, Copy, Clone, PartialEq)]
4pub struct Box {
5    pub width: f32,
6    pub height: f32,
7    pub depth: f32,
8    pub width_segments: u32,
9    pub height_segments: u32,
10    pub depth_segments: u32,
11}
12
13impl Box {
14    pub fn new(
15        width: f32,
16        height: f32,
17        depth: f32,
18        width_segments: u32,
19        height_segments: u32,
20        depth_segments: u32,
21    ) -> Self {
22        Self {
23            width,
24            height,
25            depth,
26            width_segments,
27            height_segments,
28            depth_segments,
29        }
30    }
31
32    fn vertices(&self) -> Vec<Vertex3D> {
33        let mut vertices = Vec::new();
34
35        build_plane(
36            &mut vertices,
37            2,
38            1,
39            0,
40            -1.,
41            -1.,
42            self.depth,
43            self.height,
44            self.width,
45            self.depth_segments,
46            self.height_segments,
47        );
48        build_plane(
49            &mut vertices,
50            2,
51            1,
52            0,
53            1.,
54            -1.,
55            self.depth,
56            self.height,
57            -self.width,
58            self.depth_segments,
59            self.height_segments,
60        );
61        build_plane(
62            &mut vertices,
63            0,
64            2,
65            1,
66            1.,
67            1.,
68            self.width,
69            self.depth,
70            self.height,
71            self.width_segments,
72            self.depth_segments,
73        );
74        build_plane(
75            &mut vertices,
76            0,
77            2,
78            1,
79            1.,
80            -1.,
81            self.width,
82            self.depth,
83            -self.height,
84            self.width_segments,
85            self.depth_segments,
86        );
87        build_plane(
88            &mut vertices,
89            0,
90            1,
91            2,
92            1.,
93            -1.,
94            self.width,
95            self.height,
96            self.depth,
97            self.width_segments,
98            self.height_segments,
99        );
100        build_plane(
101            &mut vertices,
102            0,
103            1,
104            2,
105            -1.,
106            -1.,
107            self.width,
108            self.height,
109            -self.depth,
110            self.width_segments,
111            self.height_segments,
112        );
113
114        vertices
115    }
116
117    fn indices(&self) -> Vec<u32> {
118        let faces = [
119            (self.depth_segments, self.height_segments),
120            (self.depth_segments, self.height_segments),
121            (self.width_segments, self.depth_segments),
122            (self.width_segments, self.depth_segments),
123            (self.width_segments, self.height_segments),
124            (self.width_segments, self.height_segments),
125        ];
126
127        let mut index_start = 0;
128        let mut indices = Vec::new();
129        for (grid_x, grid_y) in faces.iter().copied() {
130            let grid_x1 = grid_x + 1;
131            for iy in 0..grid_y {
132                for ix in 0..grid_x {
133                    let a = ix + grid_x1 * iy;
134                    let b = ix + grid_x1 * (iy + 1);
135                    let c = (ix + 1) + grid_x1 * (iy + 1);
136                    let d = (ix + 1) + grid_x1 * iy;
137
138                    indices.push(index_start + a);
139                    indices.push(index_start + b);
140                    indices.push(index_start + d);
141
142                    indices.push(index_start + b);
143                    indices.push(index_start + c);
144                    indices.push(index_start + d);
145                }
146            }
147            index_start += grid_x * grid_y * 4;
148        }
149
150        indices
151    }
152}
153
154impl Default for Box {
155    fn default() -> Self {
156        Self {
157            width: 1.,
158            height: 1.,
159            depth: 1.,
160            width_segments: 1,
161            height_segments: 1,
162            depth_segments: 1,
163        }
164    }
165}
166
167impl From<&Box> for crate::Geometry<'_, Vertex3D> {
168    fn from(b: &Box) -> Self {
169        Self::new(b.vertices(), Some(b.indices()))
170    }
171}
172
173impl From<Box> for crate::Geometry<'_, Vertex3D> {
174    fn from(b: Box) -> Self {
175        Self::new(b.vertices(), Some(b.indices()))
176    }
177}
178
179fn build_plane(
180    vertices: &mut Vec<Vertex3D>,
181    u: usize,
182    v: usize,
183    w: usize,
184    u_dir: f32,
185    v_dir: f32,
186    width: f32,
187    height: f32,
188    depth: f32,
189    grid_x: u32,
190    grid_y: u32,
191) {
192    let segment_width = width / grid_x as f32;
193    let segment_height = height / grid_y as f32;
194
195    let width_half = width / 2.;
196    let height_half = height / 2.;
197    let depth_half = depth / 2.;
198
199    let grid_x1 = grid_x + 1;
200    let grid_y1 = grid_y + 1;
201
202    for iy in 0..grid_y1 {
203        let iy = iy as f32;
204        let y = iy * segment_height - height_half;
205        for ix in 0..grid_x1 {
206            let ix = ix as f32;
207            let x = ix * segment_width - width_half;
208
209            let mut position = [0f32; 3];
210            position[u] = x * u_dir;
211            position[v] = y * v_dir;
212            position[w] = depth_half;
213
214            let mut normal = [0f32; 3];
215            normal[u] = 0.;
216            normal[v] = 0.;
217            normal[w] = if depth > 0. { 1. } else { -1. };
218
219            vertices.push(Vertex3D {
220                position,
221                normal,
222                uv: [ix / grid_x as f32, iy / grid_y as f32],
223                color: [1., 1., 1., 1.],
224            })
225        }
226    }
227}