ncollide3d/procedural/path/
polyline_path.rs
1use crate::math::{Point, Vector};
2use crate::procedural::path::{CurveSampler, PathSample};
3use na::RealField;
4
5pub struct PolylinePath<'a, N: 'a + RealField + Copy> {
9 curr_len: N,
10 curr_dir: Vector<N>,
11 curr_pt_id: usize,
12 curr_pt: Point<N>,
13 polyline: &'a Vec<Point<N>>,
14}
15
16impl<'a, N: RealField + Copy> PolylinePath<'a, N> {
17 pub fn new(polyline: &'a Vec<Point<N>>) -> PolylinePath<'a, N> {
19 assert!(
20 polyline.len() > 1,
21 "The polyline must have at least two points."
22 );
23
24 let mut dir: Vector<N> = polyline[1] - polyline[0];
25 let len: N = dir.normalize_mut();
26
27 PolylinePath {
28 curr_len: len,
29 curr_dir: dir,
30 curr_pt_id: 0,
31 curr_pt: polyline[0].clone(),
32 polyline: polyline,
33 }
34 }
35}
36
37impl<'a, N: RealField + Copy> CurveSampler<N> for PolylinePath<'a, N> {
38 fn next(&mut self) -> PathSample<N> {
39 let poly_coords = self.polyline;
40
41 let result = if self.curr_pt_id == 0 {
42 PathSample::StartPoint(self.curr_pt.clone(), self.curr_dir.clone())
43 } else if self.curr_pt_id < poly_coords.len() - 1 {
44 PathSample::InnerPoint(self.curr_pt.clone(), self.curr_dir.clone())
45 } else if self.curr_pt_id == poly_coords.len() - 1 {
46 PathSample::EndPoint(self.curr_pt.clone(), self.curr_dir.clone())
47 } else {
48 PathSample::EndOfSample
49 };
50
51 self.curr_pt_id = self.curr_pt_id + 1;
52
53 if self.curr_pt_id < poly_coords.len() {
54 self.curr_pt = poly_coords[self.curr_pt_id].clone();
55
56 if self.curr_pt_id < poly_coords.len() - 1 {
57 let mut curr_diff = poly_coords[self.curr_pt_id + 1] - poly_coords[self.curr_pt_id];
58 self.curr_len = curr_diff.normalize_mut();
59 self.curr_dir = curr_diff;
60 }
61 }
62
63 result
64 }
65}