1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use std::ops::Mul;
use cgmath::num_traits::Float;
use cgmath::{BaseFloat, EuclideanSpace, InnerSpace, Rotation, VectorSpace, Zero};
use super::{
ApplyAngular, ForceAccumulator, Inertia, Mass, PhysicalEntity, Velocity, WorldParameters,
};
use {NextFrame, Pose};
pub fn next_frame_integration<'a, T, D, P, A, I, R>(
data: D,
world_params: &WorldParameters<P::Diff, P::Scalar>,
dt: P::Scalar,
) where
D: Iterator<
Item = (
&'a mut NextFrame<Velocity<P::Diff, A>>,
&'a NextFrame<T>,
&'a mut ForceAccumulator<P::Diff, A>,
&'a Mass<P::Scalar, I>,
&'a PhysicalEntity<P::Scalar>,
),
>,
T: Pose<P, R> + 'a,
P: EuclideanSpace + 'a,
P::Scalar: BaseFloat,
P::Diff: VectorSpace + InnerSpace + 'a,
I: Inertia<Orientation = R> + Mul<A, Output = A> + 'a,
A: Mul<P::Scalar, Output = A> + Clone + Copy + Zero + 'a,
R: Rotation<P> + ApplyAngular<P::Scalar, A> + 'a,
{
for (next_velocity, next_pose, force, mass, entity) in data.filter(|(_, _, _, _, e)| e.active())
{
let a = force.consume_force() * mass.inverse_mass()
+ world_params.gravity() * entity.gravity_scale();
let new_velocity = *next_velocity.value.linear() + a * dt;
let damp = world_params.entity_damping(entity.damping()).powf(dt);
next_velocity.value.set_linear(new_velocity * damp);
let a = mass.world_inverse_inertia(&next_pose.value.rotation()) * force.consume_torque();
let new_velocity = *next_velocity.value.angular() + a * dt;
next_velocity.value.set_angular(new_velocity);
}
}
pub fn next_frame_pose<'a, B, D, P, A, R>(data: D, dt: P::Scalar)
where
D: Iterator<
Item = (
&'a NextFrame<Velocity<P::Diff, A>>,
&'a B,
&'a mut NextFrame<B>,
&'a PhysicalEntity<P::Scalar>,
),
>,
B: Pose<P, R> + 'a,
P: EuclideanSpace + 'a,
P::Scalar: BaseFloat,
P::Diff: VectorSpace + InnerSpace + 'a,
A: Mul<P::Scalar, Output = A> + Clone + Copy + Zero + 'a,
R: Rotation<P> + ApplyAngular<P::Scalar, A> + 'a,
{
for (next_velocity, pose, next_pose, _) in data.filter(|(_, _, _, e)| e.active()) {
next_pose.value = next_velocity.value.apply(pose, dt)
}
}