1use crate::b2_body::*;
2use crate::b2_draw::*;
3use crate::b2_math::*;
4use crate::b2_common::*;
5use crate::b2rs_common::UserDataType;
6use crate::b2_time_step::*;
7
8use crate::b2rs_double_linked_list::*;
9use crate::b2rs_linked_list::*;
10
11use std::cell::RefCell;
12use std::rc::{Rc, Weak};
13
14#[cfg(feature="serde_support")]
15use serde::{Serialize, Deserialize};
16
17use crate::joints::b2_distance_joint::*;
18use crate::joints::b2_friction_joint::*;
19use crate::joints::b2_gear_joint::*;
20use crate::joints::b2_motor_joint::*;
21use crate::joints::b2_mouse_joint::*;
22use crate::joints::b2_prismatic_joint::*;
23use crate::joints::b2_pulley_joint::*;
24use crate::joints::b2_revolute_joint::*;
25use crate::joints::b2_weld_joint::*;
26use crate::joints::b2_wheel_joint::*;
27
28use crate::private::dynamics::b2_joint as private;
29
30pub enum B2JointDefEnum<D: UserDataType> {
31 DistanceJoint(B2distanceJointDef<D>),
32 FrictionJoint(B2frictionJointDef<D>),
33 GearJoint(B2gearJointDef<D>),
34 MouseJoint(B2mouseJointDef<D>),
35 MotorJoint(B2motorJointDef<D>),
36 PulleyJoint(B2pulleyJointDef<D>),
37 RevoluteJoint(B2revoluteJointDef<D>),
38 PrismaticJoint(B2prismaticJointDef<D>),
39 WeldJoint(B2weldJointDef<D>),
40 WheelJoint(B2wheelJointDef<D>),
41}
42
43
44#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
45#[derive(Debug, Clone, Copy, PartialEq)]
46pub enum B2jointType {
47 EUnknownJoint,
48 EDistanceJoint,
49 EFrictionJoint,
50 EGearJoint,
51 EMotorJoint,
52 EMouseJoint,
53 EPrismaticJoint,
54 EPulleyJoint,
55 ERevoluteJoint,
56 EWeldJoint,
57 EWheelJoint,
58}
59
60impl Default for B2jointType {
61 fn default() -> Self {
62 return B2jointType::EUnknownJoint;
63 }
64}
65
66pub type B2jointEdgePtr<D> = Rc<RefCell<B2jointEdge<D>>>;
75pub type B2jointEdgeWeakPtr<D> = Weak<RefCell<B2jointEdge<D>>>;
76
77impl<D: UserDataType> LinkedListNode<B2jointEdge<D>> for B2jointEdge<D> {
78 fn get_next(&self) -> Option<B2jointEdgePtr<D>> {
79 return self.next.clone();
80 }
81 fn set_next(&mut self, value: Option<B2jointEdgePtr<D>>) {
82 self.next = value;
83 }
84 fn take_next(&mut self) -> Option<B2jointEdgePtr<D>> {
85 return self.next.take();
86 }
87}
88
89impl<D: UserDataType> DoubleLinkedListNode<B2jointEdge<D>> for B2jointEdge<D> {
90 fn get_prev(&self) -> Option<B2jointEdgeWeakPtr<D>> {
91 return self.prev.clone();
92 }
93 fn set_prev(&mut self, value: Option<B2jointEdgeWeakPtr<D>>) {
94 self.prev = value;
95 }
96}
97
98pub struct B2jointEdge<D: UserDataType> {
104 pub(crate) other: BodyWeakPtr<D>,
106 pub(crate) joint: B2jointWeakPtr<D>,
108 pub(crate) prev: Option<B2jointEdgeWeakPtr<D>>,
110 pub(crate) next: Option<B2jointEdgePtr<D>>,
112}
113
114impl<D: UserDataType> Default for B2jointDef<D> {
115 fn default() -> Self {
116 return Self {
117 jtype: B2jointType::EUnknownJoint,
118 user_data: None,
119 body_a: None,
120 body_b: None,
121 collide_connected: false,
122 };
123 }
124}
125
126impl<D: UserDataType> LinkedListNode<dyn B2jointTraitDyn<D>> for dyn B2jointTraitDyn<D> {
127 fn get_next(&self) -> Option<B2jointPtr<D>> {
128 return self.get_base().m_next.clone();
129 }
130 fn set_next(&mut self, value: Option<B2jointPtr<D>>) {
131 self.get_base_mut().m_next = value;
132 }
133 fn take_next(&mut self) -> Option<B2jointPtr<D>> {
134 return self.get_base_mut().m_next.take();
135 }
136}
137
138impl<D: UserDataType> DoubleLinkedListNode<dyn B2jointTraitDyn<D>> for dyn B2jointTraitDyn<D> {
139 fn get_prev(&self) -> Option<B2jointWeakPtr<D>> {
140 return self.get_base().m_prev.clone();
141 }
142 fn set_prev(&mut self, value: Option<B2jointWeakPtr<D>>) {
143 self.get_base_mut().m_prev = value.clone();
144 }
145}
146
147#[derive(Clone)]
149pub struct B2jointDef<D: UserDataType> {
150 pub jtype: B2jointType,
152
153 pub user_data: Option<D::Joint>,
155
156 pub body_a: Option<BodyPtr<D>>,
158
159 pub body_b: Option<BodyPtr<D>>,
161
162 pub collide_connected: bool,
164}
165
166pub type B2jointPtr<D> = Rc<RefCell<dyn B2jointTraitDyn<D>>>;
167pub type B2jointWeakPtr<D> = Weak<RefCell<dyn B2jointTraitDyn<D>>>;
168
169
170pub fn b2_linear_stiffness<D: UserDataType>(stiffness: &mut f32, damping: &mut f32,
172 frequency_hertz: f32, damping_ratio: f32,
173 body_a: BodyPtr<D>, body_b: BodyPtr<D>)
174{
175 private::b2_linear_stiffness(stiffness, damping, frequency_hertz, damping_ratio, body_a, body_b);
176}
177
178pub fn b2_angular_stiffness<D: UserDataType>(stiffness: &mut f32, damping: &mut f32,
180 frequency_hertz: f32, damping_ratio: f32,
181 body_a: BodyPtr<D>, body_b: BodyPtr<D>)
182{
183 private::b2_angular_stiffness(stiffness, damping, frequency_hertz, damping_ratio, body_a, body_b);
184}
185
186
187impl<D: UserDataType> B2joint<D> {
190 pub fn get_type(&self) -> B2jointType {
192 return self.m_type;
193 }
194
195 pub fn get_body_a(&self) -> BodyPtr<D> {
197 return self.m_body_a.clone();
198 }
199
200 pub fn get_body_b(&self) -> BodyPtr<D> {
202 return self.m_body_b.clone();
203 }
204
205 pub fn get_next(&self) -> B2jointPtr<D> {
207 return self.m_next.as_ref().unwrap().clone();
208 }
209
210 pub fn get_user_data(&self) -> Option<D::Joint> {
212 return self.m_user_data.clone();
213 }
214
215 pub fn set_user_data(&mut self, data: D::Joint) {
217 self.m_user_data = Some(data);
218 }
219
220 pub fn is_enabled(&self) -> bool {
222 return private::is_enabled(self);
223 }
224
225 pub fn get_collide_connected(&self) -> bool {
229 return self.m_collide_connected;
230 }
231
232 pub(crate) fn create(def: &B2JointDefEnum<D>) -> B2jointPtr<D> {
236 return private::create(def);
237 }
238 pub(crate) fn new(def: &B2jointDef<D>) -> B2joint<D> {
239 return private::new(def);
240 }
241}
242
243pub trait B2jointTraitDyn<D: UserDataType>: ToDerivedJoint<D> {
244 fn get_base(&self) -> &B2joint<D>;
245 fn get_base_mut(&mut self) -> &mut B2joint<D>;
246 fn get_anchor_a(&self) -> B2vec2;
248
249 fn get_anchor_b(&self) -> B2vec2;
251
252 fn get_reaction_force(&self, inv_dt: f32) -> B2vec2;
254
255 fn get_reaction_torque(&self, inv_dt: f32) -> f32;
257
258 fn shift_origin(&mut self, new_origin: B2vec2) {
260 b2_not_used(new_origin);
261 }
262
263 fn draw(&self, draw: &mut dyn B2drawTrait) {
265 private::draw(self, draw);
266 }
267
268 fn init_velocity_constraints(
269 &mut self,
270 data: &B2solverData,
271 positions: &[B2position],
272 velocities: &mut [B2velocity],
273 );
274 fn solve_velocity_constraints(
275 &mut self,
276 data: &B2solverData,
277 velocities: &mut [B2velocity],
278 );
279
280 fn solve_position_constraints(
282 &mut self,
283 data: &B2solverData,
284 positions: &mut [B2position],
285 ) -> bool;
286}
287
288pub trait ToDerivedJoint<D: UserDataType> {
289 fn as_derived(&self) -> JointAsDerived<D>;
290 fn as_derived_mut(&mut self) -> JointAsDerivedMut<D>;
291}
292
293pub enum JointAsDerived<'a, D: UserDataType> {
294 EDistanceJoint(&'a B2distanceJoint<D>),
295 EFrictionJoint(&'a B2frictionJoint<D>),
296 EGearJoint(&'a B2gearJoint<D>),
297 EMouseJoint(&'a B2mouseJoint<D>),
298 EMotorJoint(&'a B2motorJoint<D>),
299 EPulleyJoint(&'a B2pulleyJoint<D>),
300 ERevoluteJoint(&'a B2revoluteJoint<D>),
301 EPrismaticJoint(&'a B2prismaticJoint<D>),
302 EWeldJoint(&'a B2weldJoint<D>),
303 EWheelJoint(&'a B2wheelJoint<D>),
304}
305
306pub enum JointAsDerivedMut<'a, D: UserDataType> {
307 EDistanceJoint(&'a mut B2distanceJoint<D>),
308 EFrictionJoint(&'a mut B2frictionJoint<D>),
309 EGearJoint(&'a mut B2gearJoint<D>),
310 EMouseJoint(&'a mut B2mouseJoint<D>),
311 EMotorJoint(&'a mut B2motorJoint<D>),
312 EPulleyJoint(&'a mut B2pulleyJoint<D>),
313 ERevoluteJoint(&'a mut B2revoluteJoint<D>),
314 EPrismaticJoint(&'a mut B2prismaticJoint<D>),
315 EWeldJoint(&'a mut B2weldJoint<D>),
316 EWheelJoint(&'a mut B2wheelJoint<D>),
317}
318
319#[derive(Clone)]
320pub struct B2joint<D: UserDataType> {
321 pub(crate) m_type: B2jointType,
323 pub(crate) m_prev: Option<B2jointWeakPtr<D>>,
324 pub(crate) m_next: Option<B2jointPtr<D>>,
325 pub(crate) m_edge_a: Option<B2jointEdgePtr<D>>,
326 pub(crate) m_edge_b: Option<B2jointEdgePtr<D>>,
327 pub(crate) m_body_a: BodyPtr<D>,
328 pub(crate) m_body_b: BodyPtr<D>,
329
330 pub(crate) m_index: i32,
331
332 pub(crate) m_island_flag: bool,
333 pub(crate) m_collide_connected: bool,
334
335 pub(crate) m_user_data: Option<D::Joint>,
336}