1use crate::dynamics::{GenericJoint, GenericJointBuilder};
2use crate::math::{Real, Vect};
3use rapier::dynamics::{JointAxesMask, JointAxis, JointLimits, JointMotor, MotorModel};
4
5use super::TypedJoint;
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 contacts_enabled(&self) -> bool {
31 self.data.contacts_enabled()
32 }
33
34 pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
36 self.data.set_contacts_enabled(enabled);
37 self
38 }
39
40 #[must_use]
42 pub fn local_anchor1(&self) -> Vect {
43 self.data.local_anchor1()
44 }
45
46 pub fn set_local_anchor1(&mut self, anchor1: Vect) -> &mut Self {
48 self.data.set_local_anchor1(anchor1);
49 self
50 }
51
52 #[must_use]
54 pub fn local_anchor2(&self) -> Vect {
55 self.data.local_anchor2()
56 }
57
58 pub fn set_local_anchor2(&mut self, anchor2: Vect) -> &mut Self {
60 self.data.set_local_anchor2(anchor2);
61 self
62 }
63
64 #[must_use]
66 pub fn motor(&self, axis: JointAxis) -> Option<&JointMotor> {
67 self.data.motor(axis)
68 }
69
70 pub fn set_motor_model(&mut self, axis: JointAxis, model: MotorModel) -> &mut Self {
72 self.data.set_motor_model(axis, model);
73 self
74 }
75
76 pub fn set_motor_velocity(
78 &mut self,
79 axis: JointAxis,
80 target_vel: Real,
81 factor: Real,
82 ) -> &mut Self {
83 self.data.set_motor_velocity(axis, target_vel, factor);
84 self
85 }
86
87 pub fn set_motor_position(
89 &mut self,
90 axis: JointAxis,
91 target_pos: Real,
92 stiffness: Real,
93 damping: Real,
94 ) -> &mut Self {
95 self.data
96 .set_motor_position(axis, target_pos, stiffness, damping);
97 self
98 }
99
100 pub fn set_motor(
102 &mut self,
103 axis: JointAxis,
104 target_pos: Real,
105 target_vel: Real,
106 stiffness: Real,
107 damping: Real,
108 ) -> &mut Self {
109 self.data
110 .set_motor(axis, target_pos, target_vel, stiffness, damping);
111 self
112 }
113
114 pub fn set_motor_max_force(&mut self, axis: JointAxis, max_force: Real) -> &mut Self {
116 self.data.set_motor_max_force(axis, max_force);
117 self
118 }
119
120 #[must_use]
122 pub fn limits(&self, axis: JointAxis) -> Option<&JointLimits<Real>> {
123 self.data.limits(axis)
124 }
125
126 pub fn set_limits(&mut self, axis: JointAxis, limits: [Real; 2]) -> &mut Self {
128 self.data.set_limits(axis, limits);
129 self
130 }
131}
132
133impl From<SphericalJoint> for GenericJoint {
134 fn from(joint: SphericalJoint) -> GenericJoint {
135 joint.data
136 }
137}
138
139#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
141#[derive(Copy, Default, Clone, Debug, PartialEq)]
142pub struct SphericalJointBuilder(SphericalJoint);
143
144impl SphericalJointBuilder {
145 pub fn new() -> Self {
147 Self(SphericalJoint::new())
148 }
149
150 #[must_use]
152 pub fn local_anchor1(mut self, anchor1: Vect) -> Self {
153 self.0.set_local_anchor1(anchor1);
154 self
155 }
156
157 #[must_use]
159 pub fn local_anchor2(mut self, anchor2: Vect) -> Self {
160 self.0.set_local_anchor2(anchor2);
161 self
162 }
163
164 #[must_use]
166 pub fn motor_model(mut self, axis: JointAxis, model: MotorModel) -> Self {
167 self.0.set_motor_model(axis, model);
168 self
169 }
170
171 #[must_use]
173 pub fn motor_velocity(mut self, axis: JointAxis, target_vel: Real, factor: Real) -> Self {
174 self.0.set_motor_velocity(axis, target_vel, factor);
175 self
176 }
177
178 #[must_use]
180 pub fn motor_position(
181 mut self,
182 axis: JointAxis,
183 target_pos: Real,
184 stiffness: Real,
185 damping: Real,
186 ) -> Self {
187 self.0
188 .set_motor_position(axis, target_pos, stiffness, damping);
189 self
190 }
191
192 #[must_use]
194 pub fn motor(
195 mut self,
196 axis: JointAxis,
197 target_pos: Real,
198 target_vel: Real,
199 stiffness: Real,
200 damping: Real,
201 ) -> Self {
202 self.0
203 .set_motor(axis, target_pos, target_vel, stiffness, damping);
204 self
205 }
206
207 #[must_use]
209 pub fn motor_max_force(mut self, axis: JointAxis, max_force: Real) -> Self {
210 self.0.set_motor_max_force(axis, max_force);
211 self
212 }
213
214 #[must_use]
216 pub fn limits(mut self, axis: JointAxis, limits: [Real; 2]) -> Self {
217 self.0.set_limits(axis, limits);
218 self
219 }
220
221 #[must_use]
223 pub fn build(self) -> SphericalJoint {
224 self.0
225 }
226}
227
228impl From<SphericalJointBuilder> for TypedJoint {
229 fn from(joint: SphericalJointBuilder) -> TypedJoint {
230 joint.0.into()
231 }
232}
233
234impl From<SphericalJoint> for TypedJoint {
235 fn from(joint: SphericalJoint) -> TypedJoint {
236 TypedJoint::SphericalJoint(joint)
237 }
238}