vkobject_rs/
mesh.rs

1
2use crate::prelude::*;
3use std::{
4	any::{Any, TypeId, type_name},
5	collections::BTreeMap,
6	ffi::c_void,
7	fmt::Debug,
8	marker::PhantomData,
9	mem::{size_of, size_of_val},
10	path::Path,
11	ptr::{copy, null},
12	slice,
13	sync::{
14		Arc,
15		RwLock,
16		RwLockWriteGuard,
17	},
18	vec::IntoIter,
19};
20
21/// The type that could be the item of the `BufferVec`
22pub trait BufferVecStructItem: Clone + Copy + Sized + Default + Send + Sync + Debug + FFIStruct + Any {}
23impl<T> BufferVecStructItem for T where T: Clone + Copy + Sized + Default + Send + Sync + Debug + FFIStruct + Any {}
24
25/// A wrapper for `Buffer`
26#[derive(Debug, Clone)]
27pub struct BufferWithType<T>
28where
29	T: BufferVecItem {
30	/// The buffer
31	buffer: Buffer,
32
33	/// The phantom data to hold the type
34	_phantom: PhantomData<T>,
35}
36
37impl<T> BufferWithType<T>
38where
39	T: BufferVecItem {
40	/// Create the `BufferWithType<T>`
41	/// * `cmdbuf`: Could be `null`, thus the staging buffer would not be uploaded immediately.
42	pub fn new(device: Arc<VulkanDevice>, data: &[T], cmdbuf: VkCommandBuffer, usage: VkBufferUsageFlags) -> Result<Self, VulkanError> {
43		let ret = Self {
44			buffer: Buffer::new(device, size_of_val(data) as VkDeviceSize, Some(data.as_ptr() as *const c_void), usage)?,
45			_phantom: PhantomData,
46		};
47		if !cmdbuf.is_null() {
48			ret.upload_staging_buffer(cmdbuf)?;
49		}
50		Ok(ret)
51	}
52
53	/// Create the `BufferWithType<T>`
54	pub fn new_empty(device: Arc<VulkanDevice>, size: usize, usage: VkBufferUsageFlags) -> Result<Self, VulkanError> {
55		Ok(Self {
56			buffer: Buffer::new(device, (size * size_of::<T>()) as VkDeviceSize, None, usage)?,
57			_phantom: PhantomData,
58		})
59	}
60
61	/// Create the `BufferWithType<T>`
62	pub fn new_from_buffer(buffer: Buffer) -> Self {
63		Self {
64			buffer,
65			_phantom: PhantomData,
66		}
67	}
68
69	/// Get the device
70	pub fn get_device(&self) -> Arc<VulkanDevice> {
71		self.buffer.device.clone()
72	}
73
74	/// Create staging buffer for the `BufferWithType<T>`
75	pub fn ensure_staging_buffer<'a>(&'a self) -> Result<RwLockWriteGuard<'a, Option<StagingBuffer>>, VulkanError> {
76		self.buffer.ensure_staging_buffer()
77	}
78
79	/// Discard the staging buffer to save memory
80	pub fn discard_staging_buffer(&self) {
81		self.buffer.discard_staging_buffer();
82	}
83
84	/// Get data by an index
85	pub fn get_item(&self, index: usize) -> Option<T> {
86		let lock = self.buffer.staging_buffer.read().unwrap();
87		if let Some(ref staging_buffer) = *lock {
88			if index >= staging_buffer.get_size() as usize / size_of::<T>() {
89				None
90			} else {
91				let mut ret = T::default();
92				staging_buffer.get_data(&mut ret as *mut T as *mut c_void, (index * size_of::<T>()) as VkDeviceSize, size_of::<T>()).ok()?;
93				Some(ret)
94			}
95		} else {
96			None
97		}
98	}
99
100	/// Set data
101	pub fn set_item(&self, index: usize, data: T) -> Result<(), VulkanError> {
102		if index >= self.len() {
103			panic!("The index is {index}, and the size of the buffer is {}", self.len());
104		}
105		unsafe {self.buffer.set_staging_data(&data as *const T as *const c_void, (index * size_of::<T>()) as VkDeviceSize, size_of::<T>())}
106	}
107
108	/// Get all data
109	pub fn get_data(&self) -> Option<&[T]> {
110		let lock = self.buffer.staging_buffer.read().unwrap();
111		if let Some(ref staging_buffer) = *lock {
112			Some(unsafe {slice::from_raw_parts(staging_buffer.get_address() as *const T, self.len())})
113		} else {
114			None
115		}
116	}
117
118	/// Map as slice
119	pub fn map_staging_buffer_as_slice_locked<'a>(&'a self) -> Result<BufferMapGuard<'a, T>, VulkanError> {
120		self.buffer.map_staging_buffer_as_slice_locked()
121	}
122
123	/// Set all data
124	/// **NOTE** The buffer will be resized to the exact size of the data, causes the return value of `get_vk_buffer` to be changed to a new buffer.
125	pub fn set_data(&mut self, data: &[T]) -> Result<(), VulkanError> {
126		if self.len() != data.len() {
127			self.buffer = Buffer::new(self.buffer.device.clone(), size_of_val(data) as VkDeviceSize, Some(data.as_ptr() as *const c_void), self.buffer.usage)?;
128		}
129		unsafe {self.buffer.set_staging_data(data.as_ptr() as *const c_void, 0, size_of_val(data))}
130	}
131
132	/// Upload staging buffer data to buffer
133	pub fn upload_staging_buffer(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
134		self.buffer.upload_staging_buffer(cmdbuf, 0, self.buffer.get_size())
135	}
136
137	/// Get the count of the data
138	pub fn len(&self) -> usize {
139		self.buffer.get_size() as usize / size_of::<T>()
140	}
141
142	/// Get if the buffer is empty
143	pub fn is_empty(&self) -> bool {
144		self.buffer.get_size() == 0
145	}
146
147	/// Get the inner buffer
148	pub fn into_inner(self) -> Buffer {
149		self.buffer
150	}
151}
152
153unsafe impl<T> Send for BufferWithType<T> where T: BufferVecItem {}
154unsafe impl<T> Sync for BufferWithType<T> where T: BufferVecItem {}
155
156/// The trait for the mesh to hold buffers
157pub trait BufferForDraw<T>: Clone + Send + Sync + Debug + Any
158where
159	T: BufferVecItem {
160	/// Used to create the buffer
161	fn create(device: Arc<VulkanDevice>, data: &[T], cmdbuf: VkCommandBuffer, usage: VkBufferUsageFlags) -> Result<Self, VulkanError>;
162
163	/// Must be able to get the `VkBuffer` handle
164	fn get_vk_buffer(&self) -> VkBuffer;
165
166	/// Get the device
167	fn get_device(&self) -> Arc<VulkanDevice>;
168
169	/// Set data to be flushed
170	fn set_data(&mut self, data: &[T]) -> Result<(), VulkanError>;
171
172	/// Flush staging buffer data to GPU
173	fn flush(&mut self, _cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
174		Ok(())
175	}
176
177	/// Discard staging buffer if the buffer's staging buffer is discardable
178	fn discard_staging_buffer(&self) {}
179
180	/// Get the number of the items in the buffer
181	fn len(&self) -> usize;
182
183	/// Check if the buffer is empty
184	fn is_empty(&self) -> bool {
185		self.len() == 0
186	}
187
188	/// Convert to `BufferVec<T>`
189	fn convert_to_buffer_vec(self) -> BufferVec<T>;
190
191	/// Convert to `BufferWithType<T>`
192	fn convert_to_buffer_with_type(self) -> BufferWithType<T>;
193}
194
195impl<T> BufferForDraw<T> for BufferVec<T>
196where
197	T: BufferVecItem {
198	fn create(device: Arc<VulkanDevice>, data: &[T], cmdbuf: VkCommandBuffer, usage: VkBufferUsageFlags) -> Result<Self, VulkanError> {
199		BufferVec::from(device, data, cmdbuf, usage)
200	}
201
202	fn get_vk_buffer(&self) -> VkBuffer {
203		self.get_vk_buffer()
204	}
205
206	fn get_device(&self) -> Arc<VulkanDevice> {
207		self.get_device()
208	}
209
210	fn set_data(&mut self, data: &[T]) -> Result<(), VulkanError> {
211		self.resize(data.len(), T::default())?;
212		let s: &mut [T] = &mut self[..];
213		unsafe {copy(data.as_ptr(), s.as_mut_ptr(), s.len())};
214		Ok(())
215	}
216
217	fn flush(&mut self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
218		self.flush(cmdbuf)
219	}
220
221	fn len(&self) -> usize {
222		self.len()
223	}
224
225	fn convert_to_buffer_vec(self) -> BufferVec<T> {
226		self
227	}
228
229	fn convert_to_buffer_with_type(self) -> BufferWithType<T> {
230		BufferWithType::new_from_buffer(self.into_inner())
231	}
232}
233
234impl<T> BufferForDraw<T> for BufferWithType<T>
235where
236	T: BufferVecItem {
237	fn create(device: Arc<VulkanDevice>, data: &[T], cmdbuf: VkCommandBuffer, usage: VkBufferUsageFlags) -> Result<Self, VulkanError> {
238		BufferWithType::new(device, data, cmdbuf, usage)
239	}
240
241	fn get_vk_buffer(&self) -> VkBuffer {
242		self.buffer.get_vk_buffer()
243	}
244
245	fn get_device(&self) -> Arc<VulkanDevice> {
246		self.get_device()
247	}
248
249	fn set_data(&mut self, data: &[T]) -> Result<(), VulkanError> {
250		self.set_data(data)
251	}
252
253	fn flush(&mut self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
254		self.upload_staging_buffer(cmdbuf)?;
255		Ok(())
256	}
257
258	fn discard_staging_buffer(&self) {
259		self.discard_staging_buffer()
260	}
261
262	fn len(&self) -> usize {
263		self.len()
264	}
265
266	fn convert_to_buffer_vec(self) -> BufferVec<T> {
267		let len = self.len();
268		unsafe {BufferVec::from_raw_parts(self.into_inner(), len).unwrap()}
269	}
270
271	fn convert_to_buffer_with_type(self) -> BufferWithType<T> {
272		self
273	}
274}
275
276#[derive(Debug, Clone)]
277pub struct Mesh<BV, V, BE, E, BI, I, BC, C>
278where
279	BV: BufferForDraw<V>,
280	BE: BufferForDraw<E>,
281	BI: BufferForDraw<I>,
282	BC: BufferForDraw<C>,
283	V: BufferVecStructItem,
284	E: BufferVecItem,
285	I: BufferVecStructItem,
286	C: BufferVecStructItem {
287	pub primitive_type: VkPrimitiveTopology,
288	pub vertices: Arc<RwLock<BV>>,
289	pub indices: Option<Arc<RwLock<BE>>>,
290	pub instances: Option<Arc<RwLock<BI>>>,
291	pub commands: Option<Arc<RwLock<BC>>>,
292	vertex_type: V,
293	element_type: E,
294	instance_type: I,
295	command_type: C,
296}
297
298/// If a buffer you don't need, use this for your buffer item type
299#[ffi_struct]
300#[derive(Default, Debug, Clone, Copy)]
301pub struct UnusedBufferItem {}
302
303/// If a buffer you don't need, use this for your buffer type
304pub type UnusedBufferType = BufferWithType<UnusedBufferItem>;
305
306/// Use this function to create an unused buffer type
307pub fn buffer_unused() -> Option<Arc<RwLock<UnusedBufferType>>> {
308	None
309}
310
311impl<BV, V, BE, E, BI, I, BC, C> Mesh<BV, V, BE, E, BI, I, BC, C>
312where
313	BV: BufferForDraw<V>,
314	BE: BufferForDraw<E>,
315	BI: BufferForDraw<I>,
316	BC: BufferForDraw<C>,
317	V: BufferVecStructItem,
318	E: BufferVecItem,
319	I: BufferVecStructItem,
320	C: BufferVecStructItem {
321	/// Create the mesh from the buffers
322	pub fn new(primitive_type: VkPrimitiveTopology, vertices: Arc<RwLock<BV>>, indices: Option<Arc<RwLock<BE>>>, instances: Option<Arc<RwLock<BI>>>, commands: Option<Arc<RwLock<BC>>>) -> Self {
323		Self {
324			primitive_type,
325			vertices,
326			indices,
327			instances,
328			commands,
329			vertex_type: V::default(),
330			element_type: E::default(),
331			instance_type: I::default(),
332			command_type: C::default(),
333		}
334	}
335
336	/// Create the index buffer
337	pub fn create_index_buffer(&mut self, cmdbuf: VkCommandBuffer, data: *const c_void, size: usize) -> Result<(), VulkanError> {
338		let device = self.vertices.read().unwrap().get_device();
339		let data_slice = unsafe {slice::from_raw_parts(data as *const E, size / size_of::<E>())};
340		self.indices = Some(Arc::new(RwLock::new(BE::create(device, data_slice, cmdbuf, VkBufferUsageFlagBits::VK_BUFFER_USAGE_INDEX_BUFFER_BIT as VkBufferUsageFlags)?)));
341		Ok(())
342	}
343
344	/// Create the instance buffer
345	pub fn create_instance_buffer(&mut self, cmdbuf: VkCommandBuffer, data: *const c_void, size: usize) -> Result<(), VulkanError> {
346		let device = self.vertices.read().unwrap().get_device();
347		let data_slice = unsafe {slice::from_raw_parts(data as *const I, size / size_of::<I>())};
348		self.instances = Some(Arc::new(RwLock::new(BI::create(device, data_slice, cmdbuf, VkBufferUsageFlagBits::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT as VkBufferUsageFlags)?)));
349		Ok(())
350	}
351
352	/// Create the command buffer
353	pub fn create_command_buffer(&mut self, cmdbuf: VkCommandBuffer, data: *const c_void, size: usize) -> Result<(), VulkanError> {
354		let device = self.vertices.read().unwrap().get_device();
355		let data_slice = unsafe {slice::from_raw_parts(data as *const C, size / size_of::<C>())};
356		self.commands = Some(Arc::new(RwLock::new(BC::create(device, data_slice, cmdbuf, VkBufferUsageFlagBits::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT as VkBufferUsageFlags)?)));
357		Ok(())
358	}
359
360	/// Upload staging buffers to GPU
361	pub fn flush(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
362		filter_no_staging_buffer(self.vertices.write().unwrap().flush(cmdbuf))?;
363		if let Some(ref indices) = self.indices {filter_no_staging_buffer(indices.write().unwrap().flush(cmdbuf))?;}
364		if let Some(ref instances) = self.instances {filter_no_staging_buffer(instances.write().unwrap().flush(cmdbuf))?;}
365		if let Some(ref commands) = self.commands {filter_no_staging_buffer(commands.write().unwrap().flush(cmdbuf))?;}
366		Ok(())
367	}
368
369	/// Discard staging buffers if the data will never be modified.
370	pub fn discard_staging_buffers(&self) {
371		self.vertices.write().unwrap().discard_staging_buffer();
372		if let Some(ref indices) = self.indices {indices.write().unwrap().discard_staging_buffer();}
373		if let Some(ref instances) = self.instances {instances.write().unwrap().discard_staging_buffer();}
374		if let Some(ref commands) = self.commands {commands.write().unwrap().discard_staging_buffer();}
375	}
376}
377
378/// The most typical static mesh type: use `BufferWithType` for vertices and elements(indices), use `BufferVec` for instances and draw commands
379pub type StaticMesh<V, E, I, C> = Mesh<BufferWithType<V>, V, BufferWithType<E>, E, BufferVec<I>, I, BufferVec<C>, C>;
380
381/// The dynamic mesh type: use `BufferVec` for all buffers
382pub type DynamicMesh<V, E, I, C> = Mesh<BufferVec<V>, V, BufferVec<E>, E, BufferVec<I>, I, BufferVec<C>, C>;
383
384/// The trait for a mesh
385pub trait GenericMesh: Debug + Any + Send + Sync {
386	/// Clone the mesh
387	fn clone(&self) -> Box<dyn GenericMesh>;
388
389	/// Get the vertex buffer
390	fn get_vk_vertex_buffer(&self) -> VkBuffer;
391
392	/// Get the index buffer
393	fn get_vk_index_buffer(&self) -> Option<VkBuffer>;
394
395	/// Get the instance buffer
396	fn get_vk_instance_buffer(&self) -> Option<VkBuffer>;
397
398	/// Get the command buffer
399	fn get_vk_command_buffer(&self) -> Option<VkBuffer>;
400
401	/// Create the index buffer
402	fn create_index_buffer(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
403
404	/// Create the instance buffer
405	fn create_instance_buffer(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
406
407	/// Create the command buffer
408	fn create_command_buffer(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
409
410	/// Get the vertex buffer
411	fn set_vertex_buffer_data(&self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
412
413	/// Get the index buffer
414	fn set_index_buffer_data(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
415
416	/// Get the instance buffer
417	fn set_instance_buffer_data(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
418
419	/// Get the command buffer
420	fn set_command_buffer_data(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError>;
421
422	/// Get the primitive type
423	fn get_primitive_type(&self) -> VkPrimitiveTopology;
424
425	/// Get vertex count
426	fn get_vertex_count(&self) -> usize;
427
428	/// Get index count
429	fn get_index_count(&self) -> usize;
430
431	/// Get instance count
432	fn get_instance_count(&self) -> usize;
433
434	/// Get command count
435	fn get_command_count(&self) -> usize;
436
437	/// Get the iterator for the vertex buffer item structure
438	fn iter_vertex_buffer_struct_members(&self) -> IntoIter<(&'static str, MemberInfo)>;
439
440	/// Get the TypeId of the index buffer item
441	fn get_index_type_id(&self) -> Option<TypeId>;
442
443	/// Get the iterator for the vertex buffer item structure
444	fn iter_instance_buffer_struct_members(&self) -> Option<IntoIter<(&'static str, MemberInfo)>>;
445
446	/// Get the iterator for the vertex buffer item structure
447	fn iter_command_buffer_struct_members(&self) -> Option<IntoIter<(&'static str, MemberInfo)>>;
448
449	/// Get the stride of the vertex buffer
450	fn get_vertex_type_name(&self) -> &'static str;
451
452	/// Get the stride of the index buffer
453	fn get_index_type_name(&self) -> &'static str;
454
455	/// Get the stride of the instance buffer
456	fn get_instance_type_name(&self) -> &'static str;
457
458	/// Get the stride of the command buffer
459	fn get_command_type_name(&self) -> &'static str;
460
461	/// Get the stride of the vertex buffer
462	fn get_vertex_stride(&self) -> usize;
463
464	/// Get the stride of the index buffer
465	fn get_index_stride(&self) -> usize;
466
467	/// Get the stride of the instance buffer
468	fn get_instance_stride(&self) -> usize;
469
470	/// Get the stride of the command buffer
471	fn get_command_stride(&self) -> usize;
472
473	/// Flush all buffers that needs to be flushed to use
474	fn flush(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError>;
475
476	/// Discard staging buffers if the data will never be modified.
477	fn discard_staging_buffers(&self);
478
479	/// Get the index type
480	fn get_index_type(&self) -> Option<VkIndexType> {
481		match self.get_index_stride() {
482			0 => None,
483			1 => Some(VkIndexType::VK_INDEX_TYPE_UINT8),
484			2 => Some(VkIndexType::VK_INDEX_TYPE_UINT16),
485			4 => Some(VkIndexType::VK_INDEX_TYPE_UINT32),
486			_ => panic!("Unsupported index type: {}", self.get_index_type_name()),
487		}
488	}
489}
490
491impl<BV, V, BE, E, BI, I, BC, C> GenericMesh for Mesh<BV, V, BE, E, BI, I, BC, C>
492where
493	BV: BufferForDraw<V>,
494	BE: BufferForDraw<E>,
495	BI: BufferForDraw<I>,
496	BC: BufferForDraw<C>,
497	V: BufferVecStructItem,
498	E: BufferVecItem,
499	I: BufferVecStructItem,
500	C: BufferVecStructItem {
501	fn clone(&self) -> Box<dyn GenericMesh> {
502		Box::new(Clone::clone(self))
503	}
504
505	fn get_vk_vertex_buffer(&self) -> VkBuffer {
506		self.vertices.read().unwrap().get_vk_buffer()
507	}
508
509	fn get_vk_index_buffer(&self) -> Option<VkBuffer> {
510		self.indices.as_ref().map(|b|b.read().unwrap().get_vk_buffer())
511	}
512
513	fn get_vk_instance_buffer(&self) -> Option<VkBuffer> {
514		self.instances.as_ref().map(|b|b.read().unwrap().get_vk_buffer())
515	}
516
517	fn get_vk_command_buffer(&self) -> Option<VkBuffer> {
518		self.commands.as_ref().map(|b|b.read().unwrap().get_vk_buffer())
519	}
520
521	fn create_index_buffer(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
522		self.create_index_buffer(null(), data, size)
523	}
524
525	fn create_instance_buffer(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
526		self.create_instance_buffer(null(), data, size)
527	}
528
529	fn create_command_buffer(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
530		self.create_command_buffer(null(), data, size)
531	}
532
533	fn set_vertex_buffer_data(&self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
534		self.vertices.write().unwrap().set_data(unsafe {slice::from_raw_parts(data as *const V, size / size_of::<V>())})
535	}
536
537	fn set_index_buffer_data(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
538		if let Some(ref mut eb) = self.indices {
539			eb.write().unwrap().set_data(unsafe {slice::from_raw_parts(data as *const E, size / size_of::<E>())})?;
540		} else {
541			self.create_index_buffer(null(), data, size)?;
542		}
543		Ok(())
544	}
545
546	fn set_instance_buffer_data(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
547		if let Some(ref mut ib) = self.instances {
548			ib.write().unwrap().set_data(unsafe {slice::from_raw_parts(data as *const I, size / size_of::<I>())})?;
549		} else {
550			self.create_instance_buffer(null(), data, size)?;
551		}
552		Ok(())
553	}
554
555	fn set_command_buffer_data(&mut self, data: *const c_void, size: usize) -> Result<(), VulkanError> {
556		if let Some(ref mut cb) = self.commands {
557			cb.write().unwrap().set_data(unsafe {slice::from_raw_parts(data as *const C, size / size_of::<C>())})?;
558		} else {
559			self.create_command_buffer(null(), data, size)?;
560		}
561		Ok(())
562	}
563
564	fn get_primitive_type(&self) -> VkPrimitiveTopology {
565		self.primitive_type
566	}
567
568	fn get_vertex_count(&self) -> usize {
569		self.vertices.read().unwrap().len()
570	}
571
572	fn get_index_count(&self) -> usize {
573		if let Some(indices) = &self.indices {
574			indices.read().unwrap().len()
575		} else {
576			0
577		}
578	}
579
580	fn get_instance_count(&self) -> usize {
581		if let Some(instances) = &self.instances {
582			instances.read().unwrap().len()
583		} else {
584			1
585		}
586	}
587
588	fn get_command_count(&self) -> usize {
589		if let Some(commands) = &self.commands {
590			commands.read().unwrap().len()
591		} else {
592			0
593		}
594	}
595
596	fn iter_vertex_buffer_struct_members(&self) -> IntoIter<(&'static str, MemberInfo)> {
597		self.vertex_type.iter_members()
598	}
599
600	fn get_index_type_id(&self) -> Option<TypeId> {
601		self.indices.as_ref().map(|_|self.element_type.type_id())
602	}
603
604	fn iter_instance_buffer_struct_members(&self) -> Option<IntoIter<(&'static str, MemberInfo)>> {
605		self.instances.as_ref().map(|_|self.instance_type.iter_members())
606	}
607
608	fn iter_command_buffer_struct_members(&self) -> Option<IntoIter<(&'static str, MemberInfo)>> {
609		self.commands.as_ref().map(|_|self.command_type.iter_members())
610	}
611
612	fn get_vertex_type_name(&self) -> &'static str {
613		type_name::<V>()
614	}
615
616	fn get_index_type_name(&self) -> &'static str {
617		type_name::<E>()
618	}
619
620	fn get_instance_type_name(&self) -> &'static str {
621		type_name::<I>()
622	}
623
624	fn get_command_type_name(&self) -> &'static str {
625		type_name::<C>()
626	}
627
628	fn get_vertex_stride(&self) -> usize {
629		size_of::<V>()
630	}
631
632	fn get_index_stride(&self) -> usize {
633		size_of::<E>()
634	}
635
636	fn get_instance_stride(&self) -> usize {
637		size_of::<I>()
638	}
639
640	fn get_command_stride(&self) -> usize {
641		size_of::<C>()
642	}
643
644	fn flush(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
645		self.flush(cmdbuf)
646	}
647
648	fn discard_staging_buffers(&self) {
649		self.discard_staging_buffers()
650	}
651}
652
653/// Obj file parse error
654#[derive(Debug, Clone)]
655pub struct ObjParseError {
656	pub line_number: usize,
657	pub message: String,
658}
659
660derive_vertex_type! {
661	/// The struct for OBJ vertices with position data only
662	pub struct ObjVertPositionOnly {
663		pub position: Vec3,
664	}
665}
666
667derive_vertex_type! {
668	/// The struct for OBJ vertices with position data and normal data
669	pub struct ObjVertPositionNormal {
670		pub position: Vec3,
671		pub normal: Vec3,
672	}
673}
674
675derive_vertex_type! {
676	/// The struct for OBJ vertices with position data and and texcoord data (2D)
677	pub struct ObjVertPositionTexcoord2D {
678		pub position: Vec3,
679		pub texcoord: Vec2,
680	}
681}
682
683derive_vertex_type! {
684	/// The struct for OBJ vertices with position data and texcoord data (3D)
685	pub struct ObjVertPositionTexcoord3D {
686		pub position: Vec3,
687		pub texcoord: Vec3,
688	}
689}
690
691derive_vertex_type! {
692	/// The struct for OBJ vertices with position data, texcoord data (2D) and normal data
693	pub struct ObjVertPositionTexcoord2DNormal {
694		pub position: Vec3,
695		pub texcoord: Vec2,
696		pub normal: Vec3,
697	}
698}
699
700derive_vertex_type! {
701	/// The struct for OBJ vertices with position data, texcoord data (2D) and normal data
702	pub struct ObjVertPositionTexcoord2DNormalTangent {
703		pub position: Vec3,
704		pub texcoord: Vec2,
705		pub normal: Vec3,
706		pub tangent: Vec3,
707	}
708}
709
710derive_vertex_type! {
711	/// The struct for OBJ vertices with position data, texcoord data (3D) and normal data
712	pub struct ObjVertPositionTexcoord3DNormal {
713		pub position: Vec3,
714		pub texcoord: Vec3,
715		pub normal: Vec3,
716	}
717}
718
719derive_vertex_type! {
720	/// The struct for OBJ vertices with position data only
721	pub struct ObjVertPositionOnlyDouble {
722		pub position: DVec3,
723	}
724}
725
726derive_vertex_type! {
727	/// The struct for OBJ vertices with position data and normal data
728	pub struct ObjVertPositionNormalDouble {
729		pub position: DVec3,
730		pub normal: DVec3,
731	}
732}
733
734derive_vertex_type! {
735	/// The struct for OBJ vertices with position data and and texcoord data (2D)
736	pub struct ObjVertPositionTexcoord2DDouble {
737		pub position: DVec3,
738		pub texcoord: DVec2,
739	}
740}
741
742derive_vertex_type! {
743	/// The struct for OBJ vertices with position data and texcoord data (3D)
744	pub struct ObjVertPositionTexcoord3DDouble {
745		pub position: DVec3,
746		pub texcoord: DVec3,
747	}
748}
749
750derive_vertex_type! {
751	/// The struct for OBJ vertices with position data, texcoord data (2D) and normal data
752	pub struct ObjVertPositionTexcoord2DNormalDouble {
753		pub position: DVec3,
754		pub texcoord: DVec2,
755		pub normal: DVec3,
756	}
757}
758
759derive_vertex_type! {
760	/// The struct for OBJ vertices with position data, texcoord data (2D) and normal data
761	pub struct ObjVertPositionTexcoord2DNormalTangentDouble {
762		pub position: DVec3,
763		pub texcoord: DVec2,
764		pub normal: DVec3,
765		pub tangent: DVec3,
766	}
767}
768
769derive_vertex_type! {
770	/// The struct for OBJ vertices with position data, texcoord data (3D) and normal data
771	pub struct ObjVertPositionTexcoord3DNormalDouble {
772		pub position: DVec3,
773		pub texcoord: DVec3,
774		pub normal: DVec3,
775	}
776}
777
778derive_vertex_type! {
779	/// The struct for OBJ vertices with position data only
780	pub struct ObjVertDontCare {
781		// Nothing
782	}
783}
784
785impl<F> From<ObjVertices<F>> for ObjVertPositionOnly
786where
787	F: ObjMeshVecCompType, f32: From<F> {
788	fn from(f: ObjVertices<F>) -> Self {
789		Self {
790			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
791		}
792	}
793}
794
795impl<F> From<ObjVertices<F>> for ObjVertPositionNormal
796where
797	F: ObjMeshVecCompType, f32: From<F> {
798	fn from(f: ObjVertices<F>) -> Self {
799		Self {
800			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
801			normal: if let Some(normal) = f.normal {
802				Vec3::new(normal.x.into(), normal.y.into(), normal.z.into())
803			} else {
804				Vec3::default()
805			},
806		}
807	}
808}
809
810impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord2D
811where
812	F: ObjMeshVecCompType, f32: From<F> {
813	fn from(f: ObjVertices<F>) -> Self {
814		Self {
815			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
816			texcoord: if let Some(texcoord) = f.texcoord {
817				Vec2::new(texcoord.x.into(), texcoord.y.into())
818			} else {
819				Vec2::default()
820			},
821		}
822	}
823}
824
825impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord3D
826where
827	F: ObjMeshVecCompType, f32: From<F> {
828	fn from(f: ObjVertices<F>) -> Self {
829		Self {
830			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
831			texcoord: if let Some(texcoord) = f.texcoord {
832				Vec3::new(texcoord.x.into(), texcoord.y.into(), texcoord.z.into())
833			} else {
834				Vec3::default()
835			},
836		}
837	}
838}
839
840impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord2DNormal
841where
842	F: ObjMeshVecCompType, f32: From<F> {
843	fn from(f: ObjVertices<F>) -> Self {
844		Self {
845			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
846			texcoord: if let Some(texcoord) = f.texcoord {
847				Vec2::new(texcoord.x.into(), texcoord.y.into())
848			} else {
849				Vec2::default()
850			},
851			normal: if let Some(normal) = f.normal {
852				Vec3::new(normal.x.into(), normal.y.into(), normal.z.into())
853			} else {
854				Vec3::default()
855			},
856		}
857	}
858}
859
860impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord2DNormalTangent
861where
862	F: ObjMeshVecCompType, f32: From<F> {
863	fn from(f: ObjVertices<F>) -> Self {
864		Self {
865			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
866			texcoord: if let Some(texcoord) = f.texcoord {
867				Vec2::new(texcoord.x.into(), texcoord.y.into())
868			} else {
869				Vec2::default()
870			},
871			normal: if let Some(normal) = f.normal {
872				Vec3::new(normal.x.into(), normal.y.into(), normal.z.into())
873			} else {
874				Vec3::default()
875			},
876			tangent: if let Some(tangent) = f.tangent {
877				Vec3::new(tangent.x.into(), tangent.y.into(), tangent.z.into())
878			} else {
879				Vec3::default()
880			},
881		}
882	}
883}
884
885impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord3DNormal
886where
887	F: ObjMeshVecCompType, f32: From<F> {
888	fn from(f: ObjVertices<F>) -> Self {
889		Self {
890			position: Vec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
891			texcoord: if let Some(texcoord) = f.texcoord {
892				Vec3::new(texcoord.x.into(), texcoord.y.into(), texcoord.z.into())
893			} else {
894				Vec3::default()
895			},
896			normal: if let Some(normal) = f.normal {
897				Vec3::new(normal.x.into(), normal.y.into(), normal.z.into())
898			} else {
899				Vec3::default()
900			},
901		}
902	}
903}
904
905impl<F> From<ObjVertices<F>> for ObjVertPositionOnlyDouble
906where
907	F: ObjMeshVecCompType, f64: From<F> {
908	fn from(f: ObjVertices<F>) -> Self {
909		Self {
910			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
911		}
912	}
913}
914
915impl<F> From<ObjVertices<F>> for ObjVertPositionNormalDouble
916where
917	F: ObjMeshVecCompType, f64: From<F> {
918	fn from(f: ObjVertices<F>) -> Self {
919		Self {
920			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
921			normal: if let Some(normal) = f.normal {
922				DVec3::new(normal.x.into(), normal.y.into(), normal.z.into())
923			} else {
924				DVec3::default()
925			},
926		}
927	}
928}
929
930impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord2DDouble
931where
932	F: ObjMeshVecCompType, f64: From<F> {
933	fn from(f: ObjVertices<F>) -> Self {
934		Self {
935			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
936			texcoord: if let Some(texcoord) = f.texcoord {
937				DVec2::new(texcoord.x.into(), texcoord.y.into())
938			} else {
939				DVec2::default()
940			},
941		}
942	}
943}
944
945impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord3DDouble
946where
947	F: ObjMeshVecCompType, f64: From<F> {
948	fn from(f: ObjVertices<F>) -> Self {
949		Self {
950			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
951			texcoord: if let Some(texcoord) = f.texcoord {
952				DVec3::new(texcoord.x.into(), texcoord.y.into(), texcoord.z.into())
953			} else {
954				DVec3::default()
955			},
956		}
957	}
958}
959
960impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord2DNormalDouble
961where
962	F: ObjMeshVecCompType, f64: From<F> {
963	fn from(f: ObjVertices<F>) -> Self {
964		Self {
965			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
966			texcoord: if let Some(texcoord) = f.texcoord {
967				DVec2::new(texcoord.x.into(), texcoord.y.into())
968			} else {
969				DVec2::default()
970			},
971			normal: if let Some(normal) = f.normal {
972				DVec3::new(normal.x.into(), normal.y.into(), normal.z.into())
973			} else {
974				DVec3::default()
975			},
976		}
977	}
978}
979
980impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord2DNormalTangentDouble
981where
982	F: ObjMeshVecCompType, f64: From<F> {
983	fn from(f: ObjVertices<F>) -> Self {
984		Self {
985			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
986			texcoord: if let Some(texcoord) = f.texcoord {
987				DVec2::new(texcoord.x.into(), texcoord.y.into())
988			} else {
989				DVec2::default()
990			},
991			normal: if let Some(normal) = f.normal {
992				DVec3::new(normal.x.into(), normal.y.into(), normal.z.into())
993			} else {
994				DVec3::default()
995			},
996			tangent: if let Some(tangent) = f.tangent {
997				DVec3::new(tangent.x.into(), tangent.y.into(), tangent.z.into())
998			} else {
999				DVec3::default()
1000			},
1001		}
1002	}
1003}
1004
1005impl<F> From<ObjVertices<F>> for ObjVertPositionTexcoord3DNormalDouble
1006where
1007	F: ObjMeshVecCompType, f64: From<F> {
1008	fn from(f: ObjVertices<F>) -> Self {
1009		Self {
1010			position: DVec3::new(f.position.x.into(), f.position.y.into(), f.position.z.into()),
1011			texcoord: if let Some(texcoord) = f.texcoord {
1012				DVec3::new(texcoord.x.into(), texcoord.y.into(), texcoord.z.into())
1013			} else {
1014				DVec3::default()
1015			},
1016			normal: if let Some(normal) = f.normal {
1017				DVec3::new(normal.x.into(), normal.y.into(), normal.z.into())
1018			} else {
1019				DVec3::default()
1020			},
1021		}
1022	}
1023}
1024
1025impl<F> From<ObjVertices<F>> for ObjVertDontCare
1026where
1027	F: ObjMeshVecCompType, f32: From<F> {
1028	fn from(_: ObjVertices<F>) -> Self {
1029		Self {}
1030	}
1031}
1032
1033/// A Mesh with a material
1034#[derive(Debug, Clone)]
1035pub struct GenericMeshWithMaterial {
1036	/// The mesh
1037	pub geometry: Arc<dyn GenericMesh>,
1038
1039	/// The name of the material
1040	pub material_name: String,
1041
1042	/// The material
1043	pub material: Option<Arc<dyn Material>>,
1044}
1045
1046impl GenericMeshWithMaterial {
1047	/// Create an instance for the `GenericMeshWithMaterial`
1048	pub fn new(geometry: Arc<dyn GenericMesh>, material_name: &str, material: Option<Arc<dyn Material>>) -> Self {
1049		Self {
1050			geometry,
1051			material_name: material_name.to_string(),
1052			material,
1053		}
1054	}
1055
1056	/// Discard staging buffers for the mesh
1057	pub fn discard_staging_buffers(&self) {
1058		self.geometry.discard_staging_buffers();
1059	}
1060}
1061
1062unsafe impl Send for GenericMeshWithMaterial {}
1063unsafe impl Sync for GenericMeshWithMaterial {}
1064
1065/// The mesh set
1066#[derive(Debug, Clone)]
1067pub struct GenericMeshSet<I>
1068where
1069	I: BufferVecStructItem {
1070	/// The meshset
1071	pub meshset: BTreeMap<String, Arc<GenericMeshWithMaterial>>,
1072
1073	/// The instance buffer of the meshset, modify this instance buffer equals to modify each meshes' instance buffer
1074	instances: Option<Arc<RwLock<BufferVec<I>>>>,
1075}
1076
1077impl<I> GenericMeshSet<I>
1078where
1079	I: BufferVecStructItem {
1080	/// Load the `obj` file and create the meshset, all the materials were also loaded.
1081	pub fn create_meshset_from_obj_file<F, ObjVertexType, P>(device: Arc<VulkanDevice>, path: P, cmdbuf: VkCommandBuffer, instances_data: Option<&[I]>) -> Result<Self, VulkanError>
1082	where
1083		P: AsRef<Path>,
1084		F: ObjMeshVecCompType,
1085		f32: From<F>,
1086		f64: From<F>,
1087		ObjVertexType: VertexType + From<ObjVertices<F>> + Send + Sync {
1088		let obj = ObjMesh::<F>::from_file(path)?;
1089		Self::create_meshset_from_obj::<F, ObjVertexType>(device, &obj, cmdbuf, instances_data)
1090	}
1091
1092	/// Load the `obj` file and create the meshset, all the materials were also loaded.
1093	pub fn create_meshset_from_obj<F, ObjVertexType>(device: Arc<VulkanDevice>, obj: &ObjMesh::<F>, cmdbuf: VkCommandBuffer, instances_data: Option<&[I]>) -> Result<Self, VulkanError>
1094	where
1095		F: ObjMeshVecCompType,
1096		f32: From<F>,
1097		f64: From<F>,
1098		ObjVertexType: VertexType + From<ObjVertices<F>> + Send + Sync {
1099		let obj_mesh_set: ObjIndexedMeshSet<F, u32> = {
1100			let mut uim = obj.convert_to_unindexed_meshes()?;
1101			for m in uim.iter_mut() {
1102				// It's okay to fail to generate tangents here.
1103				let _ = m.generate_tangents();
1104			}
1105			ObjUnindexedMesh::convert_to_indexed_meshes(&uim)?
1106		};
1107		let (pdim, tdim, ndim) = obj_mesh_set.get_vert_dims();
1108		let template_mesh;
1109		macro_rules! vert_conv {
1110			($type:ty, $src:ident) => {
1111				{let vertices: Vec<$type> = $src.iter().map(|v|<$type>::from(*v)).collect(); vertices}
1112			}
1113		}
1114		macro_rules! vb_create {
1115			($dev:ident, $vb:ident, $cb:ident) => {
1116				BufferWithType::new($dev.clone(), &$vb, $cb, VkBufferUsageFlagBits::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT as VkBufferUsageFlags)
1117			}
1118		}
1119		let instances = if let Some(id) = instances_data {
1120			Some(Arc::new(RwLock::new(BufferVec::from(device.clone(), id, cmdbuf, VkBufferUsageFlagBits::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT as VkBufferUsageFlags)?)))
1121		} else {
1122			None
1123		};
1124		macro_rules! mesh_create {
1125			($vb:ident) => {
1126				{
1127					let mesh: Box<dyn GenericMesh> = Box::new(Mesh::new(VkPrimitiveTopology::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, Arc::new(RwLock::new($vb)), Option::<Arc::<RwLock::<BufferWithType::<u32>>>>::None, instances.clone(), buffer_unused()));
1128					mesh
1129				}
1130			}
1131		}
1132		#[allow(non_camel_case_types)] type ObjV___F = ObjVertPositionOnly;
1133		#[allow(non_camel_case_types)] type ObjV__NF = ObjVertPositionNormal;
1134		#[allow(non_camel_case_types)] type ObjV2D_F = ObjVertPositionTexcoord2D;
1135		#[allow(non_camel_case_types)] type ObjV3D_F = ObjVertPositionTexcoord3D;
1136		#[allow(non_camel_case_types)] type ObjV2DNF = ObjVertPositionTexcoord2DNormalTangent;
1137		#[allow(non_camel_case_types)] type ObjV3DNF = ObjVertPositionTexcoord3DNormal;
1138		#[allow(non_camel_case_types)] type ObjV___D = ObjVertPositionOnlyDouble;
1139		#[allow(non_camel_case_types)] type ObjV__ND = ObjVertPositionNormalDouble;
1140		#[allow(non_camel_case_types)] type ObjV2D_D = ObjVertPositionTexcoord2DDouble;
1141		#[allow(non_camel_case_types)] type ObjV3D_D = ObjVertPositionTexcoord3DDouble;
1142		#[allow(non_camel_case_types)] type ObjV2DND = ObjVertPositionTexcoord2DNormalTangentDouble;
1143		#[allow(non_camel_case_types)] type ObjV3DND = ObjVertPositionTexcoord3DNormalDouble;
1144		if TypeId::of::<ObjVertexType>() == TypeId::of::<ObjVertDontCare>() {
1145			if TypeId::of::<F>() == TypeId::of::<f32>() {
1146				match (pdim, tdim, ndim) {
1147					(_, 0, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV___F, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1148					(_, 1, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2D_F, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1149					(_, 2, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2D_F, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1150					(_, 3, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV3D_F, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1151					(_, 0, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV__NF, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1152					(_, 1, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2DNF, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1153					(_, 2, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2DNF, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1154					(_, 3, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV3DNF, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1155					(_, _, _) => panic!("Unknown VTN dimensions: V({pdim}), T({tdim}), N({ndim})"),
1156				}
1157			} else if TypeId::of::<F>() == TypeId::of::<f64>() {
1158				match (pdim, tdim, ndim) {
1159					(_, 0, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV___D, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1160					(_, 1, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2D_D, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1161					(_, 2, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2D_D, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1162					(_, 3, 0) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV3D_D, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1163					(_, 0, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV__ND, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1164					(_, 1, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2DND, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1165					(_, 2, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV2DND, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1166					(_, 3, _) => {let fv = obj_mesh_set.face_vertices; let vertices = vert_conv!(ObjV3DND, fv); let vb = vb_create!(device, vertices, cmdbuf)?; template_mesh = mesh_create!(vb)}
1167					(_, _, _) => panic!("Unknown VTN dimensions: V({pdim}), T({tdim}), N({ndim})"),
1168				}
1169			} else {
1170				let name_of_f = type_name::<F>();
1171				panic!("Unsupported generic type `{name_of_f}`, couldn't match its type id to neither `f32` nor `f64`");
1172			}
1173		} else {
1174			let fv = obj_mesh_set.face_vertices;
1175			let vertices = vert_conv!(ObjVertexType, fv);
1176			let vb = vb_create!(device, vertices, cmdbuf)?;
1177			template_mesh = mesh_create!(vb);
1178		}
1179		let mut materials: BTreeMap<String, Arc<dyn Material>> = BTreeMap::new();
1180		for (matname, matdata) in obj.materials.iter() {
1181			materials.insert(matname.clone(), create_material_from_obj_material(device.clone(), cmdbuf, &*matdata.read().unwrap())?);
1182		}
1183		let mut meshset = BTreeMap::new();
1184		for objmesh in obj_mesh_set.meshes.iter() {
1185			let object_name = &objmesh.object_name;
1186			let group_name = &objmesh.group_name;
1187			let material_name = &objmesh.material_name;
1188			let smooth_group = objmesh.smooth_group;
1189			let mut indices: Vec<u32> = Vec::with_capacity(objmesh.face_indices.len() * 3);
1190			let mut mesh = template_mesh.clone();
1191			for (v1, v2, v3) in objmesh.face_indices.iter() {
1192				indices.extend([v1, v2, v3]);
1193			}
1194			mesh.create_index_buffer(indices.as_ptr() as *const c_void, indices.len() * size_of::<u32>())?;
1195			mesh.flush(cmdbuf)?;
1196			meshset.insert(format!("{object_name}_{group_name}_{material_name}_{smooth_group}"), Arc::new(GenericMeshWithMaterial::new(Arc::from(mesh), material_name, materials.get(material_name).cloned())));
1197		}
1198		Ok(Self {
1199			meshset,
1200			instances,
1201		})
1202	}
1203
1204	/// Edit the instance buffer
1205	pub fn edit_instances<'a>(&'a self) -> Option<RwLockWriteGuard<'a, BufferVec<I>>> {
1206		self.instances.as_ref().map(|ib|ib.write().unwrap())
1207	}
1208
1209	/// Discard staging buffers for all meshes
1210	pub fn discard_staging_buffers(&self) {
1211		for mesh in self.meshset.values() {
1212			mesh.discard_staging_buffers();
1213		}
1214	}
1215}
1216
1217unsafe impl<I> Send for GenericMeshSet<I> where I: BufferVecStructItem {}
1218unsafe impl<I> Sync for GenericMeshSet<I> where I: BufferVecStructItem {}