1use crate::dynamics::{GenericJoint, GenericJointBuilder};
2use crate::math::{Real, Vect};
3use crate::plugin::context::RapierRigidBodySet;
4use bevy::prelude::Entity;
5use rapier::dynamics::{
6 JointAxesMask, JointAxis, JointLimits, JointMotor, MotorModel, RigidBodyHandle, RigidBodySet,
7};
8
9#[cfg(doc)]
10use crate::prelude::RapierContext;
11
12use super::{SpringCoefficients, TypedJoint};
13
14#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
15#[derive(Copy, Clone, Debug, PartialEq)]
16#[repr(transparent)]
17pub struct RevoluteJoint {
19 pub data: GenericJoint,
21}
22
23#[cfg(feature = "dim2")]
24impl Default for RevoluteJoint {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl RevoluteJoint {
31 #[cfg(feature = "dim2")]
33 pub fn new() -> Self {
34 let data = GenericJointBuilder::new(JointAxesMask::LOCKED_REVOLUTE_AXES);
35 Self { data: data.build() }
36 }
37
38 #[cfg(feature = "dim3")]
42 pub fn new(axis: Vect) -> Self {
43 let data = GenericJointBuilder::new(JointAxesMask::LOCKED_REVOLUTE_AXES)
44 .local_axis1(axis)
45 .local_axis2(axis)
46 .build();
47 Self { data }
48 }
49
50 pub fn contacts_enabled(&self) -> bool {
52 self.data.contacts_enabled()
53 }
54
55 pub fn set_contacts_enabled(&mut self, enabled: bool) -> &mut Self {
57 self.data.set_contacts_enabled(enabled);
58 self
59 }
60
61 #[must_use]
63 pub fn softness(&self) -> SpringCoefficients<Real> {
64 self.data.softness()
65 }
66
67 pub fn set_softness(&mut self, softness: SpringCoefficients<Real>) -> &mut Self {
69 self.data.set_softness(softness);
70 self
71 }
72
73 #[must_use]
75 pub fn local_anchor1(&self) -> Vect {
76 self.data.local_anchor1()
77 }
78
79 pub fn set_local_anchor1(&mut self, anchor1: Vect) -> &mut Self {
81 self.data.set_local_anchor1(anchor1);
82 self
83 }
84
85 #[must_use]
87 pub fn local_anchor2(&self) -> Vect {
88 self.data.local_anchor2()
89 }
90
91 pub fn set_local_anchor2(&mut self, anchor2: Vect) -> &mut Self {
93 self.data.set_local_anchor2(anchor2);
94 self
95 }
96
97 pub fn set_local_axis1(&mut self, axis1: Vect) -> &mut Self {
99 self.data.set_local_axis1(axis1);
100 self
101 }
102
103 pub fn set_local_axis2(&mut self, axis2: Vect) -> &mut Self {
105 self.data.set_local_axis2(axis2);
106 self
107 }
108
109 #[must_use]
111 pub fn motor(&self) -> Option<&JointMotor> {
112 self.data.motor(JointAxis::AngX)
113 }
114
115 pub fn set_motor_model(&mut self, model: MotorModel) -> &mut Self {
117 self.data.set_motor_model(JointAxis::AngX, model);
118 self
119 }
120
121 pub fn set_motor_velocity(&mut self, target_vel: Real, factor: Real) -> &mut Self {
123 self.data
124 .set_motor_velocity(JointAxis::AngX, target_vel, factor);
125 self
126 }
127
128 pub fn set_motor_position(
130 &mut self,
131 target_pos: Real,
132 stiffness: Real,
133 damping: Real,
134 ) -> &mut Self {
135 self.data
136 .set_motor_position(JointAxis::AngX, target_pos, stiffness, damping);
137 self
138 }
139
140 pub fn set_motor(
142 &mut self,
143 target_pos: Real,
144 target_vel: Real,
145 stiffness: Real,
146 damping: Real,
147 ) -> &mut Self {
148 self.data
149 .set_motor(JointAxis::AngX, target_pos, target_vel, stiffness, damping);
150 self
151 }
152
153 pub fn set_motor_max_force(&mut self, max_force: Real) -> &mut Self {
155 self.data.set_motor_max_force(JointAxis::AngX, max_force);
156 self
157 }
158
159 #[must_use]
161 pub fn limits(&self) -> Option<&JointLimits<Real>> {
162 self.data.limits(JointAxis::AngX)
163 }
164
165 pub fn set_limits(&mut self, limits: [Real; 2]) -> &mut Self {
167 self.data.set_limits(JointAxis::AngX, limits);
168 self
169 }
170
171 pub fn angle_from_handles(
181 &self,
182 bodies: &RigidBodySet,
183 body1: RigidBodyHandle,
184 body2: RigidBodyHandle,
185 ) -> f32 {
186 let joint = self.data.raw.as_revolute().unwrap();
188
189 let rb1 = &bodies[body1];
190 let rb2 = &bodies[body2];
191 joint.angle(rb1.rotation(), rb2.rotation())
192 }
193
194 pub fn angle(&self, rigidbody_set: &RapierRigidBodySet, body1: Entity, body2: Entity) -> f32 {
201 let rb1 = rigidbody_set.entity2body().get(&body1).unwrap();
202 let rb2 = rigidbody_set.entity2body().get(&body2).unwrap();
203 self.angle_from_handles(&rigidbody_set.bodies, *rb1, *rb2)
204 }
205}
206
207impl From<RevoluteJoint> for GenericJoint {
208 fn from(joint: RevoluteJoint) -> GenericJoint {
209 joint.data
210 }
211}
212
213#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
217#[derive(Copy, Clone, Debug, PartialEq)]
218pub struct RevoluteJointBuilder(RevoluteJoint);
219
220#[cfg(feature = "dim2")]
221impl Default for RevoluteJointBuilder {
222 fn default() -> Self {
223 Self::new()
224 }
225}
226
227impl RevoluteJointBuilder {
228 #[cfg(feature = "dim2")]
230 pub fn new() -> Self {
231 Self(RevoluteJoint::new())
232 }
233
234 #[cfg(feature = "dim3")]
238 pub fn new(axis: Vect) -> Self {
239 Self(RevoluteJoint::new(axis))
240 }
241
242 #[must_use]
244 pub fn local_anchor1(mut self, anchor1: Vect) -> Self {
245 self.0.set_local_anchor1(anchor1);
246 self
247 }
248
249 #[must_use]
251 pub fn local_anchor2(mut self, anchor2: Vect) -> Self {
252 self.0.set_local_anchor2(anchor2);
253 self
254 }
255
256 pub fn local_axis1(mut self, axis1: Vect) -> Self {
258 self.0.set_local_axis1(axis1);
259 self
260 }
261
262 pub fn local_axis2(mut self, axis2: Vect) -> Self {
264 self.0.set_local_axis2(axis2);
265 self
266 }
267
268 #[must_use]
270 pub fn motor_model(mut self, model: MotorModel) -> Self {
271 self.0.set_motor_model(model);
272 self
273 }
274
275 #[must_use]
277 pub fn motor_velocity(mut self, target_vel: Real, factor: Real) -> Self {
278 self.0.set_motor_velocity(target_vel, factor);
279 self
280 }
281
282 #[must_use]
284 pub fn motor_position(mut self, target_pos: Real, stiffness: Real, damping: Real) -> Self {
285 self.0.set_motor_position(target_pos, stiffness, damping);
286 self
287 }
288
289 #[must_use]
291 pub fn motor(
292 mut self,
293 target_pos: Real,
294 target_vel: Real,
295 stiffness: Real,
296 damping: Real,
297 ) -> Self {
298 self.0.set_motor(target_pos, target_vel, stiffness, damping);
299 self
300 }
301
302 #[must_use]
304 pub fn motor_max_force(mut self, max_force: Real) -> Self {
305 self.0.set_motor_max_force(max_force);
306 self
307 }
308
309 #[must_use]
311 pub fn limits(mut self, limits: [Real; 2]) -> Self {
312 self.0.set_limits(limits);
313 self
314 }
315
316 #[must_use]
318 pub fn contacts_enabled(mut self, enabled: bool) -> Self {
319 self.0.set_contacts_enabled(enabled);
320 self
321 }
322
323 #[must_use]
325 pub fn softness(mut self, softness: SpringCoefficients<Real>) -> Self {
326 self.0.set_softness(softness);
327 self
328 }
329
330 #[must_use]
332 pub fn build(self) -> RevoluteJoint {
333 self.0
334 }
335}
336
337impl From<RevoluteJointBuilder> for TypedJoint {
338 fn from(joint: RevoluteJointBuilder) -> TypedJoint {
339 joint.0.into()
340 }
341}
342
343impl From<RevoluteJoint> for TypedJoint {
344 fn from(joint: RevoluteJoint) -> TypedJoint {
345 TypedJoint::RevoluteJoint(joint)
346 }
347}