rapier3d/dynamics/joint/
spherical_joint.rs

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