box2d_rs/private/dynamics/joints/
b2_motor_joint.rs1use crate::b2_math::*;
2use crate::b2_common::*;
3use crate::b2rs_common::UserDataType;
4use crate::b2_time_step::*;
5use crate::joints::b2_motor_joint::*;
6
7pub(crate) fn init_velocity_constraints<D: UserDataType>(
23 self_: &mut B2motorJoint<D>,
24 data: &B2solverData,
25 positions: &[B2position],
26 velocities: &mut [B2velocity],
27) {
28 {
29 let m_body_a = self_.base.m_body_a.borrow();
30 let m_body_b = self_.base.m_body_b.borrow();
31 self_.m_index_a = m_body_a.m_island_index;
32 self_.m_index_b = m_body_b.m_island_index;
33 self_.m_local_center_a = m_body_a.m_sweep.local_center;
34 self_.m_local_center_b = m_body_b.m_sweep.local_center;
35 self_.m_inv_mass_a = m_body_a.m_inv_mass;
36 self_.m_inv_mass_b = m_body_b.m_inv_mass;
37 self_.m_inv_ia = m_body_a.m_inv_i;
38 self_.m_inv_ib = m_body_b.m_inv_i;
39 }
40
41 let c_a: B2vec2 = positions[self_.m_index_a as usize].c;
42 let a_a: f32 = positions[self_.m_index_a as usize].a;
43 let mut v_a: B2vec2 = velocities[self_.m_index_a as usize].v;
44 let mut w_a: f32 = velocities[self_.m_index_a as usize].w;
45
46 let c_b: B2vec2 = positions[self_.m_index_b as usize].c;
47 let a_b: f32 = positions[self_.m_index_b as usize].a;
48 let mut v_b: B2vec2 = velocities[self_.m_index_b as usize].v;
49 let mut w_b: f32 = velocities[self_.m_index_b as usize].w;
50
51 let (q_a, q_b) = (B2Rot::new(a_a), B2Rot::new(a_b));
52
53 self_.m_r_a = b2_mul_rot_by_vec2(q_a, self_.m_linear_offset - self_.m_local_center_a);
55 self_.m_r_b = b2_mul_rot_by_vec2(q_b, -self_.m_local_center_b);
56
57 let m_a: f32 = self_.m_inv_mass_a;
66 let m_b: f32 = self_.m_inv_mass_b;
67 let i_a: f32 = self_.m_inv_ia;
68 let i_b: f32 = self_.m_inv_ib;
69
70 let mut k = B2Mat22::default();
72 k.ex.x = m_a + m_b + i_a * self_.m_r_a.y * self_.m_r_a.y + i_b * self_.m_r_b.y * self_.m_r_b.y;
73 k.ex.y = -i_a * self_.m_r_a.x * self_.m_r_a.y - i_b * self_.m_r_b.x * self_.m_r_b.y;
74 k.ey.x = k.ex.y;
75 k.ey.y = m_a + m_b + i_a * self_.m_r_a.x * self_.m_r_a.x + i_b * self_.m_r_b.x * self_.m_r_b.x;
76
77 self_.m_linear_mass = k.get_inverse();
78
79 self_.m_angular_mass = i_a + i_b;
80 if self_.m_angular_mass > 0.0 {
81 self_.m_angular_mass = 1.0 / self_.m_angular_mass;
82 }
83
84 self_.m_linear_error = c_b + self_.m_r_b - c_a - self_.m_r_a;
85 self_.m_angular_error = a_b - a_a - self_.m_angular_offset;
86
87 if data.step.warm_starting {
88 self_.m_linear_impulse *= data.step.dt_ratio;
90 self_.m_angular_impulse *= data.step.dt_ratio;
91
92 let p = B2vec2::new(self_.m_linear_impulse.x, self_.m_linear_impulse.y);
93 v_a -= m_a * p;
94 w_a -= i_a * (b2_cross(self_.m_r_a, p) + self_.m_angular_impulse);
95 v_b += m_b * p;
96 w_b += i_b * (b2_cross(self_.m_r_b, p) + self_.m_angular_impulse);
97 } else {
98 self_.m_linear_impulse.set_zero();
99 self_.m_angular_impulse = 0.0;
100 }
101
102 velocities[self_.m_index_a as usize].v = v_a;
103 velocities[self_.m_index_a as usize].w = w_a;
104 velocities[self_.m_index_b as usize].v = v_b;
105 velocities[self_.m_index_b as usize].w = w_b;
106}
107
108pub(crate) fn solve_velocity_constraints<D: UserDataType>(
109 self_: &mut B2motorJoint<D>,
110 data: &B2solverData,
111 velocities: &mut [B2velocity],
112) {
113 let B2velocity {
114 v: mut v_a,
115 w: mut w_a,
116 } = velocities[self_.m_index_a as usize];
117 let B2velocity {
122 v: mut v_b,
123 w: mut w_b,
124 } = velocities[self_.m_index_b as usize];
125 let B2motorJoint {
130 m_inv_mass_a: m_a,
131 m_inv_mass_b: m_b,
132 m_inv_ia: i_a,
133 m_inv_ib: i_b,
134 ..
135 } = *self_;
136 let h: f32 = data.step.dt;
142 let inv_h: f32 = data.step.inv_dt;
143
144 {
146 let cdot: f32 = w_b - w_a + inv_h * self_.m_correction_factor * self_.m_angular_error;
147 let mut impulse: f32 = -self_.m_angular_mass * cdot;
148
149 let old_impulse: f32 = self_.m_angular_impulse;
150 let max_impulse: f32 = h * self_.m_max_torque;
151 self_.m_angular_impulse =
152 b2_clamp(self_.m_angular_impulse + impulse, -max_impulse, max_impulse);
153 impulse = self_.m_angular_impulse - old_impulse;
154
155 w_a -= i_a * impulse;
156 w_b += i_b * impulse;
157 }
158
159 {
161 let cdot: B2vec2 = v_b + b2_cross_scalar_by_vec(w_b, self_.m_r_b)
162 - v_a - b2_cross_scalar_by_vec(w_a, self_.m_r_a)
163 + inv_h * self_.m_correction_factor * self_.m_linear_error;
164
165 let mut impulse: B2vec2 = -b2_mul(self_.m_linear_mass, cdot);
166 let old_impulse: B2vec2 = self_.m_linear_impulse;
167 self_.m_linear_impulse += impulse;
168
169 let max_impulse: f32 = h * self_.m_max_force;
170
171 if self_.m_linear_impulse.length_squared() > max_impulse * max_impulse {
172 self_.m_linear_impulse.normalize();
173 self_.m_linear_impulse *= max_impulse;
174 }
175
176 impulse = self_.m_linear_impulse - old_impulse;
177
178 v_a -= m_a * impulse;
179 w_a -= i_a * b2_cross(self_.m_r_a, impulse);
180
181 v_b += m_b * impulse;
182 w_b += i_b * b2_cross(self_.m_r_b, impulse);
183 }
184
185 velocities[self_.m_index_a as usize].v = v_a;
186 velocities[self_.m_index_a as usize].w = w_a;
187 velocities[self_.m_index_b as usize].v = v_b;
188 velocities[self_.m_index_b as usize].w = w_b;
189}
190
191pub(crate) fn solve_position_constraints<D: UserDataType>(
192 _self: &B2motorJoint<D>,
193 data: &B2solverData,
194 _positions: &mut [B2position],
195) -> bool {
196 b2_not_used(data);
197
198 return true;
199}