geng_core/
obj.rs

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}