1use crate::types::BodyId;
2use crate::world::World;
3use boxdd_sys::ffi;
4
5use super::{Joint, JointBase, JointBaseBuilder, OwnedJoint};
6use crate::error::ApiResult;
7
8#[derive(Clone, Debug)]
10pub struct MotorJointDef(pub(crate) ffi::b2MotorJointDef);
14
15impl MotorJointDef {
16 pub fn new(base: JointBase) -> Self {
17 let mut def: ffi::b2MotorJointDef = unsafe { ffi::b2DefaultMotorJointDef() };
18 def.base = base.0;
19 Self(def)
20 }
21 pub fn linear_velocity<V: Into<crate::types::Vec2>>(mut self, v: V) -> Self {
23 self.0.linearVelocity = ffi::b2Vec2::from(v.into());
24 self
25 }
26 pub fn max_velocity_force(mut self, v: f32) -> Self {
28 self.0.maxVelocityForce = v;
29 self
30 }
31 pub fn angular_velocity(mut self, v: f32) -> Self {
33 self.0.angularVelocity = v;
34 self
35 }
36 pub fn max_velocity_torque(mut self, v: f32) -> Self {
38 self.0.maxVelocityTorque = v;
39 self
40 }
41 pub fn linear_hertz(mut self, v: f32) -> Self {
43 self.0.linearHertz = v;
44 self
45 }
46 pub fn linear_damping_ratio(mut self, v: f32) -> Self {
48 self.0.linearDampingRatio = v;
49 self
50 }
51 pub fn max_spring_force(mut self, v: f32) -> Self {
53 self.0.maxSpringForce = v;
54 self
55 }
56 pub fn angular_hertz(mut self, v: f32) -> Self {
58 self.0.angularHertz = v;
59 self
60 }
61 pub fn angular_damping_ratio(mut self, v: f32) -> Self {
63 self.0.angularDampingRatio = v;
64 self
65 }
66 pub fn max_spring_torque(mut self, v: f32) -> Self {
68 self.0.maxSpringTorque = v;
69 self
70 }
71}
72
73pub struct MotorJointBuilder<'w> {
76 pub(crate) world: &'w mut World,
77 pub(crate) body_a: BodyId,
78 pub(crate) body_b: BodyId,
79 pub(crate) def: MotorJointDef,
80}
81
82impl<'w> MotorJointBuilder<'w> {
83 pub fn linear_velocity<V: Into<crate::types::Vec2>>(mut self, v: V) -> Self {
85 self.def = self.def.linear_velocity(ffi::b2Vec2::from(v.into()));
86 self
87 }
88 pub fn angular_velocity(mut self, w: f32) -> Self {
90 self.def = self.def.angular_velocity(w);
91 self
92 }
93 pub fn max_velocity_force(mut self, f: f32) -> Self {
95 self.def = self.def.max_velocity_force(f);
96 self
97 }
98 pub fn max_velocity_torque(mut self, t: f32) -> Self {
100 self.def = self.def.max_velocity_torque(t);
101 self
102 }
103 pub fn linear_spring(mut self, hz: f32, dr: f32) -> Self {
105 self.def = self.def.linear_hertz(hz).linear_damping_ratio(dr);
106 self
107 }
108 pub fn angular_spring(mut self, hz: f32, dr: f32) -> Self {
110 self.def = self.def.angular_hertz(hz).angular_damping_ratio(dr);
111 self
112 }
113 pub fn collide_connected(mut self, flag: bool) -> Self {
115 self.def.0.base.collideConnected = flag;
116 self
117 }
118
119 #[must_use]
120 pub fn build(mut self) -> Joint<'w> {
121 crate::core::debug_checks::assert_body_valid(self.body_a);
122 crate::core::debug_checks::assert_body_valid(self.body_b);
123 let base = JointBaseBuilder::new()
125 .bodies_by_id(self.body_a, self.body_b)
126 .build();
127 self.def.0.base = base.0;
128 self.world.create_motor_joint(&self.def)
129 }
130
131 pub fn try_build(mut self) -> ApiResult<Joint<'w>> {
132 crate::core::debug_checks::check_body_valid(self.body_a)?;
133 crate::core::debug_checks::check_body_valid(self.body_b)?;
134 let base = JointBaseBuilder::new()
135 .bodies_by_id(self.body_a, self.body_b)
136 .build();
137 self.def.0.base = base.0;
138 self.world.try_create_motor_joint(&self.def)
139 }
140
141 #[must_use]
142 pub fn build_owned(mut self) -> OwnedJoint {
143 crate::core::debug_checks::assert_body_valid(self.body_a);
144 crate::core::debug_checks::assert_body_valid(self.body_b);
145 let base = JointBaseBuilder::new()
146 .bodies_by_id(self.body_a, self.body_b)
147 .build();
148 self.def.0.base = base.0;
149 self.world.create_motor_joint_owned(&self.def)
150 }
151
152 pub fn try_build_owned(mut self) -> ApiResult<OwnedJoint> {
153 crate::core::debug_checks::check_body_valid(self.body_a)?;
154 crate::core::debug_checks::check_body_valid(self.body_b)?;
155 let base = JointBaseBuilder::new()
156 .bodies_by_id(self.body_a, self.body_b)
157 .build();
158 self.def.0.base = base.0;
159 self.world.try_create_motor_joint_owned(&self.def)
160 }
161}