use crate::collider3::*;
use crate::surface3::*;
use crate::vector3::Vector3D;
use std::sync::{RwLock, Arc};
pub type OnBeginUpdateCallback = fn(&mut RigidBodyCollider3, f64, f64);
pub struct RigidBodyCollider3 {
pub linear_velocity: Vector3D,
pub angular_velocity: Vector3D,
_collider_data: Collider3Data,
_on_update_callback: Option<OnBeginUpdateCallback>,
}
impl RigidBodyCollider3 {
pub fn new(surface: Surface3Ptr) -> RigidBodyCollider3 {
return RigidBodyCollider3 {
linear_velocity: Vector3D::new_default(),
angular_velocity: Vector3D::new_default(),
_collider_data: Collider3Data::new(Some(surface)),
_on_update_callback: None,
};
}
pub fn new_vel(
surface: Surface3Ptr,
linear_velocity: Vector3D,
angular_velocity: Vector3D) -> RigidBodyCollider3 {
return RigidBodyCollider3 {
linear_velocity,
angular_velocity,
_collider_data: Collider3Data::new(Some(surface)),
_on_update_callback: None,
};
}
pub fn builder() -> Builder {
return Builder::new();
}
pub fn set_on_begin_update_callback(&mut self, callback: OnBeginUpdateCallback) {
self._on_update_callback = Some(callback);
}
}
impl Collider3 for RigidBodyCollider3 {
fn velocity_at(&self, point: &Vector3D) -> Vector3D {
let r = *point - self.surface().read().unwrap().view().transform.translation();
return self.linear_velocity + self.angular_velocity.cross(&r);
}
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 RigidBodyCollider3Ptr = Arc<RwLock<RigidBodyCollider3>>;
pub struct Builder {
_surface: Option<Surface3Ptr>,
_linear_velocity: Vector3D,
_angular_velocity: Vector3D,
}
impl Builder {
pub fn with_surface(&mut self, surface: Surface3Ptr) -> &mut Self {
self._surface = Some(surface);
return self;
}
pub fn with_linear_velocity(&mut self, linear_velocity: Vector3D) -> &mut Self {
self._linear_velocity = linear_velocity;
return self;
}
pub fn with_angular_velocity(&mut self, angular_velocity: Vector3D) -> &mut Self {
self._angular_velocity = angular_velocity;
return self;
}
pub fn build(&mut self) -> RigidBodyCollider3 {
return RigidBodyCollider3::new_vel(self._surface.as_ref().unwrap().clone(),
self._linear_velocity,
self._angular_velocity);
}
pub fn make_shared(&mut self) -> RigidBodyCollider3Ptr {
return RigidBodyCollider3Ptr::new(RwLock::new(self.build()));
}
pub fn new() -> Builder {
return Builder {
_surface: None,
_linear_velocity: Vector3D::new_default(),
_angular_velocity: Vector3D::new_default(),
};
}
}