use crate::collider3::*;
use crate::surface_set3::*;
use crate::vector3::Vector3D;
use std::sync::{RwLock, Arc};
pub type OnBeginUpdateCallback = fn(&mut ColliderSet3, f64, f64);
pub struct ColliderSet3 {
_colliders: Vec<Collider3Ptr>,
_surface: SurfaceSet3Ptr,
_collider_data: Collider3Data,
_on_update_callback: Option<OnBeginUpdateCallback>,
}
impl ColliderSet3 {
pub fn new_default() -> ColliderSet3 {
let set = SurfaceSet3::builder().make_shared();
return ColliderSet3 {
_colliders: vec![],
_surface: set.clone(),
_collider_data: Collider3Data::new(Some(set)),
_on_update_callback: None,
};
}
pub fn new(others: Vec<Collider3Ptr>) -> ColliderSet3 {
let mut collider_set = ColliderSet3::new_default();
for collider in others {
collider_set.add_collider(collider);
}
return collider_set;
}
pub fn builder() -> Builder {
return Builder::new();
}
pub fn add_collider(&mut self, collider: Collider3Ptr) {
self._colliders.push(collider.clone());
self._surface.write().unwrap().add_surface(collider.read().unwrap().surface());
}
pub fn number_of_colliders(&self) -> usize {
return self._colliders.len();
}
pub fn collider(&self, i: usize) -> Collider3Ptr {
return self._colliders[i].clone();
}
pub fn set_on_begin_update_callback(&mut self, callback: OnBeginUpdateCallback) {
self._on_update_callback = Some(callback);
}
}
impl Collider3 for ColliderSet3 {
fn velocity_at(&self, point: &Vector3D) -> Vector3D {
let mut closest_collider = usize::MAX;
let mut closest_dist = f64::MAX;
for i in 0..self._colliders.len() {
let dist = self._colliders[i].read().unwrap().surface().read().unwrap().closest_distance(point);
if dist < closest_dist {
closest_dist = dist;
closest_collider = i;
}
}
return if closest_collider != usize::MAX {
self._colliders[closest_collider].read().unwrap().velocity_at(point)
} else {
Vector3D::new_default()
};
}
fn update(&mut self, current_time_in_seconds: f64,
time_interval_in_seconds: f64) where Self: Sized {
if !self.surface().read().unwrap().is_valid_geometry() {
return;
}
self.surface().read().unwrap().update_query_engine();
if let Some(callback) = self._on_update_callback {
(callback)(self, current_time_in_seconds, time_interval_in_seconds);
}
}
fn view(&self) -> &Collider3Data {
return &self._collider_data;
}
fn view_mut(&mut self) -> &mut Collider3Data {
return &mut self._collider_data;
}
}
pub type ColliderSet3Ptr = Arc<RwLock<ColliderSet3>>;
pub struct Builder {
_colliders: Vec<Collider3Ptr>,
}
impl Builder {
pub fn with_colliders(&mut self, others: Vec<Collider3Ptr>) -> &mut Self {
self._colliders = others;
return self;
}
pub fn build(&mut self) -> ColliderSet3 {
return ColliderSet3::new(self._colliders.clone());
}
pub fn make_shared(&mut self) -> ColliderSet3Ptr {
return ColliderSet3Ptr::new(RwLock::new(self.build()));
}
pub fn new() -> Builder {
return Builder {
_colliders: vec![]
};
}
}