vox_geometry_rust 0.1.2

Geometry Tools for Rust
Documentation
/*
 * // Copyright (c) 2021 Feng Yang
 * //
 * // I am making my contributions/submissions to this project solely in my
 * // personal capacity and am not conveying any rights to any intellectual
 * // property of any third parties.
 */

use crate::collider3::*;
use crate::surface_set3::*;
use crate::vector3::Vector3D;
use std::sync::{RwLock, Arc};

///
/// # Callback function type for update calls.
///
/// This type of callback function will take the collider pointer, current
/// time, and time interval in seconds.
///
pub type OnBeginUpdateCallback = fn(&mut ColliderSet3, f64, f64);

/// # Collection of 3-D colliders
pub struct ColliderSet3 {
    _colliders: Vec<Collider3Ptr>,

    _surface: SurfaceSet3Ptr,
    _collider_data: Collider3Data,
    _on_update_callback: Option<OnBeginUpdateCallback>,
}

impl ColliderSet3 {
    /// Default constructor.
    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,
        };
    }

    /// Constructs with other colliders.
    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;
    }

    /// Returns builder fox ColliderSet3.
    pub fn builder() -> Builder {
        return Builder::new();
    }

    /// Adds a collider to the set.
    pub fn add_collider(&mut self, collider: Collider3Ptr) {
        self._colliders.push(collider.clone());
        self._surface.write().unwrap().add_surface(collider.read().unwrap().surface());
    }

    /// Returns number of colliders.
    pub fn number_of_colliders(&self) -> usize {
        return self._colliders.len();
    }

    /// Returns collider at index \p i.
    pub fn collider(&self, i: usize) -> Collider3Ptr {
        return self._colliders[i].clone();
    }


    ///
    /// \brief      Sets the callback function to be called when
    ///             Collider3::update function is invoked.
    ///
    /// The callback function takes current simulation time in seconds unit. Use
    /// this callback to track any motion or state changes related to this
    /// collider.
    ///
    /// - parameter: callback The callback function.
    ///
    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;
    }
}

/// Shared pointer for the ColliderSet3 type.
pub type ColliderSet3Ptr = Arc<RwLock<ColliderSet3>>;

///
/// # Front-end to create ColliderSet3 objects step by step.
///
pub struct Builder {
    _colliders: Vec<Collider3Ptr>,
}

impl Builder {
    /// Returns builder with other colliders.
    pub fn with_colliders(&mut self, others: Vec<Collider3Ptr>) -> &mut Self {
        self._colliders = others;
        return self;
    }

    /// Builds ColliderSet3.
    pub fn build(&mut self) -> ColliderSet3 {
        return ColliderSet3::new(self._colliders.clone());
    }

    /// Builds shared pointer of ColliderSet3 instance.
    pub fn make_shared(&mut self) -> ColliderSet3Ptr {
        return ColliderSet3Ptr::new(RwLock::new(self.build()));
    }

    /// constructor
    pub fn new() -> Builder {
        return Builder {
            _colliders: vec![]
        };
    }
}