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::surface2::*;
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 RigidBodyCollider2, f64, f64);

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

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

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

impl RigidBodyCollider2 {
    /// Constructs a collider with a surface.
    pub fn new(surface: Surface2Ptr) -> RigidBodyCollider2 {
        return RigidBodyCollider2 {
            linear_velocity: Vector2D::new_default(),
            angular_velocity: 0.0,
            _collider_data: Collider2Data::new(Some(surface)),
            _on_update_callback: None,
        };
    }

    /// Constructs a collider with a surface and other parameters.
    pub fn new_vel(
        surface: Surface2Ptr,
        linear_velocity: Vector2D,
        angular_velocity: f64) -> RigidBodyCollider2 {
        return RigidBodyCollider2 {
            linear_velocity,
            angular_velocity,
            _collider_data: Collider2Data::new(Some(surface)),
            _on_update_callback: None,
        };
    }

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

    ///
    /// \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 RigidBodyCollider2 {
    fn velocity_at(&self, point: &Vector2D) -> Vector2D {
        let r = *point - self.surface().read().unwrap().view().transform.translation();
        return self.linear_velocity + Vector2D::new(-r.y, r.x) * self.angular_velocity;
    }

    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 RigidBodyCollider2 type.
pub type RigidBodyCollider2Ptr = Arc<RwLock<RigidBodyCollider2>>;

///
/// # Front-end to create RigidBodyCollider2 objects step by step.
///
pub struct Builder {
    _surface: Option<Surface2Ptr>,
    _linear_velocity: Vector2D,
    _angular_velocity: f64,
}

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

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

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

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

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

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