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)]
10pub struct SphericalJoint {
12 pub data: GenericJoint,
14}
15
16impl Default for SphericalJoint {
17 fn default() -> Self {
18 SphericalJoint::new()
19 }
20}
21
22impl SphericalJoint {
23 pub fn new() -> Self {
25 let data = GenericJointBuilder::new(JointAxesMask::LOCKED_SPHERICAL_AXES).build();
26 Self { data }
27 }
28
29 pub fn data(&self) -> &GenericJoint {
31 &self.data
32 }
33
34 pub fn contacts_enabled(&self) -> bool {
36 self.data.contacts_enabled
37 }
38
39 pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
41 self.data.set_contacts_enabled(enabled);
42 self
43 }
44
45 #[must_use]
47 pub fn local_anchor1(&self) -> Point<Real> {
48 self.data.local_anchor1()
49 }
50
51 pub fn set_local_anchor1(&mut self, anchor1: Point<Real>) -> &mut Self {
53 self.data.set_local_anchor1(anchor1);
54 self
55 }
56
57 #[must_use]
59 pub fn local_anchor2(&self) -> Point<Real> {
60 self.data.local_anchor2()
61 }
62
63 pub fn set_local_anchor2(&mut self, anchor2: Point<Real>) -> &mut Self {
65 self.data.set_local_anchor2(anchor2);
66 self
67 }
68
69 #[must_use]
72 pub fn local_frame1(&self) -> &Isometry<Real> {
73 &self.data.local_frame1
74 }
75
76 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 #[must_use]
86 pub fn local_frame2(&self) -> &Isometry<Real> {
87 &self.data.local_frame2
88 }
89
90 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 #[must_use]
99 pub fn motor(&self, axis: JointAxis) -> Option<&JointMotor> {
100 self.data.motor(axis)
101 }
102
103 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 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 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 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 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 #[must_use]
155 pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
156 self.data.limits(axis)
157 }
158
159 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#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
175#[derive(Copy, Clone, Debug, Default, PartialEq)]
176pub struct SphericalJointBuilder(pub SphericalJoint);
177
178impl SphericalJointBuilder {
179 pub fn new() -> Self {
181 Self(SphericalJoint::new())
182 }
183
184 #[must_use]
186 pub fn contacts_enabled(mut self, enabled: bool) -> Self {
187 self.0.set_contacts_enabled(enabled);
188 self
189 }
190
191 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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}