use crate::b2_body::*;
use crate::b2_draw::*;
use crate::b2_math::*;
use crate::b2_settings::*;
use crate::b2_time_step::*;
use crate::double_linked_list::*;
use crate::linked_list::*;
use std::cell::RefCell;
use std::rc::{Rc, Weak};
use crate::joints::b2_distance_joint::*;
use crate::joints::b2_friction_joint::*;
use crate::joints::b2_gear_joint::*;
use crate::joints::b2_motor_joint::*;
use crate::joints::b2_mouse_joint::*;
use crate::joints::b2_prismatic_joint::*;
use crate::joints::b2_pulley_joint::*;
use crate::joints::b2_revolute_joint::*;
use crate::joints::b2_rope_joint::*;
use crate::joints::b2_weld_joint::*;
use crate::joints::b2_wheel_joint::*;
use crate::private::dynamics::b2_joint as private;
pub enum B2JointDefEnum<D: UserDataType> {
DistanceJoint(B2distanceJointDef<D>),
FrictionJoint(B2frictionJointDef<D>),
GearJoint(B2gearJointDef<D>),
MouseJoint(B2mouseJointDef<D>),
MotorJoint(B2motorJointDef<D>),
PulleyJoint(B2pulleyJointDef<D>),
RevoluteJoint(B2revoluteJointDef<D>),
RopeJoint(B2ropeJointDef<D>),
PrismaticJoint(B2prismaticJointDef<D>),
WeldJoint(B2weldJointDef<D>),
WheelJoint(B2wheelJointDef<D>),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum B2jointType {
EUnknownJoint,
EDistanceJoint,
EFrictionJoint,
EGearJoint,
EMotorJoint,
EMouseJoint,
EPrismaticJoint,
EPulleyJoint,
ERevoluteJoint,
ERopeJoint,
EWeldJoint,
EWheelJoint,
}
impl Default for B2jointType {
fn default() -> Self {
return B2jointType::EUnknownJoint;
}
}
#[derive(Default, Clone, Copy, Debug)]
pub(crate) struct B2jacobian {
linear: B2vec2,
angular_a: f32,
angular_b: f32,
}
pub type B2jointEdgePtr<D> = Rc<RefCell<B2jointEdge<D>>>;
pub type B2jointEdgeWeakPtr<D> = Weak<RefCell<B2jointEdge<D>>>;
impl<D: UserDataType> LinkedListNode<B2jointEdge<D>> for B2jointEdge<D> {
fn get_next(&self) -> Option<B2jointEdgePtr<D>> {
return self.next.clone();
}
fn set_next(&mut self, value: Option<B2jointEdgePtr<D>>) {
self.next = value;
}
fn take_next(&mut self) -> Option<B2jointEdgePtr<D>> {
return self.next.take();
}
}
impl<D: UserDataType> DoubleLinkedListNode<B2jointEdge<D>> for B2jointEdge<D> {
fn get_prev(&self) -> Option<B2jointEdgeWeakPtr<D>> {
return self.prev.clone();
}
fn set_prev(&mut self, value: Option<B2jointEdgeWeakPtr<D>>) {
self.prev = value;
}
}
pub struct B2jointEdge<D: UserDataType> {
pub(crate) other: BodyWeakPtr<D>,
pub(crate) joint: B2jointWeakPtr<D>,
pub(crate) prev: Option<B2jointEdgeWeakPtr<D>>,
pub(crate) next: Option<B2jointEdgePtr<D>>,
}
impl<D: UserDataType> Default for B2jointDef<D> {
fn default() -> Self {
return Self {
jtype: B2jointType::EUnknownJoint,
user_data: None,
body_a: None,
body_b: None,
collide_connected: false,
};
}
}
impl<D: UserDataType> LinkedListNode<dyn B2jointTraitDyn<D>> for dyn B2jointTraitDyn<D> {
fn get_next(&self) -> Option<B2jointPtr<D>> {
return self.get_base().m_next.clone();
}
fn set_next(&mut self, value: Option<B2jointPtr<D>>) {
self.get_base_mut().m_next = value;
}
fn take_next(&mut self) -> Option<B2jointPtr<D>> {
return self.get_base_mut().m_next.take();
}
}
impl<D: UserDataType> DoubleLinkedListNode<dyn B2jointTraitDyn<D>> for dyn B2jointTraitDyn<D> {
fn get_prev(&self) -> Option<B2jointWeakPtr<D>> {
return self.get_base().m_prev.clone();
}
fn set_prev(&mut self, value: Option<B2jointWeakPtr<D>>) {
self.get_base_mut().m_prev = value.clone();
}
}
#[derive(Clone)]
pub struct B2jointDef<D: UserDataType> {
pub jtype: B2jointType,
pub user_data: Option<D::Joint>,
pub body_a: Option<BodyPtr<D>>,
pub body_b: Option<BodyPtr<D>>,
pub collide_connected: bool,
}
pub type B2jointPtr<D> = Rc<RefCell<dyn B2jointTraitDyn<D>>>;
pub type B2jointWeakPtr<D> = Weak<RefCell<dyn B2jointTraitDyn<D>>>;
pub fn b2_linear_stiffness<D: UserDataType>(stiffness: &mut f32, damping: &mut f32,
frequency_hertz: f32, damping_ratio: f32,
body_a: BodyPtr<D>, body_b: BodyPtr<D>)
{
private::b2_linear_stiffness(stiffness, damping, frequency_hertz, damping_ratio, body_a, body_b);
}
pub fn b2_angular_stiffness<D: UserDataType>(stiffness: &mut f32, damping: &mut f32,
frequency_hertz: f32, damping_ratio: f32,
body_a: BodyPtr<D>, body_b: BodyPtr<D>)
{
private::b2_angular_stiffness(stiffness, damping, frequency_hertz, damping_ratio, body_a, body_b);
}
impl<D: UserDataType> B2joint<D> {
pub fn get_type(&self) -> B2jointType {
return self.m_type;
}
pub fn get_body_a(&self) -> BodyPtr<D> {
return self.m_body_a.clone();
}
pub fn get_body_b(&self) -> BodyPtr<D> {
return self.m_body_b.clone();
}
pub fn get_next(&self) -> B2jointPtr<D> {
return self.m_next.as_ref().unwrap().clone();
}
pub fn get_user_data(&self) -> Option<D::Joint> {
return self.m_user_data.clone();
}
pub fn set_user_data(&mut self, data: D::Joint) {
self.m_user_data = Some(data);
}
pub fn is_enabled(&self) -> bool {
return private::is_enabled(self);
}
pub fn get_collide_connected(&self) -> bool {
return self.m_collide_connected;
}
pub(crate) fn create(def: &B2JointDefEnum<D>) -> B2jointPtr<D> {
return private::create(def);
}
pub(crate) fn new(def: &B2jointDef<D>) -> B2joint<D> {
return private::new(def);
}
}
pub trait B2jointTraitDyn<D: UserDataType>: ToDerivedJoint<D> {
fn get_base(&self) -> &B2joint<D>;
fn get_base_mut(&mut self) -> &mut B2joint<D>;
fn get_anchor_a(&self) -> B2vec2;
fn get_anchor_b(&self) -> B2vec2;
fn get_reaction_force(&self, inv_dt: f32) -> B2vec2;
fn get_reaction_torque(&self, inv_dt: f32) -> f32;
fn dump(&self) {
}
fn shift_origin(&mut self, new_origin: B2vec2) {
b2_not_used(new_origin);
}
fn draw(&self, draw: &mut dyn B2drawTrait) {
private::draw(self, draw);
}
fn init_velocity_constraints(
&mut self,
data: &mut B2solverData,
positions: &mut [B2position],
velocities: &mut [B2velocity],
);
fn solve_velocity_constraints(
&mut self,
data: &mut B2solverData,
velocities: &mut [B2velocity],
);
fn solve_position_constraints(
&mut self,
data: &mut B2solverData,
positions: &mut [B2position],
) -> bool;
}
pub trait ToDerivedJoint<D: UserDataType> {
fn as_derived(&self) -> JointAsDerived<D>;
fn as_derived_mut(&mut self) -> JointAsDerivedMut<D>;
}
pub enum JointAsDerived<'a, D: UserDataType> {
EDistanceJoint(&'a B2distanceJoint<D>),
EFrictionJoint(&'a B2frictionJoint<D>),
EGearJoint(&'a B2gearJoint<D>),
EMouseJoint(&'a B2mouseJoint<D>),
EMotorJoint(&'a B2motorJoint<D>),
EPulleyJoint(&'a B2pulleyJoint<D>),
ERevoluteJoint(&'a B2revoluteJoint<D>),
ERopeJoint(&'a B2ropeJoint<D>),
EPrismaticJoint(&'a B2prismaticJoint<D>),
EWeldJoint(&'a B2weldJoint<D>),
EWheelJoint(&'a B2wheelJoint<D>),
}
pub enum JointAsDerivedMut<'a, D: UserDataType> {
EDistanceJoint(&'a mut B2distanceJoint<D>),
EFrictionJoint(&'a mut B2frictionJoint<D>),
EGearJoint(&'a mut B2gearJoint<D>),
EMouseJoint(&'a mut B2mouseJoint<D>),
EMotorJoint(&'a mut B2motorJoint<D>),
EPulleyJoint(&'a mut B2pulleyJoint<D>),
ERevoluteJoint(&'a mut B2revoluteJoint<D>),
ERopeJoint(&'a mut B2ropeJoint<D>),
EPrismaticJoint(&'a mut B2prismaticJoint<D>),
EWeldJoint(&'a mut B2weldJoint<D>),
EWheelJoint(&'a mut B2wheelJoint<D>),
}
#[derive(Clone)]
pub struct B2joint<D: UserDataType> {
pub(crate) m_type: B2jointType,
pub(crate) m_prev: Option<B2jointWeakPtr<D>>,
pub(crate) m_next: Option<B2jointPtr<D>>,
pub(crate) m_edge_a: Option<B2jointEdgePtr<D>>,
pub(crate) m_edge_b: Option<B2jointEdgePtr<D>>,
pub(crate) m_body_a: BodyPtr<D>,
pub(crate) m_body_b: BodyPtr<D>,
pub(crate) m_index: i32,
pub(crate) m_island_flag: bool,
pub(crate) m_collide_connected: bool,
pub(crate) m_user_data: Option<D::Joint>,
}