Skip to main content

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