use std::marker::PhantomData;
use std::rc::Rc;
use std::sync::Arc;
use crate::core::world_core::WorldCore;
use crate::types::{BodyId, JointId, Vec2};
use crate::world::World;
use boxdd_sys::ffi;
mod owned;
mod runtime_handle;
mod scoped;
mod user_data;
pub struct Joint<'w> {
pub(crate) id: JointId,
pub(crate) core: Arc<crate::core::world_core::WorldCore>,
pub(crate) _world: PhantomData<&'w World>,
}
pub struct OwnedJoint {
id: JointId,
core: Arc<WorldCore>,
destroy_on_drop: bool,
wake_bodies_on_drop: bool,
_not_send: PhantomData<Rc<()>>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum JointType {
Distance,
Filter,
Motor,
Prismatic,
Revolute,
Weld,
Wheel,
}
impl JointType {
#[inline]
pub const fn from_raw(raw: ffi::b2JointType) -> Option<Self> {
match raw {
ffi::b2JointType_b2_distanceJoint => Some(Self::Distance),
ffi::b2JointType_b2_filterJoint => Some(Self::Filter),
ffi::b2JointType_b2_motorJoint => Some(Self::Motor),
ffi::b2JointType_b2_prismaticJoint => Some(Self::Prismatic),
ffi::b2JointType_b2_revoluteJoint => Some(Self::Revolute),
ffi::b2JointType_b2_weldJoint => Some(Self::Weld),
ffi::b2JointType_b2_wheelJoint => Some(Self::Wheel),
_ => None,
}
}
#[inline]
pub const fn into_raw(self) -> ffi::b2JointType {
match self {
Self::Distance => ffi::b2JointType_b2_distanceJoint,
Self::Filter => ffi::b2JointType_b2_filterJoint,
Self::Motor => ffi::b2JointType_b2_motorJoint,
Self::Prismatic => ffi::b2JointType_b2_prismaticJoint,
Self::Revolute => ffi::b2JointType_b2_revoluteJoint,
Self::Weld => ffi::b2JointType_b2_weldJoint,
Self::Wheel => ffi::b2JointType_b2_wheelJoint,
}
}
}
impl TryFrom<ffi::b2JointType> for JointType {
type Error = ffi::b2JointType;
#[inline]
fn try_from(value: ffi::b2JointType) -> Result<Self, Self::Error> {
Self::from_raw(value).ok_or(value)
}
}
#[inline]
fn joint_type_from_ffi(raw: ffi::b2JointType) -> JointType {
JointType::from_raw(raw).expect("Box2D returned an unknown joint type")
}
#[inline]
fn raw_joint_id(id: JointId) -> ffi::b2JointId {
id.into_raw()
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct ConstraintTuning {
pub hertz: f32,
pub damping_ratio: f32,
}
impl ConstraintTuning {
#[inline]
pub const fn new(hertz: f32, damping_ratio: f32) -> Self {
Self {
hertz,
damping_ratio,
}
}
}
#[inline]
pub(crate) fn joint_is_valid_impl(id: JointId) -> bool {
unsafe { ffi::b2Joint_IsValid(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_type_raw_impl(id: JointId) -> ffi::b2JointType {
unsafe { ffi::b2Joint_GetType(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_type_impl(id: JointId) -> JointType {
joint_type_from_ffi(joint_type_raw_impl(id))
}
#[inline]
pub(crate) fn joint_body_a_id_impl(id: JointId) -> BodyId {
BodyId::from_raw(unsafe { ffi::b2Joint_GetBodyA(raw_joint_id(id)) })
}
#[inline]
pub(crate) fn joint_body_b_id_impl(id: JointId) -> BodyId {
BodyId::from_raw(unsafe { ffi::b2Joint_GetBodyB(raw_joint_id(id)) })
}
#[inline]
pub(crate) fn joint_linear_separation_impl(id: JointId) -> f32 {
unsafe { ffi::b2Joint_GetLinearSeparation(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_angular_separation_impl(id: JointId) -> f32 {
unsafe { ffi::b2Joint_GetAngularSeparation(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_constraint_force_impl(id: JointId) -> Vec2 {
Vec2::from_raw(unsafe { ffi::b2Joint_GetConstraintForce(raw_joint_id(id)) })
}
#[inline]
pub(crate) fn joint_constraint_torque_impl(id: JointId) -> f32 {
unsafe { ffi::b2Joint_GetConstraintTorque(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_collide_connected_impl(id: JointId) -> bool {
unsafe { ffi::b2Joint_GetCollideConnected(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_set_collide_connected_impl(id: JointId, flag: bool) {
unsafe { ffi::b2Joint_SetCollideConnected(raw_joint_id(id), flag) }
}
#[inline]
pub(crate) fn joint_constraint_tuning_impl(id: JointId) -> ConstraintTuning {
let mut hertz = 0.0f32;
let mut damping_ratio = 0.0f32;
unsafe { ffi::b2Joint_GetConstraintTuning(raw_joint_id(id), &mut hertz, &mut damping_ratio) };
ConstraintTuning::new(hertz, damping_ratio)
}
#[inline]
pub(crate) fn joint_set_constraint_tuning_impl(id: JointId, tuning: ConstraintTuning) {
unsafe {
ffi::b2Joint_SetConstraintTuning(raw_joint_id(id), tuning.hertz, tuning.damping_ratio)
}
}
#[inline]
pub(crate) fn joint_local_frame_a_impl(id: JointId) -> crate::Transform {
crate::Transform::from_raw(unsafe { ffi::b2Joint_GetLocalFrameA(raw_joint_id(id)) })
}
#[inline]
pub(crate) fn joint_local_frame_b_impl(id: JointId) -> crate::Transform {
crate::Transform::from_raw(unsafe { ffi::b2Joint_GetLocalFrameB(raw_joint_id(id)) })
}
#[inline]
pub(crate) fn joint_wake_bodies_impl(id: JointId) {
unsafe { ffi::b2Joint_WakeBodies(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_force_threshold_impl(id: JointId) -> f32 {
unsafe { ffi::b2Joint_GetForceThreshold(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_set_force_threshold_impl(id: JointId, threshold: f32) {
unsafe { ffi::b2Joint_SetForceThreshold(raw_joint_id(id), threshold) }
}
#[inline]
pub(crate) fn joint_torque_threshold_impl(id: JointId) -> f32 {
unsafe { ffi::b2Joint_GetTorqueThreshold(raw_joint_id(id)) }
}
#[inline]
pub(crate) fn joint_set_torque_threshold_impl(id: JointId, threshold: f32) {
unsafe { ffi::b2Joint_SetTorqueThreshold(raw_joint_id(id), threshold) }
}