ncollide3d/procedural/path/
polyline_path.rs

1use crate::math::{Point, Vector};
2use crate::procedural::path::{CurveSampler, PathSample};
3use na::RealField;
4
5/// A path with its sample points given by a polyline.
6///
7/// This will return sequencially each vertex of the polyline.
8pub 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    /// Creates a new polyline-based path.
18    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}