feo_oop_engine/components/
triangle_mesh.rs1use vulkano::sync;
6
7use {
8 super::{material::Material, texture::Texture},
9 crate::{
10 shaders::fs_draw,
11 components::{Normal, TextureIndex, Vertex}
12 },
13 std::{
14 sync::Arc,
15 collections::HashMap
16 },
17 vulkano::{
18 buffer::{
19 BufferUsage,
20 CpuAccessibleBuffer
21 },
22 device::Queue,
23 sync::GpuFuture
24 }
25};
26
27#[derive(Clone)]
29pub struct TriangleMesh {
30 pub(crate) vertex_buffer: Option<Arc<CpuAccessibleBuffer<[Vertex]>>>, pub(crate) normal_buffer: Option<Arc<CpuAccessibleBuffer<[Normal]>>>,
32 pub(crate) texture_indices_buffer: Option<Arc<CpuAccessibleBuffer<[TextureIndex]>>>,
33
34 pub(crate) material: Option<(fs_draw::ty::Material, [Arc<Texture>; 4])>,
35}
36
37impl std::fmt::Debug for TriangleMesh {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 write!(f, "TriangleMesh debug todo")
40 }
41}
42
43impl TriangleMesh{
44 pub fn new_empty() -> Self{
46 TriangleMesh {
47 vertex_buffer: None,
48 normal_buffer: None,
49 texture_indices_buffer: None,
50 material: None,
51 }
52 }
53
54 pub fn new(
56 ordered_vertices: Vec<Vertex>,
57 ordered_normals: Vec<Normal>,
58 ordered_texture_indices: Vec<TextureIndex>,
59 material: Arc<Material>,
60
61 queue: Arc<Queue>) -> Self {
62
63 TriangleMesh{
64 vertex_buffer: Some(CpuAccessibleBuffer::from_iter(queue.device().clone(), BufferUsage::all(), false, ordered_vertices.iter().cloned()).unwrap()),
65 normal_buffer: Some(CpuAccessibleBuffer::from_iter(queue.device().clone(), BufferUsage::all(), false, ordered_normals.iter().cloned()).unwrap()),
66 texture_indices_buffer: Some(CpuAccessibleBuffer::from_iter(queue.device().clone(), BufferUsage::all(), false, ordered_texture_indices.iter().cloned()).unwrap()),
67 material: Some(material.into_set(queue.clone())),
68 }
69 }
70
71 #[allow(clippy::type_complexity)]
73 pub fn from_obj_block<'a>(block: &[&str], mtls_hashmap: &mut HashMap<String, (Arc<Material>, Box<dyn GpuFuture>)>, vertex_data: (&Vec<Box<Vertex>>, &Vec<Box<TextureIndex>>, &Vec<Box<Normal>>), queue: Arc<Queue>) -> Result<Self, &'a str> {
74 let mut ordered_vertices = Vec::new();
76 let mut ordered_normals = Vec::new();
77 let mut ordered_texture_indices = Vec::new();
78
79 let mut current_material: Arc<Material> = Arc::new(Material::default());
80
81 block.iter().for_each(|line| {
82 if !(*line).is_empty() {
83 let mut e = line.split_whitespace();
84 let ty: &str = e.next().unwrap();
85 match &*ty {
86
87 "f" => {
90 let mut tris = Vec::new();
91 let mut i = 0;
92 for coord in &mut e{
93 i += 1;
94 if i > 3{ tris.push(tris[0]);
96 tris.push(tris[i - 2]);
97 }
98 tris.push(coord);
99 }
100
101 let mut vertex_fmt: i8 = -1;
102 let mut developing_normal: Vec<Vertex> = Vec::new();
103 for raw in tris{
104 let part = raw.split('/').collect::<Vec<&str>>();
105
106 if vertex_fmt != part.len() as i8 {
107 if vertex_fmt == -1 {
108 vertex_fmt = part.len() as i8;
109 }else {
110 panic! ("Inconsistent face vertex format.")
111 }
112 }
113
114 let position = *vertex_data.0[part[0].parse::<usize>().unwrap() - 1_usize].clone();
115
116 let texture_index = if vertex_fmt > 1 && !part[1].is_empty() {
117 *vertex_data.1[part[1].parse::<usize>().unwrap() - 1_usize].clone()
118 } else {
119 TextureIndex::new(0.0, 0.0)
120 };
121
122 if developing_normal.is_empty() && vertex_fmt == 3 && !part[2].is_empty() { ordered_normals.push(*vertex_data.2[part[2].parse::<usize>().unwrap() - 1_usize].clone());
124 } else {
125 developing_normal.push(position);
126 }
127
128 ordered_vertices.push(position);
129 ordered_texture_indices.push(texture_index);
130 }
131
132 if developing_normal.len() > 2 {
133 let normal = Normal::calculate_normal(&developing_normal[0], &developing_normal[1], developing_normal.last().unwrap());
134
135 for _ in 0..developing_normal.len() {
136 ordered_normals.push(normal);
137 }
138 }
139 },
140
141 "usemtl" => {
144 let key = e.next().expect("formatting error");
145 let (cm, fut ) = mtls_hashmap.remove(key).unwrap();
146 current_material = cm.clone();
147 if fut.queue().is_some() {
148 let _ = Arc::new(fut.then_signal_fence_and_flush().unwrap()).wait(None); }
150 mtls_hashmap.insert(key.to_string(), (cm, sync::now(queue.device().clone()).boxed()));
151 },
152
153 &_ => {
156 panic!("Formatting error");
157 }
158
159 #[allow(unreachable_patterns)] "line" => {
164 todo!();
165 },
166 };
167 }
168
169 });
170
171 Ok(Self::new(ordered_vertices, ordered_normals, ordered_texture_indices, current_material, queue))
172 }
173}