1pub type Attitude<T> = (T, [T; 3]);
7pub use vecmath::Vector3;
9
10use vecmath::traits::Float;
11
12#[derive(Clone, Copy, Debug)]
14pub struct RigidBody<T> {
15 pub pos: Vector3<T>,
17 pub vel: Vector3<T>,
19 pub acc: Vector3<T>,
21 pub ori: Attitude<T>,
23 pub tor: Attitude<T>,
25 pub wre: Attitude<T>,
27}
28
29impl<T: Float> RigidBody<T> {
30 pub fn update_linear(&mut self, dt: T) {
32 use vecmath::vec3_add as add;
33 use vecmath::vec3_scale as scale;
34
35 let half_dt = T::from_f64(0.5) * dt;
36 self.vel = add(self.vel, scale(self.acc, half_dt));
37 self.pos = add(self.pos, scale(self.vel, dt));
38 self.vel = add(self.vel, scale(self.acc, half_dt));
39 }
40
41 pub fn update_angular(&mut self, dt: T) {
43 let half_dt = T::from_f64(0.5) * dt;
44 self.tor = angular(self.tor, self.wre, half_dt);
45 self.ori = angular(self.ori, self.tor, dt);
46 self.tor = angular(self.tor, self.wre, half_dt);
47 }
48
49 pub fn update(&mut self, dt: T) {
51 self.update_linear(dt);
52 self.update_angular(dt);
53 }
54}
55
56pub fn angular<T: Float>(a: Attitude<T>, b: Attitude<T>, t: T) -> Attitude<T> {
58 use vecmath::vec3_scale as scale;
59 use vecmath::vec3_dot as dot;
60 use vecmath::vec3_cross as cross;
61 use vecmath::vec3_add as add;
62
63 let angle = a.0 + dot(a.1, b.1) * b.0 * t;
64 let cos = b.0.cos();
65 let sin = b.0.sin();
66 let axis = add(scale(a.1, cos), add(scale(cross(b.1, a.1), sin),
68 scale(b.1, dot(b.1, a.1) * (T::one() - cos))));
69 (angle, axis)
70}