1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use alga::general::RealField;
use nalgebra as na;
use std::fmt::Debug;

/// Mesh that will be returned from tessellate.
#[derive(Clone, Debug, PartialEq)]
pub struct Mesh<S> {
    /// The list of vertices.
    pub vertices: Vec<[S; 3]>,
    /// The list of triangles as indexes into vertices.
    pub faces: Vec<[usize; 3]>,
}

impl<S: RealField + Debug> Mesh<S> {
    /// Return the normal of the face at index face as triple of f32.
    pub fn normal32(&self, face: usize) -> [f32; 3]
    where
        f64: From<S>,
    {
        let v: Vec<na::Point3<f32>> = self.faces[face]
            .iter()
            .map(|&i| {
                let v: (f64, f64, f64) = (
                    self.vertices[i][0].into(),
                    self.vertices[i][1].into(),
                    self.vertices[i][2].into(),
                );
                na::Point3::<f32>::new(v.0 as f32, v.1 as f32, v.2 as f32)
            })
            .collect();
        let r = (v[1] - v[0]).cross(&(v[2] - v[0])).normalize();
        [r[0], r[1], r[2]]
    }
    /// Return the vertics of the face at index face as triple of f32.
    pub fn vertex32(&self, i: usize) -> [f32; 3]
    where
        f64: From<S>,
    {
        let v: (f64, f64, f64) = (
            self.vertices[i][0].into(),
            self.vertices[i][1].into(),
            self.vertices[i][2].into(),
        );
        [v.0 as f32, v.1 as f32, v.2 as f32]
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn f32slice_eq(a: &[f32], b: &[f32]) -> bool {
        assert_eq!(a.len(), b.len());
        for i in 0..a.len() {
            if (a[i] - b[i]).abs() > f32::EPSILON {
                return false;
            }
        }
        true
    }

    #[test]
    fn simple() {
        let m = Mesh {
            vertices: vec![[0., 0., 0.], [1., 0., 0.], [0., 1., 0.]],
            faces: vec![[0, 1, 2]],
        };
        assert!(f32slice_eq(&m.normal32(0), &[0., 0., 1.]));
        assert!(f32slice_eq(&m.vertex32(0), &[0., 0., 0.]));
        assert!(f32slice_eq(&m.vertex32(1), &[1., 0., 0.]));
        assert!(f32slice_eq(&m.vertex32(2), &[0., 1., 0.]));
    }
}