vox_geometry_rust/
collider_set2.rs

1/*
2 * // Copyright (c) 2021 Feng Yang
3 * //
4 * // I am making my contributions/submissions to this project solely in my
5 * // personal capacity and am not conveying any rights to any intellectual
6 * // property of any third parties.
7 */
8
9use crate::collider2::*;
10use crate::surface_set2::*;
11use crate::vector2::Vector2D;
12use std::sync::{RwLock, Arc};
13
14
15///
16/// # Callback function type for update calls.
17///
18/// This type of callback function will take the collider pointer, current
19/// time, and time interval in seconds.
20///
21pub type OnBeginUpdateCallback = fn(&mut ColliderSet2, f64, f64);
22
23/// # Collection of 2-D colliders
24pub struct ColliderSet2 {
25    _colliders: Vec<Collider2Ptr>,
26
27    _surface: SurfaceSet2Ptr,
28    _collider_data: Collider2Data,
29    _on_update_callback: Option<OnBeginUpdateCallback>,
30}
31
32impl ColliderSet2 {
33    /// Default constructor.
34    pub fn new_default() -> ColliderSet2 {
35        let set = SurfaceSet2::builder().make_shared();
36        return ColliderSet2 {
37            _colliders: vec![],
38            _surface: set.clone(),
39            _collider_data: Collider2Data::new(Some(set)),
40            _on_update_callback: None,
41        };
42    }
43
44    /// Constructs with other colliders.
45    pub fn new(others: Vec<Collider2Ptr>) -> ColliderSet2 {
46        let mut collider_set = ColliderSet2::new_default();
47        for collider in others {
48            collider_set.add_collider(collider);
49        }
50
51        return collider_set;
52    }
53
54    /// Returns builder fox ColliderSet2.
55    pub fn builder() -> Builder {
56        return Builder::new();
57    }
58
59    /// Adds a collider to the set.
60    pub fn add_collider(&mut self, collider: Collider2Ptr) {
61        self._colliders.push(collider.clone());
62        self._surface.write().unwrap().add_surface(collider.read().unwrap().surface());
63    }
64
65    /// Returns number of colliders.
66    pub fn number_of_colliders(&self) -> usize {
67        return self._colliders.len();
68    }
69
70    /// Returns collider at index \p i.
71    pub fn collider(&self, i: usize) -> Collider2Ptr {
72        return self._colliders[i].clone();
73    }
74
75
76    ///
77    /// \brief      Sets the callback function to be called when
78    ///             Collider2::update function is invoked.
79    ///
80    /// The callback function takes current simulation time in seconds unit. Use
81    /// this callback to track any motion or state changes related to this
82    /// collider.
83    ///
84    /// - parameter: callback The callback function.
85    ///
86    pub fn set_on_begin_update_callback(&mut self, callback: OnBeginUpdateCallback) {
87        self._on_update_callback = Some(callback);
88    }
89}
90
91impl Collider2 for ColliderSet2 {
92    fn velocity_at(&self, point: &Vector2D) -> Vector2D {
93        let mut closest_collider = usize::MAX;
94        let mut closest_dist = f64::MAX;
95        for i in 0..self._colliders.len() {
96            let dist = self._colliders[i].read().unwrap().surface().read().unwrap().closest_distance(point);
97            if dist < closest_dist {
98                closest_dist = dist;
99                closest_collider = i;
100            }
101        }
102        return if closest_collider != usize::MAX {
103            self._colliders[closest_collider].read().unwrap().velocity_at(point)
104        } else {
105            Vector2D::new_default()
106        };
107    }
108
109    fn update(&mut self, current_time_in_seconds: f64,
110              time_interval_in_seconds: f64) where Self: Sized {
111        if !self.surface().read().unwrap().is_valid_geometry() {
112            return;
113        }
114
115        self.surface().read().unwrap().update_query_engine();
116
117        if let Some(callback) = self._on_update_callback {
118            (callback)(self, current_time_in_seconds, time_interval_in_seconds);
119        }
120    }
121
122    fn view(&self) -> &Collider2Data {
123        return &self._collider_data;
124    }
125
126    fn view_mut(&mut self) -> &mut Collider2Data {
127        return &mut self._collider_data;
128    }
129}
130
131/// Shared pointer for the ColliderSet2 type.
132pub type ColliderSet2Ptr = Arc<RwLock<ColliderSet2>>;
133
134///
135/// # Front-end to create ColliderSet2 objects step by step.
136///
137pub struct Builder {
138    _colliders: Vec<Collider2Ptr>,
139}
140
141impl Builder {
142    /// Returns builder with other colliders.
143    pub fn with_colliders(&mut self, others: Vec<Collider2Ptr>) -> &mut Self {
144        self._colliders = others;
145        return self;
146    }
147
148    /// Builds ColliderSet2.
149    pub fn build(&mut self) -> ColliderSet2 {
150        return ColliderSet2::new(self._colliders.clone());
151    }
152
153    /// Builds shared pointer of ColliderSet2 instance.
154    pub fn make_shared(&mut self) -> ColliderSet2Ptr {
155        return ColliderSet2Ptr::new(RwLock::new(self.build()));
156    }
157
158    /// constructor
159    pub fn new() -> Builder {
160        return Builder {
161            _colliders: vec![]
162        };
163    }
164}