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;
#[derive(Clone, Debug, PartialEq)]
pub struct Mesh<S> {
pub vertices: Vec<[S; 3]>,
pub faces: Vec<[usize; 3]>,
}
impl<S: RealField + Debug> Mesh<S> {
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]]
}
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.]));
}
}