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::surface3::*;
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 RigidBodyCollider3, f64, f64);

///
/// # 3-D rigid body collider class.
///
/// This class implements 3-D rigid body collider. The collider can only take
/// rigid body motion with linear and rotational velocities.
///
pub struct RigidBodyCollider3 {
    /// Linear velocity of the rigid body.
    pub linear_velocity: Vector3D,

    /// Angular velocity of the rigid body.
    pub angular_velocity: Vector3D,

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

impl RigidBodyCollider3 {
    /// Constructs a collider with a surface.
    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,
        };
    }

    /// Constructs a collider with a surface and other parameters.
    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,
        };
    }

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

    ///
    /// \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 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;
    }
}

/// Shared pointer for the RigidBodyCollider3 type.
pub type RigidBodyCollider3Ptr = Arc<RwLock<RigidBodyCollider3>>;

///
/// # Front-end to create RigidBodyCollider3 objects step by step.
///
pub struct Builder {
    _surface: Option<Surface3Ptr>,
    _linear_velocity: Vector3D,
    _angular_velocity: Vector3D,
}

impl Builder {
    /// Returns builder with surface.
    pub fn with_surface(&mut self, surface: Surface3Ptr) -> &mut Self {
        self._surface = Some(surface);
        return self;
    }

    /// Returns builder with linear velocity.
    pub fn with_linear_velocity(&mut self, linear_velocity: Vector3D) -> &mut Self {
        self._linear_velocity = linear_velocity;
        return self;
    }

    /// Returns builder with angular velocity.
    pub fn with_angular_velocity(&mut self, angular_velocity: Vector3D) -> &mut Self {
        self._angular_velocity = angular_velocity;
        return self;
    }

    /// Builds RigidBodyCollider3.
    pub fn build(&mut self) -> RigidBodyCollider3 {
        return RigidBodyCollider3::new_vel(self._surface.as_ref().unwrap().clone(),
                                           self._linear_velocity,
                                           self._angular_velocity);
    }

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

    /// constructor
    pub fn new() -> Builder {
        return Builder {
            _surface: None,
            _linear_velocity: Vector3D::new_default(),
            _angular_velocity: Vector3D::new_default(),
        };
    }
}