rapier2d/dynamics/joint/
pin_slot_joint.rs

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