bevy_mops/
merge.rs

1use crate::GIMesh;
2
3pub struct MergeSettings {
4    /// Merge distance between vertices
5    pub merge_distance: f32,
6
7    /// If `true` b's normals are inverted when added
8    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
20/// Merges `b` into `a`
21pub 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}