rapier3d/dynamics/joint/
prismatic_joint.rs

1use crate::dynamics::joint::{GenericJoint, GenericJointBuilder, JointAxesMask};
2use crate::dynamics::{JointAxis, MotorModel};
3use crate::math::{Point, Real, UnitVector};
4
5use super::{JointLimits, JointMotor};
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: UnitVector<Real>) -> 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    /// The underlying generic joint.
29    pub fn data(&self) -> &GenericJoint {
30        &self.data
31    }
32
33    /// Are contacts between the attached rigid-bodies enabled?
34    pub fn contacts_enabled(&self) -> bool {
35        self.data.contacts_enabled
36    }
37
38    /// Sets whether contacts between the attached rigid-bodies are enabled.
39    pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
40        self.data.set_contacts_enabled(enabled);
41        self
42    }
43
44    /// The joint’s anchor, expressed in the local-space of the first rigid-body.
45    #[must_use]
46    pub fn local_anchor1(&self) -> Point<Real> {
47        self.data.local_anchor1()
48    }
49
50    /// Sets the joint’s anchor, expressed in the local-space of the first rigid-body.
51    pub fn set_local_anchor1(&mut self, anchor1: Point<Real>) -> &mut Self {
52        self.data.set_local_anchor1(anchor1);
53        self
54    }
55
56    /// The joint’s anchor, expressed in the local-space of the second rigid-body.
57    #[must_use]
58    pub fn local_anchor2(&self) -> Point<Real> {
59        self.data.local_anchor2()
60    }
61
62    /// Sets the joint’s anchor, expressed in the local-space of the second rigid-body.
63    pub fn set_local_anchor2(&mut self, anchor2: Point<Real>) -> &mut Self {
64        self.data.set_local_anchor2(anchor2);
65        self
66    }
67
68    /// The principal axis of the joint, expressed in the local-space of the first rigid-body.
69    #[must_use]
70    pub fn local_axis1(&self) -> UnitVector<Real> {
71        self.data.local_axis1()
72    }
73
74    /// Sets the principal axis of the joint, expressed in the local-space of the first rigid-body.
75    pub fn set_local_axis1(&mut self, axis1: UnitVector<Real>) -> &mut Self {
76        self.data.set_local_axis1(axis1);
77        self
78    }
79
80    /// The principal axis of the joint, expressed in the local-space of the second rigid-body.
81    #[must_use]
82    pub fn local_axis2(&self) -> UnitVector<Real> {
83        self.data.local_axis2()
84    }
85
86    /// Sets the principal axis of the joint, expressed in the local-space of the second rigid-body.
87    pub fn set_local_axis2(&mut self, axis2: UnitVector<Real>) -> &mut Self {
88        self.data.set_local_axis2(axis2);
89        self
90    }
91
92    /// The motor affecting the joint’s translational degree of freedom.
93    #[must_use]
94    pub fn motor(&self) -> Option<&JointMotor> {
95        self.data.motor(JointAxis::LinX)
96    }
97
98    /// Set the spring-like model used by the motor to reach the desired target velocity and position.
99    pub fn set_motor_model(&mut self, model: MotorModel) -> &mut Self {
100        self.data.set_motor_model(JointAxis::LinX, model);
101        self
102    }
103
104    /// Sets the target velocity this motor needs to reach.
105    pub fn set_motor_velocity(&mut self, target_vel: Real, factor: Real) -> &mut Self {
106        self.data
107            .set_motor_velocity(JointAxis::LinX, target_vel, factor);
108        self
109    }
110
111    /// Sets the target angle this motor needs to reach.
112    pub fn set_motor_position(
113        &mut self,
114        target_pos: Real,
115        stiffness: Real,
116        damping: Real,
117    ) -> &mut Self {
118        self.data
119            .set_motor_position(JointAxis::LinX, target_pos, stiffness, damping);
120        self
121    }
122
123    /// Configure both the target angle and target velocity of the motor.
124    pub fn set_motor(
125        &mut self,
126        target_pos: Real,
127        target_vel: Real,
128        stiffness: Real,
129        damping: Real,
130    ) -> &mut Self {
131        self.data
132            .set_motor(JointAxis::LinX, target_pos, target_vel, stiffness, damping);
133        self
134    }
135
136    /// Sets the maximum force the motor can deliver.
137    pub fn set_motor_max_force(&mut self, max_force: Real) -> &mut Self {
138        self.data.set_motor_max_force(JointAxis::LinX, max_force);
139        self
140    }
141
142    /// The limit distance attached bodies can translate along the joint’s principal axis.
143    #[must_use]
144    pub fn limits(&self) -> Option<&JointLimits<Real>> {
145        self.data.limits(JointAxis::LinX)
146    }
147
148    /// Sets the `[min,max]` limit distances attached bodies can translate along the joint’s principal axis.
149    pub fn set_limits(&mut self, limits: [Real; 2]) -> &mut Self {
150        self.data.set_limits(JointAxis::LinX, limits);
151        self
152    }
153}
154
155impl From<PrismaticJoint> for GenericJoint {
156    fn from(val: PrismaticJoint) -> GenericJoint {
157        val.data
158    }
159}
160
161/// Create prismatic joints using the builder pattern.
162///
163/// A prismatic joint locks all relative motion except for translations along the joint’s principal axis.
164#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
165#[derive(Copy, Clone, Debug, PartialEq)]
166pub struct PrismaticJointBuilder(pub PrismaticJoint);
167
168impl PrismaticJointBuilder {
169    /// Creates a new builder for prismatic joints.
170    ///
171    /// This axis is expressed in the local-space of both rigid-bodies.
172    pub fn new(axis: UnitVector<Real>) -> Self {
173        Self(PrismaticJoint::new(axis))
174    }
175
176    /// Sets whether contacts between the attached rigid-bodies are enabled.
177    #[must_use]
178    pub fn contacts_enabled(mut self, enabled: bool) -> Self {
179        self.0.set_contacts_enabled(enabled);
180        self
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: Point<Real>) -> 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: Point<Real>) -> 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: UnitVector<Real>) -> 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: UnitVector<Real>) -> 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    /// Builds the prismatic joint.
260    #[must_use]
261    pub fn build(self) -> PrismaticJoint {
262        self.0
263    }
264}
265
266impl From<PrismaticJointBuilder> for GenericJoint {
267    fn from(val: PrismaticJointBuilder) -> GenericJoint {
268        val.0.into()
269    }
270}