1use super::*;
2
3#[derive(ugli::Vertex, Debug, Copy, Clone)]
4pub struct Vertex {
5 pub a_v: Vec3<f32>,
6 pub a_vt: Vec2<f32>,
7 pub a_vn: Vec3<f32>,
8}
9
10pub fn parse(source: &str) -> HashMap<String, Vec<Vertex>> {
11 let mut result = HashMap::new();
12
13 let mut current_name = String::from("__unnamed__");
14
15 let mut v = Vec::new();
16 let mut vn = Vec::new();
17 let mut vt = Vec::new();
18 let mut current_obj = Vec::new();
19 for line in source.lines().chain(std::iter::once("o _")) {
20 if line.starts_with("v ") {
21 let mut parts = line.split_whitespace();
22 parts.next();
23 let x: f32 = parts.next().unwrap().parse().unwrap();
24 let y: f32 = parts.next().unwrap().parse().unwrap();
25 let z: f32 = parts.next().unwrap().parse().unwrap();
26 v.push(vec3(x, y, z));
27 } else if line.starts_with("vn ") {
28 let mut parts = line.split_whitespace();
29 parts.next();
30 let x: f32 = parts.next().unwrap().parse().unwrap();
31 let y: f32 = parts.next().unwrap().parse().unwrap();
32 let z: f32 = parts.next().unwrap().parse().unwrap();
33 vn.push(vec3(x, y, z));
34 } else if line.starts_with("vt ") {
35 let mut parts = line.split_whitespace();
36 parts.next();
37 let x: f32 = parts.next().unwrap().parse().unwrap();
38 let y: f32 = parts.next().unwrap().parse().unwrap();
39 vt.push(vec2(x, y));
40 } else if line.starts_with("f ") {
41 let mut parts = line.split_whitespace();
42 parts.next();
43 let to_vertex = |s: &str| {
44 let mut parts = s.split("/");
45 let i_v: usize = parts.next().unwrap().parse().unwrap();
46 let i_vt: usize = parts.next().unwrap().parse().unwrap();
47 let i_vn: usize = parts.next().unwrap().parse().unwrap();
48 Vertex {
49 a_v: v[i_v - 1],
50 a_vn: vn[i_vn - 1],
51 a_vt: vt[i_vt - 1],
52 }
53 };
54 let mut cur = Vec::new();
55 while let Some(s) = parts.next() {
56 cur.push(to_vertex(s));
57 }
58 for i in 2..cur.len() {
59 current_obj.push(cur[0]);
60 current_obj.push(cur[i - 1]);
61 current_obj.push(cur[i]);
62 }
63 } else if line.starts_with("o ") || line.starts_with("g ") {
64 if current_obj.len() != 0 {
65 result.insert(current_name.clone(), current_obj);
66 current_obj = Vec::new();
67 }
68 current_name = String::from(&line[2..]);
69 }
70 }
71 result
72}
73
74pub fn recalculate_normals(data: &mut [Vertex]) {
75 for face in data.chunks_mut(3) {
76 let n = Vec3::cross(face[1].a_v - face[0].a_v, face[2].a_v - face[0].a_v).normalize();
77 for v in face {
78 v.a_vn = n;
79 }
80 }
81}
82
83pub fn unitize<'a, I: Iterator<Item = &'a mut [Vertex]>>(iter: I) {
84 let vss: Vec<&'a mut [Vertex]> = iter.collect();
85 const INF: f32 = 1e9;
86 let mut min_x: f32 = INF;
87 let mut max_x: f32 = -INF;
88 let mut min_y: f32 = INF;
89 let mut max_y: f32 = -INF;
90 for vs in &vss {
91 for v in vs.iter() {
92 let x = v.a_v.x;
93 let y = v.a_v.y;
94 min_x = min_x.min(x);
95 max_x = max_x.max(x);
96 min_y = min_y.min(y);
97 max_y = max_y.max(y);
98 }
99 }
100 let center = vec3(min_x + max_x, min_y + max_y, 0.0) / 2.0;
101 let div = (max_y - min_y).max(max_x - min_x) / 2.0;
102 for vs in vss {
103 for v in vs.iter_mut() {
104 v.a_v = (v.a_v - center) / div;
105 }
106 }
107}
108
109pub fn scale(data: &mut [Vertex], k: f32) {
110 for v in data {
111 v.a_v *= k;
112 }
113}
114
115pub fn united(data: HashMap<String, Vec<Vertex>>) -> Vec<Vertex> {
116 let mut result = Vec::new();
117 for part in data.values() {
118 result.extend(part);
119 }
120 result
121}