wrapped2d/dynamics/joints/
mod.rs1macro_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 unsafe { ffi::Joint_get_body_a(self.base_ptr() as *mut _).handle() }
146 }
147
148 fn body_b(&self) -> BodyHandle {
149 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_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}