1use std::{
2 io::{BufRead, BufReader},
3 mem::offset_of,
4};
5
6use crate::errors::GraphicsResult;
7
8pub struct Attribute {
10 pub(crate) size: usize,
11 pub(crate) offset: usize,
12}
13
14type Vec3 = [f32; 3];
15type Vec2 = [f32; 2];
16
17pub type Index = u32;
19
20#[repr(C, align(16))]
22#[derive(Clone, Copy, Default)]
23pub struct VertexTexture {
24 pos: Vec3,
25 nor: Vec3,
26 uv: Vec2,
27 col: Vec3,
28}
29
30impl VertexTexture {
31 pub fn get_attributes() -> Vec<Attribute> {
33 vec![
34 Attribute {
35 size: size_of::<Vec3>(),
36 offset: offset_of!(Self, pos),
37 },
38 Attribute {
39 size: size_of::<Vec3>(),
40 offset: offset_of!(Self, nor),
41 },
42 Attribute {
43 size: size_of::<Vec2>(),
44 offset: offset_of!(Self, uv),
45 },
46 Attribute {
47 size: size_of::<Vec3>(),
48 offset: offset_of!(Self, col),
49 },
50 ]
51 }
52}
53
54pub struct Mesh {
56 pub(crate) vertices: Vec<VertexTexture>,
57 pub(crate) indices: Vec<Index>,
58}
59
60impl Mesh {
61 pub fn screen_space_plane() -> Self {
63 let vertices = vec![
64 VertexTexture {
65 pos: [0., 0., 0.],
66 ..Default::default()
67 },
68 VertexTexture {
69 pos: [1., 0., 0.],
70 ..Default::default()
71 },
72 VertexTexture {
73 pos: [1., -1., 0.],
74 ..Default::default()
75 },
76 VertexTexture {
77 pos: [-1., -1., 0.],
78 ..Default::default()
79 },
80 ];
81
82 Self {
83 vertices,
84 indices: vec![0, 1, 2, 2, 3, 0],
85 }
86 }
87
88 pub fn from_buffer<T>(buffer: BufReader<T>) -> GraphicsResult<Self>
90 where
91 BufReader<T>: BufRead,
92 {
93 let mut vertices = vec![];
94 let mut indices = vec![];
95 let mut normals: Vec<[f32; 3]> = vec![];
96 let mut uvs: Vec<[f32; 2]> = vec![];
97
98 for line in buffer.lines() {
99 let line = match line {
100 Ok(line) => line,
101 Err(_) => continue,
102 };
103
104 let splitted: Vec<&str> = line.split_whitespace().collect();
105
106 if splitted.len() == 0 || splitted[0].chars().next().unwrap() == '#' {
107 continue;
108 }
109
110 if splitted.len() >= 3 {
111 match splitted[0] {
112 "vn" => normals.push([
113 splitted[1].parse().unwrap(),
114 splitted[2].parse().unwrap(),
115 splitted[3].parse().unwrap(),
116 ]),
117 "vt" => uvs.push([splitted[1].parse().unwrap(), splitted[2].parse().unwrap()]),
118 "v" => vertices.push(VertexTexture {
119 pos: [
120 splitted[1].parse().unwrap(),
121 splitted[2].parse().unwrap(),
122 splitted[3].parse().unwrap(),
123 ],
124 nor: [0., 0., 0.],
125 uv: [0., 0.],
126 col: if splitted.len() != 7 {
127 [0., 0., 0.]
128 } else {
129 [
130 splitted[4].parse().unwrap_or(0.),
131 splitted[5].parse().unwrap_or(0.),
132 splitted[6].parse().unwrap_or(0.),
133 ]
134 },
135 }),
136 "f" => {
137 let mut local_indices = vec![];
138
139 for &data in &splitted[1..] {
140 if data.chars().next().unwrap() == '#' {
141 break;
142 }
143 let splitted: Vec<&str> = data.split('/').collect();
144
145 let idx: i32 = splitted[0].parse().unwrap();
146 let idx: Index = if idx >= 0 {
147 (idx - 1) as Index
148 } else {
149 (idx + vertices.len() as i32) as Index
150 };
151
152 if splitted[1].len() > 0 {
153 let uv: i32 = splitted[1].parse().unwrap();
154 let uv: usize = if uv >= 0 {
155 (uv - 1) as usize
156 } else {
157 (uv + uvs.len() as i32) as usize
158 };
159 vertices[idx as usize].uv = uvs[uv];
160 }
161
162 if splitted.len() > 2 && splitted[2].len() > 0 {
163 let nor: i32 = splitted[2].parse().unwrap();
164 let nor: usize = if nor >= 0 {
165 (nor - 1) as usize
166 } else {
167 (nor + normals.len() as i32) as usize
168 };
169 vertices[idx as usize].nor = normals[nor];
170 }
171
172 local_indices.push(idx);
173 }
174
175 if local_indices.len() == 3 {
176 indices.append(&mut local_indices);
177 } else if local_indices.len() == 4 {
178 indices.push(local_indices[0]);
179 indices.push(local_indices[1]);
180 indices.push(local_indices[2]);
181
182 indices.push(local_indices[0]);
183 indices.push(local_indices[2]);
184 indices.push(local_indices[3]);
185 }
186 }
187
188 _ => (),
189 }
190 }
191 }
192
193 Ok(Self { vertices, indices })
194 }
195}