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
106
107
108
109
110
111
use std::ops::{AddAssign, SubAssign};
use std::vec::Vec;
use bvh::*;
use geom::*;
use collision::*;
use bounds::{BoundedBy};
use cgmath::{EuclideanSpace, Vector3, Point3, Zero};
pub struct Vertex {
pub p: Point3<f32>,
pub n: Vector3<f32>,
}
pub struct Mesh {
pub disp: Vector3<f32>,
pub verts: Vec<Vertex>,
pub faces: Vec<(usize, usize, usize)>,
pub bvh: BVH<AABB, usize>,
}
impl Mesh {
pub fn new() -> Self {
Mesh {
disp: Vector3::zero(),
verts: Vec::new(),
faces: Vec::new(),
bvh: BVH::new(),
}
}
pub fn with_capacity(cap_verts: usize, cap_faces: usize) -> Self {
Mesh {
disp: Vector3::zero(),
verts: Vec::with_capacity(cap_verts),
faces: Vec::with_capacity(cap_faces),
bvh: BVH::with_capacity(cap_faces),
}
}
pub fn push_vert(&mut self, v: Vertex) -> usize {
let id = self.verts.len();
self.verts.push(v);
id
}
pub fn push_face(&mut self, f: (usize, usize, usize)) -> usize {
let a = self.verts[f.0].p;
let b = self.verts[f.1].p;
let c = self.verts[f.2].p;
let tri = Triangle::from((a, b, c));
let index = self.faces.len();
self.faces.push(f);
self.bvh.insert(&tri, index);
index
}
}
impl AddAssign<Vector3<f32>> for Mesh {
fn add_assign(&mut self, v: Vector3<f32>) {
self.disp += v;
}
}
impl SubAssign<Vector3<f32>> for Mesh {
fn sub_assign(&mut self, v: Vector3<f32>) {
self.disp -= v;
}
}
impl Shape for Mesh {
fn center(&self) -> Point3<f32> {
Point3::from_vec(self.disp)
}
}
impl<RHS> Contacts<RHS> for Mesh
where
RHS: Contacts<Triangle> + Contacts<Rectangle> + BoundedBy<AABB>
{
fn contacts<F: FnMut(Contact)>(&self, rhs: &RHS, mut callback: F) -> bool {
let mut collided = false;
self.bvh.query(&(rhs.bounds() - self.disp), |&face_index| {
let (a, b, c) = self.faces[face_index];
let a = self.verts[a].p + self.disp;
let b = self.verts[b].p + self.disp;
let c = self.verts[c].p + self.disp;
let tri = Triangle::from((a, b, c));
rhs.contacts(&tri, |c| { collided = true; callback(-c) });
});
collided
}
}