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::collider2::*;
use crate::surface_set2::*;
use crate::vector2::Vector2D;
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 ColliderSet2, f64, f64);

/// # Collection of 2-D colliders
pub struct ColliderSet2 {
    _colliders: Vec<Collider2Ptr>,

    _surface: SurfaceSet2Ptr,
    _collider_data: Collider2Data,
    _on_update_callback: Option<OnBeginUpdateCallback>,
}

impl ColliderSet2 {
    /// Default constructor.
    pub fn new_default() -> ColliderSet2 {
        let set = SurfaceSet2::builder().make_shared();
        return ColliderSet2 {
            _colliders: vec![],
            _surface: set.clone(),
            _collider_data: Collider2Data::new(Some(set)),
            _on_update_callback: None,
        };
    }

    /// Constructs with other colliders.
    pub fn new(others: Vec<Collider2Ptr>) -> ColliderSet2 {
        let mut collider_set = ColliderSet2::new_default();
        for collider in others {
            collider_set.add_collider(collider);
        }

        return collider_set;
    }

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

    /// Adds a collider to the set.
    pub fn add_collider(&mut self, collider: Collider2Ptr) {
        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) -> Collider2Ptr {
        return self._colliders[i].clone();
    }


    ///
    /// \brief      Sets the callback function to be called when
    ///             Collider2::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 Collider2 for ColliderSet2 {
    fn velocity_at(&self, point: &Vector2D) -> Vector2D {
        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 {
            Vector2D::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) -> &Collider2Data {
        return &self._collider_data;
    }

    fn view_mut(&mut self) -> &mut Collider2Data {
        return &mut self._collider_data;
    }
}

/// Shared pointer for the ColliderSet2 type.
pub type ColliderSet2Ptr = Arc<RwLock<ColliderSet2>>;

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

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

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

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

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