1use std::ops::{Mul, MulAssign};
2
3use bevy::ecs::component::Component;
4use bevy::math::prelude::*;
5use bevy::reflect::prelude::*;
6use duplicate::duplicate_item;
7
8use crate::utils::NearZero;
9
10#[derive(Debug, Component, Copy, Clone, PartialEq, Default, Reflect)]
33pub struct Velocity {
34 pub linear: Vec3,
38
39 pub angular: AxisAngle,
41}
42
43#[derive(Debug, Component, Copy, Clone, PartialEq, Default, Reflect)]
67pub struct Acceleration {
68 pub linear: Vec3,
70
71 pub angular: AxisAngle,
73}
74
75#[derive(Debug, Copy, Clone, PartialEq, Default, Reflect, Component)]
98pub struct Damping {
99 pub linear: f32,
101
102 pub angular: f32,
104}
105
106#[derive(Debug, Copy, Clone, PartialEq, Default, Reflect)]
110pub struct AxisAngle(Vec3);
111
112impl Velocity {
113 #[must_use]
115 pub fn from_linear(linear: Vec3) -> Self {
116 Self {
117 linear,
118 angular: AxisAngle::default(),
119 }
120 }
121
122 #[must_use]
124 pub fn from_angular(angular: AxisAngle) -> Self {
125 Self {
126 angular,
127 linear: Vec3::ZERO,
128 }
129 }
130
131 #[must_use]
133 pub fn with_linear(mut self, linear: Vec3) -> Self {
134 self.linear = linear;
135 self
136 }
137
138 #[must_use]
140 pub fn with_angular(mut self, angular: AxisAngle) -> Self {
141 self.angular = angular;
142 self
143 }
144}
145
146impl Acceleration {
147 #[must_use]
149 pub fn from_linear(linear: Vec3) -> Self {
150 Self {
151 linear,
152 angular: AxisAngle::default(),
153 }
154 }
155
156 #[must_use]
158 pub fn from_angular(angular: AxisAngle) -> Self {
159 Self {
160 angular,
161 linear: Vec3::ZERO,
162 }
163 }
164
165 #[must_use]
167 pub fn with_linear(mut self, linear: Vec3) -> Self {
168 self.linear = linear;
169 self
170 }
171
172 #[must_use]
174 pub fn with_angular(mut self, angular: AxisAngle) -> Self {
175 self.angular = angular;
176 self
177 }
178}
179
180impl Damping {
181 #[must_use]
183 pub fn from_linear(linear: f32) -> Self {
184 Self {
185 linear,
186 angular: 0.0,
187 }
188 }
189
190 #[must_use]
192 pub fn from_angular(angular: f32) -> Self {
193 Self {
194 angular,
195 linear: 0.0,
196 }
197 }
198
199 #[must_use]
201 pub fn with_linear(mut self, linear: f32) -> Self {
202 self.linear = linear;
203 self
204 }
205
206 #[must_use]
208 pub fn with_angular(mut self, angular: f32) -> Self {
209 self.angular = angular;
210 self
211 }
212}
213
214#[duplicate_item(
215 Velocity;
216 [ Velocity ];
217 [ Acceleration ];
218)]
219impl From<Vec2> for Velocity {
220 fn from(v: Vec2) -> Self {
221 Self::from_linear(v.extend(0.0))
222 }
223}
224
225#[duplicate_item(
226 Velocity;
227 [ Velocity ];
228 [ Acceleration ];
229)]
230impl From<Vec3> for Velocity {
231 fn from(linear: Vec3) -> Self {
232 Self::from_linear(linear)
233 }
234}
235
236#[duplicate_item(
237 Velocity;
238 [ Velocity ];
239 [ Acceleration ];
240)]
241impl From<Velocity> for Vec3 {
242 fn from(Velocity { linear, .. }: Velocity) -> Self {
243 linear
244 }
245}
246
247#[duplicate_item(
248 Velocity;
249 [ Velocity ];
250 [ Acceleration ];
251)]
252impl From<AxisAngle> for Velocity {
253 fn from(angular: AxisAngle) -> Self {
254 Self::from_angular(angular)
255 }
256}
257
258#[duplicate_item(
259 Velocity;
260 [ Velocity ];
261 [ Acceleration ];
262)]
263impl From<Quat> for Velocity {
264 fn from(quat: Quat) -> Self {
265 Self::from_angular(quat.into())
266 }
267}
268
269#[duplicate_item(
270 Velocity;
271 [ Velocity ];
272 [ Acceleration ];
273)]
274impl From<Velocity> for AxisAngle {
275 fn from(Velocity { angular, .. }: Velocity) -> Self {
276 angular
277 }
278}
279
280#[duplicate_item(
281 Velocity;
282 [ Velocity ];
283 [ Acceleration ];
284)]
285impl From<Velocity> for Quat {
286 fn from(Velocity { angular, .. }: Velocity) -> Self {
287 angular.into()
288 }
289}
290
291impl From<Vec3> for AxisAngle {
292 fn from(v: Vec3) -> Self {
293 Self(v)
294 }
295}
296
297impl From<AxisAngle> for Vec3 {
298 fn from(AxisAngle(v): AxisAngle) -> Self {
299 v
300 }
301}
302
303impl From<AxisAngle> for f32 {
304 fn from(AxisAngle(v): AxisAngle) -> Self {
305 v.length()
306 }
307}
308
309#[duplicate_item(
310 Velocity;
311 [ Velocity ];
312 [ Acceleration ];
313)]
314impl NearZero for Velocity {
315 fn is_near_zero(self) -> bool {
316 self.linear.is_near_zero() && self.angular.is_near_zero()
317 }
318}
319
320impl MulAssign<f32> for AxisAngle {
321 fn mul_assign(&mut self, rhs: f32) {
322 self.0 = self.0 * rhs;
323 }
324}
325
326impl Mul<f32> for AxisAngle {
327 type Output = Self;
328
329 fn mul(mut self, rhs: f32) -> Self::Output {
330 self *= rhs;
331 self
332 }
333}
334
335impl Mul<AxisAngle> for f32 {
336 type Output = AxisAngle;
337
338 fn mul(self, mut rhs: AxisAngle) -> Self::Output {
339 rhs *= self;
340 rhs
341 }
342}
343
344impl AxisAngle {
345 #[inline]
347 #[must_use]
348 pub fn new(axis: Vec3, angle: f32) -> Self {
349 Self(axis.normalize() * angle)
350 }
351
352 #[inline]
356 #[must_use]
357 pub fn angle_squared(self) -> f32 {
358 self.0.length_squared()
359 }
360
361 #[inline]
365 #[must_use]
366 pub fn angle(self) -> f32 {
367 self.0.length()
368 }
369
370 #[inline]
372 #[must_use]
373 pub fn axis(self) -> Vec3 {
374 self.0
375 }
376}
377
378impl NearZero for AxisAngle {
379 fn is_near_zero(self) -> bool {
380 self.0.is_near_zero()
381 }
382}
383
384impl From<Quat> for AxisAngle {
385 fn from(quat: Quat) -> Self {
386 let length = quat.length();
387 let (axis, angle) = quat.to_axis_angle();
388 Self(axis.normalize() * (angle * length))
389 }
390}
391
392impl From<AxisAngle> for Quat {
393 fn from(axis_angle: AxisAngle) -> Self {
394 if axis_angle.is_near_zero() {
395 Quat::IDENTITY
396 } else {
397 let angle = axis_angle.0.length();
398 Quat::from_axis_angle(axis_angle.0 / angle, angle)
399 }
400 }
401}