1use crate::dynamics::integration_parameters::SpringCoefficients;
2use crate::dynamics::joint::{GenericJoint, GenericJointBuilder, JointAxesMask};
3use crate::dynamics::{JointAxis, JointMotor, MotorModel};
4use crate::math::{Isometry, Point, Real};
5
6use super::JointLimits;
7
8#[cfg(doc)]
9use crate::dynamics::RevoluteJoint;
10
11#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
12#[derive(Copy, Clone, Debug, PartialEq)]
13#[repr(transparent)]
14pub struct SphericalJoint {
27 pub data: GenericJoint,
29}
30
31impl Default for SphericalJoint {
32 fn default() -> Self {
33 SphericalJoint::new()
34 }
35}
36
37impl SphericalJoint {
38 pub fn new() -> Self {
40 let data = GenericJointBuilder::new(JointAxesMask::LOCKED_SPHERICAL_AXES).build();
41 Self { data }
42 }
43
44 pub fn data(&self) -> &GenericJoint {
46 &self.data
47 }
48
49 pub fn contacts_enabled(&self) -> bool {
51 self.data.contacts_enabled
52 }
53
54 pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
56 self.data.set_contacts_enabled(enabled);
57 self
58 }
59
60 #[must_use]
62 pub fn local_anchor1(&self) -> Point<Real> {
63 self.data.local_anchor1()
64 }
65
66 pub fn set_local_anchor1(&mut self, anchor1: Point<Real>) -> &mut Self {
68 self.data.set_local_anchor1(anchor1);
69 self
70 }
71
72 #[must_use]
74 pub fn local_anchor2(&self) -> Point<Real> {
75 self.data.local_anchor2()
76 }
77
78 pub fn set_local_anchor2(&mut self, anchor2: Point<Real>) -> &mut Self {
80 self.data.set_local_anchor2(anchor2);
81 self
82 }
83
84 #[must_use]
87 pub fn local_frame1(&self) -> &Isometry<Real> {
88 &self.data.local_frame1
89 }
90
91 pub fn set_local_frame1(&mut self, local_frame: Isometry<Real>) -> &mut Self {
94 self.data.set_local_frame1(local_frame);
95 self
96 }
97
98 #[must_use]
101 pub fn local_frame2(&self) -> &Isometry<Real> {
102 &self.data.local_frame2
103 }
104
105 pub fn set_local_frame2(&mut self, local_frame: Isometry<Real>) -> &mut Self {
108 self.data.set_local_frame2(local_frame);
109 self
110 }
111
112 #[must_use]
117 pub fn motor(&self, axis: JointAxis) -> Option<&JointMotor> {
118 self.data.motor(axis)
119 }
120
121 pub fn set_motor_model(&mut self, axis: JointAxis, model: MotorModel) -> &mut Self {
125 self.data.set_motor_model(axis, model);
126 self
127 }
128
129 pub fn set_motor_velocity(
136 &mut self,
137 axis: JointAxis,
138 target_vel: Real,
139 factor: Real,
140 ) -> &mut Self {
141 self.data.set_motor_velocity(axis, target_vel, factor);
142 self
143 }
144
145 pub fn set_motor_position(
153 &mut self,
154 axis: JointAxis,
155 target_pos: Real,
156 stiffness: Real,
157 damping: Real,
158 ) -> &mut Self {
159 self.data
160 .set_motor_position(axis, target_pos, stiffness, damping);
161 self
162 }
163
164 pub fn set_motor(
166 &mut self,
167 axis: JointAxis,
168 target_pos: Real,
169 target_vel: Real,
170 stiffness: Real,
171 damping: Real,
172 ) -> &mut Self {
173 self.data
174 .set_motor(axis, target_pos, target_vel, stiffness, damping);
175 self
176 }
177
178 pub fn set_motor_max_force(&mut self, axis: JointAxis, max_force: Real) -> &mut Self {
180 self.data.set_motor_max_force(axis, max_force);
181 self
182 }
183
184 #[must_use]
186 pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
187 self.data.limits(axis)
188 }
189
190 pub fn set_limits(&mut self, axis: JointAxis, limits: [Real; 2]) -> &mut Self {
193 self.data.set_limits(axis, limits);
194 self
195 }
196
197 #[must_use]
199 pub fn softness(&self) -> SpringCoefficients<Real> {
200 self.data.softness
201 }
202
203 #[must_use]
205 pub fn set_softness(&mut self, softness: SpringCoefficients<Real>) -> &mut Self {
206 self.data.softness = softness;
207 self
208 }
209}
210
211impl From<SphericalJoint> for GenericJoint {
212 fn from(val: SphericalJoint) -> GenericJoint {
213 val.data
214 }
215}
216
217#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
219#[derive(Copy, Clone, Debug, Default, PartialEq)]
220pub struct SphericalJointBuilder(pub SphericalJoint);
221
222impl SphericalJointBuilder {
223 pub fn new() -> Self {
225 Self(SphericalJoint::new())
226 }
227
228 #[must_use]
230 pub fn contacts_enabled(mut self, enabled: bool) -> Self {
231 self.0.set_contacts_enabled(enabled);
232 self
233 }
234
235 #[must_use]
237 pub fn local_anchor1(mut self, anchor1: Point<Real>) -> Self {
238 self.0.set_local_anchor1(anchor1);
239 self
240 }
241
242 #[must_use]
244 pub fn local_anchor2(mut self, anchor2: Point<Real>) -> Self {
245 self.0.set_local_anchor2(anchor2);
246 self
247 }
248
249 #[must_use]
252 pub fn local_frame1(mut self, frame1: Isometry<Real>) -> Self {
253 self.0.set_local_frame1(frame1);
254 self
255 }
256
257 #[must_use]
260 pub fn local_frame2(mut self, frame2: Isometry<Real>) -> Self {
261 self.0.set_local_frame2(frame2);
262 self
263 }
264
265 #[must_use]
267 pub fn motor_model(mut self, axis: JointAxis, model: MotorModel) -> Self {
268 self.0.set_motor_model(axis, model);
269 self
270 }
271
272 #[must_use]
274 pub fn motor_velocity(mut self, axis: JointAxis, target_vel: Real, factor: Real) -> Self {
275 self.0.set_motor_velocity(axis, target_vel, factor);
276 self
277 }
278
279 #[must_use]
281 pub fn motor_position(
282 mut self,
283 axis: JointAxis,
284 target_pos: Real,
285 stiffness: Real,
286 damping: Real,
287 ) -> Self {
288 self.0
289 .set_motor_position(axis, target_pos, stiffness, damping);
290 self
291 }
292
293 #[must_use]
295 pub fn motor(
296 mut self,
297 axis: JointAxis,
298 target_pos: Real,
299 target_vel: Real,
300 stiffness: Real,
301 damping: Real,
302 ) -> Self {
303 self.0
304 .set_motor(axis, target_pos, target_vel, stiffness, damping);
305 self
306 }
307
308 #[must_use]
310 pub fn motor_max_force(mut self, axis: JointAxis, max_force: Real) -> Self {
311 self.0.set_motor_max_force(axis, max_force);
312 self
313 }
314
315 #[must_use]
317 pub fn limits(mut self, axis: JointAxis, limits: [Real; 2]) -> Self {
318 self.0.set_limits(axis, limits);
319 self
320 }
321
322 #[must_use]
324 pub fn softness(mut self, softness: SpringCoefficients<Real>) -> Self {
325 self.0.data.softness = softness;
326 self
327 }
328
329 #[must_use]
331 pub fn build(self) -> SphericalJoint {
332 self.0
333 }
334}
335
336impl From<SphericalJointBuilder> for GenericJoint {
337 fn from(val: SphericalJointBuilder) -> GenericJoint {
338 val.0.into()
339 }
340}