wrapped2d/dynamics/joints/
mod.rs

1macro_rules! wrap_joint {
2    {
3        $wrapped:ty => $wrap:ident ($joint_type:path)
4        < $as_base:path
5        > $base_as:path
6    } => {
7        wrap! {
8            ffi::Joint: $wrapped => pub $wrap
9            < $as_base
10            > $base_as
11        }
12
13        impl Joint for $wrap {
14            fn assumed_type() -> JointType { $joint_type }
15        }
16    };
17}
18
19pub mod distance;
20pub mod friction;
21pub mod gear;
22pub mod motor;
23pub mod mouse;
24pub mod prismatic;
25pub mod pulley;
26pub mod revolute;
27pub mod rope;
28pub mod weld;
29pub mod wheel;
30
31pub use self::distance::{DistanceJoint, DistanceJointDef};
32pub use self::friction::{FrictionJoint, FrictionJointDef};
33pub use self::gear::{GearJoint, GearJointDef};
34pub use self::motor::{MotorJoint, MotorJointDef};
35pub use self::mouse::{MouseJoint, MouseJointDef};
36pub use self::prismatic::{PrismaticJoint, PrismaticJointDef};
37pub use self::pulley::{PulleyJoint, PulleyJointDef};
38pub use self::revolute::{RevoluteJoint, RevoluteJointDef};
39pub use self::rope::{RopeJoint, RopeJointDef};
40pub use self::weld::{WeldJoint, WeldJointDef};
41pub use self::wheel::{WheelJoint, WheelJointDef};
42
43
44use std::ops::{Deref, DerefMut};
45use wrap::*;
46use common::math::Vec2;
47use dynamics::world::{World, BodyHandle, JointHandle};
48use user_data::{UserDataTypes, UserData, RawUserData, RawUserDataMut, InternalUserData};
49
50#[repr(C)]
51#[derive(Copy, Clone, PartialEq, Debug)]
52pub enum JointType {
53    Unknown,
54    Revolute,
55    Prismatic,
56    Distance,
57    Pulley,
58    Mouse,
59    Gear,
60    Wheel,
61    Weld,
62    Friction,
63    Rope,
64    Motor,
65}
66
67#[repr(C)]
68#[derive(Copy, Clone, PartialEq, Debug)]
69pub enum LimitState {
70    Inactive,
71    Lower,
72    Upper,
73    Equal,
74}
75
76pub trait JointDef {
77    fn joint_type() -> JointType where Self: Sized;
78
79    #[doc(hidden)]
80    unsafe fn create<U: UserDataTypes>(&self, world: &mut World<U>) -> *mut ffi::Joint;
81    
82    #[doc(hidden)]
83    unsafe fn try_create<U: UserDataTypes>(&self, world: &mut World<U>) -> Option<*mut ffi::Joint> {
84        Some(self.create(world))
85    }
86}
87
88pub struct MetaJoint<U: UserDataTypes> {
89    joint: UnknownJoint,
90    user_data: Box<InternalUserData<dyn Joint, U::JointData>>,
91}
92
93impl<U: UserDataTypes> MetaJoint<U> {
94    #[doc(hidden)]
95    pub unsafe fn new(ptr: *mut ffi::Joint, handle: JointHandle, custom: U::JointData) -> Self {
96        let mut j = MetaJoint {
97            joint: UnknownJoint::from_ffi(ptr),
98            user_data: Box::new(InternalUserData {
99                handle: handle,
100                custom: custom,
101            }),
102        };
103        j.mut_base_ptr().set_internal_user_data(&mut *j.user_data);
104        j
105    }
106}
107
108impl<U: UserDataTypes> UserData<U::JointData> for MetaJoint<U> {
109    fn user_data(&self) -> &U::JointData {
110        &self.user_data.custom
111    }
112
113    fn user_data_mut(&mut self) -> &mut U::JointData {
114        &mut self.user_data.custom
115    }
116}
117
118impl<U: UserDataTypes> Deref for MetaJoint<U> {
119    type Target = UnknownJoint;
120
121    fn deref(&self) -> &UnknownJoint {
122        &self.joint
123    }
124}
125
126impl<U: UserDataTypes> DerefMut for MetaJoint<U> {
127    fn deref_mut(&mut self) -> &mut UnknownJoint {
128        &mut self.joint
129    }
130}
131
132pub trait Joint: WrappedBase<ffi::Joint> + FromFFI<ffi::Joint> {
133    fn handle(&self) -> JointHandle {
134        unsafe { self.base_ptr().handle() }
135    }
136    
137    fn assumed_type() -> JointType where Self: Sized;
138
139    fn get_type(&self) -> JointType {
140        unsafe { ffi::Joint_get_type(self.base_ptr()) }
141    }
142
143    fn body_a(&self) -> BodyHandle {
144        // we don't need &mut self because nothing is actually mutated here
145        unsafe { ffi::Joint_get_body_a(self.base_ptr() as *mut _).handle() }
146    }
147
148    fn body_b(&self) -> BodyHandle {
149        // we don't need &mut self because nothing is actually mutated here
150        unsafe { ffi::Joint_get_body_b(self.base_ptr() as *mut _).handle() }
151    }
152
153    fn anchor_a(&self) -> Vec2 {
154        unsafe { ffi::Joint_get_anchor_a_virtual(self.base_ptr()) }
155    }
156
157    fn anchor_b(&self) -> Vec2 {
158        unsafe { ffi::Joint_get_anchor_b_virtual(self.base_ptr()) }
159    }
160
161    fn reaction_force(&self) -> Vec2 {
162        unsafe { ffi::Joint_get_reaction_force_virtual(self.base_ptr()) }
163    }
164
165    fn reaction_torque(&self) -> f32 {
166        unsafe { ffi::Joint_get_reaction_torque_virtual(self.base_ptr()) }
167    }
168
169    fn is_active(&self) -> bool {
170        unsafe { ffi::Joint_is_active(self.base_ptr()) }
171    }
172
173    fn is_collide_connected(&self) -> bool {
174        unsafe { ffi::Joint_get_collide_connected(self.base_ptr()) }
175    }
176
177    fn dump(&mut self) {
178        unsafe { ffi::Joint_dump_virtual(self.mut_base_ptr()) }
179    }
180
181    fn shift_origin(&mut self, origin: &Vec2) {
182        unsafe { ffi::Joint_shift_origin_virtual(self.mut_base_ptr(), origin) }
183    }
184}
185
186#[repr(C)]
187#[doc(hidden)]
188pub struct JointEdge {
189    pub other: *mut ffi::Body,
190    pub joint: *mut ffi::Joint,
191    pub prev: *mut JointEdge,
192    pub next: *mut JointEdge,
193}
194
195pub enum UnknownJoint {
196    Unknown,
197    Revolute(RevoluteJoint),
198    Prismatic(PrismaticJoint),
199    Distance(DistanceJoint),
200    Pulley(PulleyJoint),
201    Mouse(MouseJoint),
202    Gear(GearJoint),
203    Wheel(WheelJoint),
204    Weld(WeldJoint),
205    Friction(FrictionJoint),
206    Rope(RopeJoint),
207    Motor(MotorJoint),
208}
209
210impl WrappedBase<ffi::Joint> for UnknownJoint {
211    unsafe fn base_ptr(&self) -> *const ffi::Joint {
212        use self::UnknownJoint::*;
213        match self {
214            &Distance(ref x) => x.base_ptr(),
215            &Friction(ref x) => x.base_ptr(),
216            &Gear(ref x) => x.base_ptr(),
217            &Motor(ref x) => x.base_ptr(),
218            &Mouse(ref x) => x.base_ptr(),
219            &Prismatic(ref x) => x.base_ptr(),
220            &Pulley(ref x) => x.base_ptr(),
221            &Revolute(ref x) => x.base_ptr(),
222            &Rope(ref x) => x.base_ptr(),
223            &Weld(ref x) => x.base_ptr(),
224            &Wheel(ref x) => x.base_ptr(),
225            _ => panic!("Truly unknown joint"),
226        }
227    }
228
229    unsafe fn mut_base_ptr(&mut self) -> *mut ffi::Joint {
230        use self::UnknownJoint::*;
231        match self {
232            &mut Distance(ref mut x) => x.mut_base_ptr(),
233            &mut Friction(ref mut x) => x.mut_base_ptr(),
234            &mut Gear(ref mut x) => x.mut_base_ptr(),
235            &mut Motor(ref mut x) => x.mut_base_ptr(),
236            &mut Mouse(ref mut x) => x.mut_base_ptr(),
237            &mut Prismatic(ref mut x) => x.mut_base_ptr(),
238            &mut Pulley(ref mut x) => x.mut_base_ptr(),
239            &mut Revolute(ref mut x) => x.mut_base_ptr(),
240            &mut Rope(ref mut x) => x.mut_base_ptr(),
241            &mut Weld(ref mut x) => x.mut_base_ptr(),
242            &mut Wheel(ref mut x) => x.mut_base_ptr(),
243            _ => panic!("Truly unknown joint"),
244        }
245    }
246}
247
248impl FromFFI<ffi::Joint> for UnknownJoint {
249    unsafe fn from_ffi(ptr: *mut ffi::Joint) -> UnknownJoint {
250        use self::UnknownJoint::*;
251        assert!(!ptr.is_null());
252        let joint_type = ffi::Joint_get_type(ptr as *const ffi::Joint);
253        match joint_type {
254            JointType::Revolute => Revolute(RevoluteJoint::from_ffi(ptr)),
255            JointType::Prismatic => Prismatic(PrismaticJoint::from_ffi(ptr)),
256            JointType::Distance => Distance(DistanceJoint::from_ffi(ptr)),
257            JointType::Pulley => Pulley(PulleyJoint::from_ffi(ptr)),
258            JointType::Mouse => Mouse(MouseJoint::from_ffi(ptr)),
259            JointType::Gear => Gear(GearJoint::from_ffi(ptr)),
260            JointType::Wheel => Wheel(WheelJoint::from_ffi(ptr)),
261            JointType::Weld => Weld(WeldJoint::from_ffi(ptr)),
262            JointType::Friction => Friction(FrictionJoint::from_ffi(ptr)),
263            JointType::Rope => Rope(RopeJoint::from_ffi(ptr)),
264            JointType::Motor => Motor(MotorJoint::from_ffi(ptr)),
265            _ => Unknown,
266        }
267    }
268}
269
270impl Joint for UnknownJoint {
271    fn assumed_type() -> JointType {
272        JointType::Unknown
273    }
274}
275
276
277#[doc(hidden)]
278pub mod ffi {
279    pub use ffi::Any;
280    pub use dynamics::body::ffi::Body;
281    use common::math::Vec2;
282    use super::JointType;
283
284    pub enum Joint {}
285
286    extern "C" {
287        pub fn Joint_get_type(slf: *const Joint) -> JointType;
288        pub fn Joint_get_body_a(slf: *mut Joint) -> *mut Body;
289        pub fn Joint_get_body_b(slf: *mut Joint) -> *mut Body;
290        pub fn Joint_get_anchor_a_virtual(slf: *const Joint) -> Vec2;
291        pub fn Joint_get_anchor_b_virtual(slf: *const Joint) -> Vec2;
292        pub fn Joint_get_reaction_force_virtual(slf: *const Joint) -> Vec2;
293        pub fn Joint_get_reaction_torque_virtual(slf: *const Joint) -> f32;
294        // pub fn Joint_get_next(slf: *mut Joint) -> *mut Joint;
295        // pub fn Joint_get_next_const(slf: *const Joint) -> *const Joint;
296        pub fn Joint_is_active(slf: *const Joint) -> bool;
297        pub fn Joint_get_collide_connected(slf: *const Joint) -> bool;
298        pub fn Joint_dump_virtual(slf: *mut Joint);
299        pub fn Joint_shift_origin_virtual(slf: *mut Joint, origin: *const Vec2);
300    }
301}