1#![allow(dead_code)]
2#[allow(dead_code)]
8pub struct ArrayResult {
9 pub verts: Vec<[f32; 3]>,
10 pub tris: Vec<[u32; 3]>,
11}
12
13#[allow(dead_code)]
14pub fn array_mesh(
15 verts: &[[f32; 3]],
16 tris: &[[u32; 3]],
17 count: u32,
18 offset: [f32; 3],
19) -> ArrayResult {
20 let nv = verts.len();
21 let mut out_verts = Vec::with_capacity(array_vert_count(nv, count));
22 let mut out_tris = Vec::with_capacity(array_tri_count(tris.len(), count));
23 for i in 0..count {
24 let dx = offset[0] * i as f32;
25 let dy = offset[1] * i as f32;
26 let dz = offset[2] * i as f32;
27 let base = (i as usize * nv) as u32;
28 for v in verts {
29 out_verts.push([v[0] + dx, v[1] + dy, v[2] + dz]);
30 }
31 for t in tris {
32 out_tris.push([t[0] + base, t[1] + base, t[2] + base]);
33 }
34 }
35 ArrayResult {
36 verts: out_verts,
37 tris: out_tris,
38 }
39}
40
41#[allow(dead_code)]
42pub fn array_vert_count(orig: usize, count: u32) -> usize {
43 orig * count as usize
44}
45
46#[allow(dead_code)]
47pub fn array_tri_count(orig: usize, count: u32) -> usize {
48 orig * count as usize
49}
50
51pub struct ArrayParams {
55 pub count: usize,
56 pub offset: [f32; 3],
57 pub scale: [f32; 3],
58}
59
60pub fn new_array_params(count: usize, offset: [f32; 3]) -> ArrayParams {
61 ArrayParams {
62 count: count.max(1),
63 offset,
64 scale: [1.0, 1.0, 1.0],
65 }
66}
67
68pub fn array_instance_transform(params: &ArrayParams, instance: usize) -> ([f32; 3], [f32; 3]) {
69 let i = instance as f32;
70 let translation = [
71 params.offset[0] * i,
72 params.offset[1] * i,
73 params.offset[2] * i,
74 ];
75 (translation, params.scale)
76}
77
78pub fn array_total_size(params: &ArrayParams) -> [f32; 3] {
79 let n = params.count as f32;
80 [
81 params.offset[0] * n,
82 params.offset[1] * n,
83 params.offset[2] * n,
84 ]
85}
86
87pub fn array_vertex_count(base_count: usize, params: &ArrayParams) -> usize {
88 base_count * params.count
89}
90
91pub fn array_face_count(base_count: usize, params: &ArrayParams) -> usize {
92 base_count * params.count
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 fn unit_tri_verts() -> Vec<[f32; 3]> {
100 vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
101 }
102 fn unit_tri_tris() -> Vec<[u32; 3]> {
103 vec![[0, 1, 2]]
104 }
105
106 #[test]
107 fn vert_count_formula() {
108 assert_eq!(array_vert_count(3, 4), 12);
109 }
110
111 #[test]
112 fn tri_count_formula() {
113 assert_eq!(array_tri_count(2, 3), 6);
114 }
115
116 #[test]
117 fn single_copy_unchanged() {
118 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 1, [1.0, 0.0, 0.0]);
119 assert_eq!(r.verts.len(), 3);
120 assert_eq!(r.tris.len(), 1);
121 assert_eq!(r.tris[0], [0, 1, 2]);
122 }
123
124 #[test]
125 fn two_copies_vert_count() {
126 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 2, [2.0, 0.0, 0.0]);
127 assert_eq!(r.verts.len(), 6);
128 }
129
130 #[test]
131 fn two_copies_offset_applied() {
132 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 2, [2.0, 0.0, 0.0]);
133 assert!((r.verts[3][0] - 2.0).abs() < 1e-6);
134 }
135
136 #[test]
137 fn two_copies_tri_indices_offset() {
138 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 2, [1.0, 0.0, 0.0]);
139 assert_eq!(r.tris[1], [3, 4, 5]);
140 }
141
142 #[test]
143 fn zero_count_empty() {
144 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 0, [1.0, 0.0, 0.0]);
145 assert!(r.verts.is_empty());
146 assert!(r.tris.is_empty());
147 }
148
149 #[test]
150 fn y_offset_applied() {
151 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 3, [0.0, 1.0, 0.0]);
152 assert!((r.verts[6][1] - 2.0).abs() < 1e-6);
153 }
154
155 #[test]
156 fn z_offset_applied() {
157 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 2, [0.0, 0.0, 5.0]);
158 assert!((r.verts[3][2] - 5.0).abs() < 1e-6);
159 }
160
161 #[test]
162 fn first_copy_at_origin() {
163 let r = array_mesh(&unit_tri_verts(), &unit_tri_tris(), 3, [1.0, 1.0, 1.0]);
164 assert!((r.verts[0][0]).abs() < 1e-6);
165 }
166}