1use crate::GIMesh;
2
3pub struct MergeSettings {
4 pub merge_distance: f32,
6
7 pub invert_b_normals: bool,
9}
10
11impl Default for MergeSettings {
12 fn default() -> Self {
13 Self {
14 merge_distance: 0.0001,
15 invert_b_normals: false,
16 }
17 }
18}
19
20pub fn merge_meshes(a: &mut GIMesh, b: &GIMesh, settings: &MergeSettings) {
22 let distance = settings.merge_distance * settings.merge_distance;
23
24 for t in 0..b.tri_count() {
25 let tri = b.tri(t);
26 let verts = [b.vertex(tri[0].0), b.vertex(tri[1].0), b.vertex(tri[2].0)];
27
28 let mut ivs = [None, None, None];
29 for ai in 0..a.index_count() {
30 let aindex = a.index(ai);
31 let av = a.vertex(aindex);
32
33 for i in 0..3 {
34 if ivs[i].is_some() {
35 continue;
36 }
37
38 if verts[i].pos.distance_squared(av.pos) < distance {
39 ivs[i] = Some(aindex);
40 }
41 }
42
43 if ivs[0].is_some() && ivs[1].is_some() && ivs[2].is_some() {
44 break;
45 }
46 }
47
48 let i1 = ivs[0].unwrap_or_else(|| {
49 let mut v = verts[0].clone();
50 if settings.invert_b_normals {
51 v.normal = -v.normal;
52 }
53
54 a.add_vertex(v)
55 });
56 let i2 = ivs[1].unwrap_or_else(|| {
57 let mut v = verts[1].clone();
58 if settings.invert_b_normals {
59 v.normal = -v.normal;
60 }
61
62 a.add_vertex(v)
63 });
64 let i3 = ivs[2].unwrap_or_else(|| {
65 let mut v = verts[2].clone();
66 if settings.invert_b_normals {
67 v.normal = -v.normal;
68 }
69
70 a.add_vertex(v)
71 });
72
73 if settings.invert_b_normals {
74 a.add_index(i3);
75 a.add_index(i2);
76 a.add_index(i1);
77 } else {
78 a.add_index(i1);
79 a.add_index(i2);
80 a.add_index(i3);
81 }
82 }
83}