1use crate::dynamics::{GenericJoint, GenericJointBuilder};
2use crate::math::{Real, Rot, Vect};
3use rapier::dynamics::{JointAxesMask, JointAxis, JointLimits, JointMotor, MotorModel};
4use rapier::math::Pose;
5
6use super::{SpringCoefficients, TypedJoint};
7
8#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
9#[derive(Copy, Clone, Debug, PartialEq)]
10#[repr(transparent)]
11pub struct SphericalJoint {
13 pub data: GenericJoint,
15}
16
17impl Default for SphericalJoint {
18 fn default() -> Self {
19 SphericalJoint::new()
20 }
21}
22
23impl SphericalJoint {
24 pub fn new() -> Self {
26 let data = GenericJointBuilder::new(JointAxesMask::LOCKED_SPHERICAL_AXES).build();
27 Self { data }
28 }
29
30 pub fn contacts_enabled(&self) -> bool {
32 self.data.contacts_enabled()
33 }
34
35 pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
37 self.data.set_contacts_enabled(enabled);
38 self
39 }
40
41 #[must_use]
43 pub fn softness(&self) -> SpringCoefficients<Real> {
44 self.data.softness()
45 }
46
47 pub fn set_softness(&mut self, softness: SpringCoefficients<Real>) -> &mut Self {
49 self.data.set_softness(softness);
50 self
51 }
52
53 #[must_use]
55 pub fn local_anchor1(&self) -> Vect {
56 self.data.local_anchor1()
57 }
58
59 pub fn set_local_anchor1(&mut self, anchor1: Vect) -> &mut Self {
61 self.data.set_local_anchor1(anchor1);
62 self
63 }
64
65 #[must_use]
67 pub fn local_anchor2(&self) -> Vect {
68 self.data.local_anchor2()
69 }
70
71 pub fn set_local_anchor2(&mut self, anchor2: Vect) -> &mut Self {
73 self.data.set_local_anchor2(anchor2);
74 self
75 }
76
77 #[must_use]
79 pub fn local_basis1(&self) -> Rot {
80 self.data.local_basis1()
81 }
82
83 pub fn set_local_basis1(&mut self, local_basis: Rot) -> &mut Self {
85 self.data.set_local_basis1(local_basis);
86 self
87 }
88
89 #[must_use]
91 pub fn local_basis2(&self) -> Rot {
92 self.data.local_basis2()
93 }
94
95 pub fn set_local_basis2(&mut self, local_basis: Rot) -> &mut Self {
97 self.data.set_local_basis2(local_basis);
98 self
99 }
100
101 #[must_use]
103 pub fn local_frame1(&self) -> Pose {
104 self.data.local_frame1()
105 }
106
107 pub fn set_local_frame1(&mut self, local_frame: Pose) -> &mut Self {
109 self.data.set_local_frame1(local_frame);
110 self
111 }
112
113 #[must_use]
115 pub fn local_frame2(&self) -> Pose {
116 self.data.local_frame2()
117 }
118
119 pub fn set_local_frame2(&mut self, local_frame: Pose) -> &mut Self {
121 self.data.set_local_frame2(local_frame);
122 self
123 }
124
125 #[must_use]
127 pub fn motor(&self, axis: JointAxis) -> Option<&JointMotor> {
128 self.data.motor(axis)
129 }
130
131 pub fn set_motor_model(&mut self, axis: JointAxis, model: MotorModel) -> &mut Self {
133 self.data.set_motor_model(axis, model);
134 self
135 }
136
137 pub fn set_motor_velocity(
139 &mut self,
140 axis: JointAxis,
141 target_vel: Real,
142 factor: Real,
143 ) -> &mut Self {
144 self.data.set_motor_velocity(axis, target_vel, factor);
145 self
146 }
147
148 pub fn set_motor_position(
150 &mut self,
151 axis: JointAxis,
152 target_pos: Real,
153 stiffness: Real,
154 damping: Real,
155 ) -> &mut Self {
156 self.data
157 .set_motor_position(axis, target_pos, stiffness, damping);
158 self
159 }
160
161 pub fn set_motor(
163 &mut self,
164 axis: JointAxis,
165 target_pos: Real,
166 target_vel: Real,
167 stiffness: Real,
168 damping: Real,
169 ) -> &mut Self {
170 self.data
171 .set_motor(axis, target_pos, target_vel, stiffness, damping);
172 self
173 }
174
175 pub fn set_motor_max_force(&mut self, axis: JointAxis, max_force: Real) -> &mut Self {
177 self.data.set_motor_max_force(axis, max_force);
178 self
179 }
180
181 #[must_use]
183 pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
184 self.data.limits(axis)
185 }
186
187 pub fn set_limits(&mut self, axis: JointAxis, limits: [Real; 2]) -> &mut Self {
189 self.data.set_limits(axis, limits);
190 self
191 }
192}
193
194impl From<SphericalJoint> for GenericJoint {
195 fn from(joint: SphericalJoint) -> GenericJoint {
196 joint.data
197 }
198}
199
200#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
202#[derive(Copy, Default, Clone, Debug, PartialEq)]
203pub struct SphericalJointBuilder(SphericalJoint);
204
205impl SphericalJointBuilder {
206 pub fn new() -> Self {
208 Self(SphericalJoint::new())
209 }
210
211 #[must_use]
213 pub fn local_anchor1(mut self, anchor1: Vect) -> Self {
214 self.0.set_local_anchor1(anchor1);
215 self
216 }
217
218 #[must_use]
220 pub fn local_anchor2(mut self, anchor2: Vect) -> Self {
221 self.0.set_local_anchor2(anchor2);
222 self
223 }
224
225 #[must_use]
227 pub fn local_basis1(mut self, local_basis: Rot) -> Self {
228 self.0.set_local_basis1(local_basis);
229 self
230 }
231
232 #[must_use]
234 pub fn local_basis2(mut self, local_basis: Rot) -> Self {
235 self.0.set_local_basis2(local_basis);
236 self
237 }
238
239 #[must_use]
241 pub fn local_frame1(mut self, local_frame: Pose) -> Self {
242 self.0.set_local_frame1(local_frame);
243 self
244 }
245
246 #[must_use]
248 pub fn local_frame2(mut self, local_frame: Pose) -> Self {
249 self.0.set_local_frame2(local_frame);
250 self
251 }
252
253 #[must_use]
255 pub fn motor_model(mut self, axis: JointAxis, model: MotorModel) -> Self {
256 self.0.set_motor_model(axis, model);
257 self
258 }
259
260 #[must_use]
262 pub fn motor_velocity(mut self, axis: JointAxis, target_vel: Real, factor: Real) -> Self {
263 self.0.set_motor_velocity(axis, target_vel, factor);
264 self
265 }
266
267 #[must_use]
269 pub fn motor_position(
270 mut self,
271 axis: JointAxis,
272 target_pos: Real,
273 stiffness: Real,
274 damping: Real,
275 ) -> Self {
276 self.0
277 .set_motor_position(axis, target_pos, stiffness, damping);
278 self
279 }
280
281 #[must_use]
283 pub fn motor(
284 mut self,
285 axis: JointAxis,
286 target_pos: Real,
287 target_vel: Real,
288 stiffness: Real,
289 damping: Real,
290 ) -> Self {
291 self.0
292 .set_motor(axis, target_pos, target_vel, stiffness, damping);
293 self
294 }
295
296 #[must_use]
298 pub fn motor_max_force(mut self, axis: JointAxis, max_force: Real) -> Self {
299 self.0.set_motor_max_force(axis, max_force);
300 self
301 }
302
303 #[must_use]
305 pub fn limits(mut self, axis: JointAxis, limits: [Real; 2]) -> Self {
306 self.0.set_limits(axis, limits);
307 self
308 }
309
310 #[must_use]
312 pub fn contacts_enabled(mut self, enabled: bool) -> Self {
313 self.0.set_contacts_enabled(enabled);
314 self
315 }
316
317 #[must_use]
319 pub fn softness(mut self, softness: SpringCoefficients<Real>) -> Self {
320 self.0.set_softness(softness);
321 self
322 }
323
324 #[must_use]
326 pub fn build(self) -> SphericalJoint {
327 self.0
328 }
329}
330
331impl From<SphericalJointBuilder> for TypedJoint {
332 fn from(joint: SphericalJointBuilder) -> TypedJoint {
333 joint.0.into()
334 }
335}
336
337impl From<SphericalJoint> for TypedJoint {
338 fn from(joint: SphericalJoint) -> TypedJoint {
339 TypedJoint::SphericalJoint(joint)
340 }
341}