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
use std::f32;
use cgmath::{EuclideanSpace, InnerSpace};
use smallvec::SmallVec;
use collision::*;
use geom::*;
pub const PERSISTENT_THRESHOLD_SQ: f32 = 1.0;
#[derive(Clone, Debug)]
pub struct Manifold {
pub min_coll_time: f32,
pub contacts: SmallVec<[LocalContact; 4]>,
}
impl Manifold {
pub fn new() -> Self {
Manifold {
min_coll_time: f32::INFINITY,
contacts: SmallVec::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
Manifold {
min_coll_time: f32::INFINITY,
contacts: SmallVec::with_capacity(cap),
}
}
pub fn push(&mut self, new_contact: LocalContact) {
if new_contact.global.t < self.min_coll_time - COLLISION_EPSILON {
self.contacts.clear();
self.contacts.push(new_contact);
self.min_coll_time = new_contact.global.t;
return;
} else if new_contact.global.t > self.min_coll_time + COLLISION_EPSILON {
return;
}
for old_contact in self.contacts.iter_mut() {
let ra = new_contact.global.a - old_contact.global.a;
let rb = new_contact.global.b - old_contact.global.b;
if ra.magnitude2() <= PERSISTENT_THRESHOLD_SQ ||
rb.magnitude2() <= PERSISTENT_THRESHOLD_SQ
{
let prev_dist = old_contact.local_a.to_vec().magnitude2() +
old_contact.local_b.to_vec().magnitude2();
let new_dist = new_contact.local_a.to_vec().magnitude2() +
new_contact.local_b.to_vec().magnitude2();
if prev_dist < new_dist {
*old_contact = new_contact;
}
return;
}
}
self.contacts.push(new_contact);
}
}