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