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
use std::io::Result as IoResult;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::path::Path;
use ncollide_procedural::TriMesh3;
use ncollide_procedural as procedural;
use resource::Mesh;
use loader::obj;
use loader::mtl::MtlMaterial;
thread_local!(static KEY_MESH_MANAGER: RefCell<MeshManager> = RefCell::new(MeshManager::new()));
pub struct MeshManager {
meshes: HashMap<String, Rc<RefCell<Mesh>>>
}
impl MeshManager {
pub fn new() -> MeshManager {
let mut res = MeshManager {
meshes: HashMap::new()
};
let _ = res.add_trimesh(procedural::unit_sphere(50, 50, true), false, "sphere");
let _ = res.add_trimesh(procedural::unit_cuboid(), false, "cube");
let _ = res.add_trimesh(procedural::unit_cone(50), false, "cone");
let _ = res.add_trimesh(procedural::unit_cylinder(50), false, "cylinder");
res
}
pub fn get_global_manager<T, F: FnMut(&mut MeshManager) -> T>(mut f: F) -> T {
KEY_MESH_MANAGER.with(|manager| f(&mut *manager.borrow_mut()))
}
pub fn get(&mut self, name: &str) -> Option<Rc<RefCell<Mesh>>> {
self.meshes.get(&name.to_string()).map(|t| t.clone())
}
pub fn add(&mut self, mesh: Rc<RefCell<Mesh>>, name: &str) {
let _ = self.meshes.insert(name.to_string(), mesh);
}
pub fn add_trimesh(&mut self, descr: TriMesh3<f32>, dynamic_draw: bool, name: &str) -> Rc<RefCell<Mesh>> {
let mesh = Mesh::from_trimesh(descr, dynamic_draw);
let mesh = Rc::new(RefCell::new(mesh));
self.add(mesh.clone(), name);
mesh
}
pub fn remove(&mut self, name: &str) {
let _ = self.meshes.remove(&name.to_string());
}
pub fn load_obj(path: &Path, mtl_dir: &Path, geometry_name: &str)
-> IoResult<Vec<(String, Rc<RefCell<Mesh>>, Option<MtlMaterial>)>> {
obj::parse_file(path, mtl_dir, geometry_name).map(|ms| {
let mut res = Vec::new();
for (n, m, mat) in ms.into_iter() {
let m = Rc::new(RefCell::new(m));
res.push((n, m, mat));
}
res
})
}
}