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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use na::Real;
use partitioning::BVT;
use bounding_volume::AABB;
use shape::{CompositeShape, Segment, Shape};
use math::{Isometry, Point};
pub struct Polyline<N: Real> {
bvt: BVT<usize, AABB<N>>,
bvs: Vec<AABB<N>>, vertices: Vec<Point<N>>,
}
impl<N: Real> Polyline<N> {
pub fn new(vertices: Vec<Point<N>>) -> Polyline<N> {
let mut leaves = Vec::new();
let mut bvs = Vec::new();
for (i, vtx) in vertices.windows(2).enumerate() {
let element = Segment::new(vtx[0], vtx[1]);
let bv = element.aabb(&Isometry::identity());
leaves.push((i, bv.clone()));
bvs.push(bv);
}
let bvt = BVT::new_balanced(leaves);
Polyline {
bvt: bvt,
bvs: bvs,
vertices: vertices,
}
}
#[inline]
pub fn vertices(&self) -> &[Point<N>] {
&self.vertices
}
#[inline]
pub fn bounding_volumes(&self) -> &[AABB<N>] {
&self.bvs
}
#[inline]
pub fn segment_at(&self, i: usize) -> Segment<N> {
Segment::new(self.vertices[i], self.vertices[i + 1])
}
}
impl<N: Real> CompositeShape<N> for Polyline<N> {
#[inline]
fn nparts(&self) -> usize {
self.vertices.len() / 2
}
#[inline(always)]
fn map_part_at(&self, i: usize, f: &mut FnMut(usize, &Isometry<N>, &Shape<N>)) {
self.map_transformed_part_at(i, &Isometry::identity(), f)
}
#[inline(always)]
fn map_transformed_part_at(
&self,
i: usize,
m: &Isometry<N>,
f: &mut FnMut(usize, &Isometry<N>, &Shape<N>),
) {
let element = self.segment_at(i);
f(i, m, &element)
}
#[inline]
fn aabb_at(&self, i: usize) -> AABB<N> {
self.bvs[i].clone()
}
#[inline]
fn bvt(&self) -> &BVT<usize, AABB<N>> {
&self.bvt
}
}