Skip to main content

bevy_rapier2d/dynamics/
pin_slot_joint.rs

1use crate::dynamics::{GenericJoint, GenericJointBuilder};
2use crate::math::{Real, Vect};
3use rapier::dynamics::{JointAxesMask, JointAxis, JointLimits, JointMotor, MotorModel};
4
5use super::{SpringCoefficients, TypedJoint};
6
7#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
8#[derive(Copy, Clone, Debug, PartialEq)]
9#[repr(transparent)]
10/// A pin-slot joint, locks all relative motion between two bodies except for translations along the joint’s
11/// principal axis and relative rotations.
12///
13/// This joint is also known as a groove joint. It is only available in 2D.
14pub struct PinSlotJoint {
15    /// The underlying joint data.
16    pub data: GenericJoint,
17}
18
19impl PinSlotJoint {
20    /// Creates a new pin-slot joint allowing only relative rotations and relative translations along the specified axis.
21    ///
22    /// This axis is expressed in the local-space of both rigid-bodies.
23    pub fn new(axis: Vect) -> Self {
24        let data = GenericJointBuilder::new(JointAxesMask::LOCKED_PIN_SLOT_AXES)
25            .local_axis1(axis)
26            .local_axis2(axis)
27            .build();
28        Self { data }
29    }
30
31    /// Are contacts between the attached rigid-bodies enabled?
32    pub fn contacts_enabled(&self) -> bool {
33        self.data.contacts_enabled()
34    }
35
36    /// Sets whether contacts between the attached rigid-bodies are enabled.
37    pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
38        self.data.set_contacts_enabled(enabled);
39        self
40    }
41
42    /// The spring coefficients controlling the softness of this joint’s locked degrees of freedom.
43    #[must_use]
44    pub fn softness(&self) -> SpringCoefficients<Real> {
45        self.data.softness()
46    }
47
48    /// Sets the spring coefficients controlling the softness of this joint’s locked degrees of freedom.
49    pub fn set_softness(&mut self, softness: SpringCoefficients<Real>) -> &mut Self {
50        self.data.set_softness(softness);
51        self
52    }
53
54    /// The joint’s anchor, expressed in the local-space of the first rigid-body.
55    #[must_use]
56    pub fn local_anchor1(&self) -> Vect {
57        self.data.local_anchor1()
58    }
59
60    /// Sets the joint’s anchor, expressed in the local-space of the first rigid-body.
61    pub fn set_local_anchor1(&mut self, anchor1: Vect) -> &mut Self {
62        self.data.set_local_anchor1(anchor1);
63        self
64    }
65
66    /// The joint’s anchor, expressed in the local-space of the second rigid-body.
67    #[must_use]
68    pub fn local_anchor2(&self) -> Vect {
69        self.data.local_anchor2()
70    }
71
72    /// Sets the joint’s anchor, expressed in the local-space of the second rigid-body.
73    pub fn set_local_anchor2(&mut self, anchor2: Vect) -> &mut Self {
74        self.data.set_local_anchor2(anchor2);
75        self
76    }
77
78    /// The principal axis of the joint, expressed in the local-space of the first rigid-body.
79    #[must_use]
80    pub fn local_axis1(&self) -> Vect {
81        self.data.local_axis1()
82    }
83
84    /// Sets the principal axis of the joint, expressed in the local-space of the first rigid-body.
85    pub fn set_local_axis1(&mut self, axis1: Vect) -> &mut Self {
86        self.data.set_local_axis1(axis1);
87        self
88    }
89
90    /// The principal axis of the joint, expressed in the local-space of the second rigid-body.
91    #[must_use]
92    pub fn local_axis2(&self) -> Vect {
93        self.data.local_axis2()
94    }
95
96    /// Sets the principal axis of the joint, expressed in the local-space of the second rigid-body.
97    pub fn set_local_axis2(&mut self, axis2: Vect) -> &mut Self {
98        self.data.set_local_axis2(axis2);
99        self
100    }
101
102    /// The motor affecting the joint’s translational degree of freedom.
103    #[must_use]
104    pub fn motor(&self) -> Option<&JointMotor> {
105        self.data.motor(JointAxis::LinX)
106    }
107
108    /// Set the spring-like model used by the motor to reach the desired target velocity and position.
109    pub fn set_motor_model(&mut self, model: MotorModel) -> &mut Self {
110        self.data.set_motor_model(JointAxis::LinX, model);
111        self
112    }
113
114    /// Sets the target velocity this motor needs to reach.
115    pub fn set_motor_velocity(&mut self, target_vel: Real, factor: Real) -> &mut Self {
116        self.data
117            .set_motor_velocity(JointAxis::LinX, target_vel, factor);
118        self
119    }
120
121    /// Sets the target angle this motor needs to reach.
122    pub fn set_motor_position(
123        &mut self,
124        target_pos: Real,
125        stiffness: Real,
126        damping: Real,
127    ) -> &mut Self {
128        self.data
129            .set_motor_position(JointAxis::LinX, target_pos, stiffness, damping);
130        self
131    }
132
133    /// Configure both the target angle and target velocity of the motor.
134    pub fn set_motor(
135        &mut self,
136        target_pos: Real,
137        target_vel: Real,
138        stiffness: Real,
139        damping: Real,
140    ) -> &mut Self {
141        self.data
142            .set_motor(JointAxis::LinX, target_pos, target_vel, stiffness, damping);
143        self
144    }
145
146    /// Sets the maximum force the motor can deliver.
147    pub fn set_motor_max_force(&mut self, max_force: Real) -> &mut Self {
148        self.data.set_motor_max_force(JointAxis::LinX, max_force);
149        self
150    }
151
152    /// The limit distance attached bodies can translate along the joint’s principal axis.
153    #[must_use]
154    pub fn limits(&self) -> Option<&JointLimits<Real>> {
155        self.data.limits(JointAxis::LinX)
156    }
157
158    /// Sets the `[min,max]` limit distances attached bodies can translate along the joint’s principal axis.
159    pub fn set_limits(&mut self, limits: [Real; 2]) -> &mut Self {
160        self.data.set_limits(JointAxis::LinX, limits);
161        self
162    }
163}
164
165impl From<PinSlotJoint> for GenericJoint {
166    fn from(joint: PinSlotJoint) -> GenericJoint {
167        joint.data
168    }
169}
170
171/// Create pin-slot joints using the builder pattern.
172///
173/// A pin-slot joint locks all relative motion except for translations along the joint’s principal axis
174/// and relative rotations.
175#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
176#[derive(Copy, Clone, Debug, PartialEq)]
177pub struct PinSlotJointBuilder(PinSlotJoint);
178
179impl PinSlotJointBuilder {
180    /// Creates a new builder for pin-slot joints.
181    ///
182    /// This axis is expressed in the local-space of both rigid-bodies.
183    pub fn new(axis: Vect) -> Self {
184        Self(PinSlotJoint::new(axis))
185    }
186
187    /// Sets the joint’s anchor, expressed in the local-space of the first rigid-body.
188    #[must_use]
189    pub fn local_anchor1(mut self, anchor1: Vect) -> Self {
190        self.0.set_local_anchor1(anchor1);
191        self
192    }
193
194    /// Sets the joint’s anchor, expressed in the local-space of the second rigid-body.
195    #[must_use]
196    pub fn local_anchor2(mut self, anchor2: Vect) -> Self {
197        self.0.set_local_anchor2(anchor2);
198        self
199    }
200
201    /// Sets the principal axis of the joint, expressed in the local-space of the first rigid-body.
202    #[must_use]
203    pub fn local_axis1(mut self, axis1: Vect) -> Self {
204        self.0.set_local_axis1(axis1);
205        self
206    }
207
208    /// Sets the principal axis of the joint, expressed in the local-space of the second rigid-body.
209    #[must_use]
210    pub fn local_axis2(mut self, axis2: Vect) -> Self {
211        self.0.set_local_axis2(axis2);
212        self
213    }
214
215    /// Set the spring-like model used by the motor to reach the desired target velocity and position.
216    #[must_use]
217    pub fn motor_model(mut self, model: MotorModel) -> Self {
218        self.0.set_motor_model(model);
219        self
220    }
221
222    /// Sets the target velocity this motor needs to reach.
223    #[must_use]
224    pub fn motor_velocity(mut self, target_vel: Real, factor: Real) -> Self {
225        self.0.set_motor_velocity(target_vel, factor);
226        self
227    }
228
229    /// Sets the target angle this motor needs to reach.
230    #[must_use]
231    pub fn motor_position(mut self, target_pos: Real, stiffness: Real, damping: Real) -> Self {
232        self.0.set_motor_position(target_pos, stiffness, damping);
233        self
234    }
235
236    /// Configure both the target angle and target velocity of the motor.
237    #[must_use]
238    pub fn set_motor(
239        mut self,
240        target_pos: Real,
241        target_vel: Real,
242        stiffness: Real,
243        damping: Real,
244    ) -> Self {
245        self.0.set_motor(target_pos, target_vel, stiffness, damping);
246        self
247    }
248
249    /// Sets the maximum force the motor can deliver.
250    #[must_use]
251    pub fn motor_max_force(mut self, max_force: Real) -> Self {
252        self.0.set_motor_max_force(max_force);
253        self
254    }
255
256    /// Sets the `[min,max]` limit distances attached bodies can translate along the joint’s principal axis.
257    #[must_use]
258    pub fn limits(mut self, limits: [Real; 2]) -> Self {
259        self.0.set_limits(limits);
260        self
261    }
262
263    /// Sets whether contacts between the attached rigid-bodies are enabled.
264    #[must_use]
265    pub fn contacts_enabled(mut self, enabled: bool) -> Self {
266        self.0.set_contacts_enabled(enabled);
267        self
268    }
269
270    /// Sets the spring coefficients controlling the softness of this joint’s locked degrees of freedom.
271    #[must_use]
272    pub fn softness(mut self, softness: SpringCoefficients<Real>) -> Self {
273        self.0.set_softness(softness);
274        self
275    }
276
277    /// Builds the pin-slot joint.
278    #[must_use]
279    pub fn build(self) -> PinSlotJoint {
280        self.0
281    }
282}
283
284impl From<PinSlotJointBuilder> for TypedJoint {
285    fn from(joint: PinSlotJointBuilder) -> TypedJoint {
286        joint.0.into()
287    }
288}
289
290impl From<PinSlotJoint> for TypedJoint {
291    fn from(joint: PinSlotJoint) -> TypedJoint {
292        TypedJoint::PinSlotJoint(joint)
293    }
294}