1use crate::{
24 core::{
25 algebra::{Vector2, Vector3, Vector4},
26 arrayvec::ArrayVec,
27 byteorder::{ByteOrder, LittleEndian},
28 futures::io::Error,
29 math::TriangleDefinition,
30 reflect::prelude::*,
31 visitor::prelude::*,
32 },
33 core::{array_as_u8_slice, value_as_u8_slice},
34};
35use bytemuck::Pod;
36use fxhash::FxHasher;
37use fyrox_core::visitor::pod::PodVecView;
38use std::{
39 alloc::Layout,
40 fmt::{Display, Formatter},
41 hash::{Hash, Hasher},
42 marker::PhantomData,
43 mem::MaybeUninit,
44 ops::{Deref, DerefMut, Index, IndexMut, RangeBounds},
45 vec::Drain,
46};
47
48pub trait VertexTrait: Copy + 'static {
52 fn layout() -> &'static [VertexAttributeDescriptor];
55}
56
57#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
59#[repr(u8)]
60#[derive(Default)]
61pub enum VertexAttributeDataType {
62 #[default]
64 F32,
65 U32,
67 U16,
69 U8,
71}
72
73impl VertexAttributeDataType {
74 pub fn size(self) -> u8 {
76 match self {
77 VertexAttributeDataType::F32 | VertexAttributeDataType::U32 => 4,
78 VertexAttributeDataType::U16 => 2,
79 VertexAttributeDataType::U8 => 1,
80 }
81 }
82}
83
84#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
87#[repr(u32)]
88#[derive(Default)]
89pub enum VertexAttributeUsage {
90 #[default]
92 Position = 0,
93 Normal = 1,
95 Tangent = 2,
97 TexCoord0 = 3,
100 TexCoord1 = 4,
102 TexCoord2 = 5,
104 TexCoord3 = 6,
106 TexCoord4 = 7,
108 TexCoord5 = 8,
110 TexCoord6 = 9,
112 TexCoord7 = 10,
114 BoneWeight = 11,
116 BoneIndices = 12,
118 Color = 13,
120 Custom0 = 14,
122 Custom1 = 15,
124 Custom2 = 16,
126 Custom3 = 17,
128 Custom4 = 18,
130 Custom5 = 19,
132 Custom6 = 20,
134 Custom7 = 21,
136 Count,
138}
139
140#[derive(Debug, Hash)]
142pub struct VertexAttributeDescriptor {
143 pub usage: VertexAttributeUsage,
145 pub data_type: VertexAttributeDataType,
147 pub size: u8,
150 pub divisor: u8,
155 pub shader_location: u8,
157 pub normalized: bool,
166}
167
168#[derive(Reflect, Visit, Copy, Clone, Default, Debug, Hash)]
171pub struct VertexAttribute {
172 pub usage: VertexAttributeUsage,
174 pub data_type: VertexAttributeDataType,
176 pub size: u8,
179 pub divisor: u8,
184 pub offset: u8,
186 pub shader_location: u8,
188 #[visit(optional)]
197 pub normalized: bool,
198}
199
200impl Display for VertexAttribute {
201 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
202 write!(
203 f,
204 "Vertex Attribute:\n\tUsage: {:?}\n\tData Type: {:?}\n\tComponent Count: {}\n\t\
205 Divisor: {}\n\tOffset: {}\n\tBinding Point:{}\n\tNormalized: {}",
206 self.usage,
207 self.data_type,
208 self.size,
209 self.divisor,
210 self.offset,
211 self.shader_location,
212 self.normalized
213 )
214 }
215}
216
217#[derive(Reflect, Clone, Debug)]
219pub struct BytesStorage {
220 bytes: Vec<u8>,
221 #[reflect(hidden)]
222 layout: Layout,
223}
224
225impl Visit for BytesStorage {
226 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
227 let mut bytes_adapter = PodVecView::from_pod_vec(&mut self.bytes);
228 if bytes_adapter.visit(name, visitor).is_err() {
229 let mut bytes = Vec::<u8>::new();
230 bytes.visit(name, visitor)?;
231 self.bytes = bytes;
232 }
233
234 if visitor.is_reading() {
235 self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
236 }
237 Ok(())
238 }
239}
240
241impl Default for BytesStorage {
242 fn default() -> Self {
243 Self {
244 bytes: Default::default(),
245 layout: Layout::array::<u8>(0).unwrap(),
246 }
247 }
248}
249
250impl BytesStorage {
251 pub fn with_capacity(capacity: usize) -> Self {
253 Self {
254 bytes: Vec::with_capacity(capacity),
255 layout: Layout::array::<u8>(capacity).unwrap(),
256 }
257 }
258
259 pub fn new<T>(data: Vec<T>) -> Self {
261 let mut data = std::mem::ManuallyDrop::new(data);
264 let bytes_length = data.len() * std::mem::size_of::<T>();
265 let bytes_capacity = data.capacity() * std::mem::size_of::<T>();
266 Self {
267 bytes: unsafe {
268 Vec::<u8>::from_raw_parts(
269 data.as_mut_ptr() as *mut u8,
270 bytes_length,
271 bytes_capacity,
272 )
273 },
274 layout: Layout::array::<T>(data.capacity()).unwrap(),
277 }
278 }
279
280 fn extend_from_slice(&mut self, slice: &[u8]) {
281 if self.layout.align() != 1 {
282 let new_storage = Vec::with_capacity(self.bytes.len());
284 let old_storage = std::mem::replace(&mut self.bytes, new_storage);
285 self.bytes.extend_from_slice(old_storage.as_slice());
286 self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
287 }
288 self.bytes.extend_from_slice(slice);
289 self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
290 }
291
292 fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
293 where
294 R: RangeBounds<usize>,
295 {
296 self.bytes.drain(range)
297 }
298
299 fn as_mut_ptr(&mut self) -> *mut u8 {
300 self.bytes.as_mut_ptr()
301 }
302
303 fn as_slice_mut(&mut self) -> &mut [u8] {
304 self.bytes.as_mut_slice()
305 }
306
307 fn clear(&mut self) {
308 self.bytes.clear()
309 }
310}
311
312impl Drop for BytesStorage {
313 fn drop(&mut self) {
314 let mut bytes = std::mem::ManuallyDrop::new(std::mem::take(&mut self.bytes));
315 if bytes.capacity() != 0 {
317 unsafe { std::alloc::dealloc(bytes.as_mut_ptr(), self.layout) }
318 }
319 }
320}
321
322impl Deref for BytesStorage {
323 type Target = Vec<u8>;
324
325 fn deref(&self) -> &Self::Target {
326 &self.bytes
327 }
328}
329
330#[derive(Reflect, Clone, Visit, Default, Debug)]
398pub struct VertexBuffer {
399 dense_layout: Vec<VertexAttribute>,
400 sparse_layout: [Option<VertexAttribute>; VertexAttributeUsage::Count as usize],
401 vertex_size: u8,
402 vertex_count: u32,
403 data: BytesStorage,
404 #[visit(optional)]
405 layout_hash: u64,
406 #[visit(optional)]
407 modifications_counter: u64,
408}
409
410fn calculate_layout_hash(layout: &[VertexAttribute]) -> u64 {
411 let mut hasher = FxHasher::default();
412 layout.hash(&mut hasher);
413 hasher.finish()
414}
415
416fn calculate_data_hash(data: &[u8]) -> u64 {
417 let mut hasher = FxHasher::default();
418 data.hash(&mut hasher);
419 hasher.finish()
420}
421
422pub struct VertexBufferRefMut<'a> {
424 vertex_buffer: &'a mut VertexBuffer,
425}
426
427impl Drop for VertexBufferRefMut<'_> {
428 fn drop(&mut self) {
429 self.vertex_buffer.modifications_counter += 1;
430 }
431}
432
433impl Deref for VertexBufferRefMut<'_> {
434 type Target = VertexBuffer;
435
436 fn deref(&self) -> &Self::Target {
437 self.vertex_buffer
438 }
439}
440
441impl DerefMut for VertexBufferRefMut<'_> {
442 fn deref_mut(&mut self) -> &mut Self::Target {
443 self.vertex_buffer
444 }
445}
446
447impl VertexBufferRefMut<'_> {
448 pub fn push_vertex<T>(&mut self, vertex: &T) -> Result<(), ValidationError>
456 where
457 T: VertexTrait + bytemuck::Pod,
458 {
459 if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
460 self.vertex_buffer
461 .data
462 .extend_from_slice(value_as_u8_slice(vertex));
463 self.vertex_buffer.vertex_count += 1;
464 Ok(())
465 } else {
466 Err(ValidationError::InvalidVertexSize {
467 expected: self.vertex_buffer.vertex_size,
468 actual: std::mem::size_of::<T>() as u8,
469 })
470 }
471 }
472
473 pub fn push_vertices<T>(&mut self, vertices: &[T]) -> Result<(), ValidationError>
481 where
482 T: VertexTrait + Pod,
483 {
484 if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
485 self.vertex_buffer
486 .data
487 .extend_from_slice(array_as_u8_slice(vertices));
488 self.vertex_buffer.vertex_count += vertices.len() as u32;
489 Ok(())
490 } else {
491 Err(ValidationError::InvalidVertexSize {
492 expected: self.vertex_buffer.vertex_size,
493 actual: std::mem::size_of::<T>() as u8,
494 })
495 }
496 }
497
498 pub fn push_vertex_raw(&mut self, data: &[u8]) -> Result<(), ValidationError> {
501 if data.len() == self.vertex_buffer.vertex_size as usize {
502 self.vertex_buffer.data.extend_from_slice(data);
503 self.vertex_buffer.vertex_count += 1;
504 Ok(())
505 } else {
506 Err(ValidationError::InvalidVertexSize {
507 expected: self.vertex_buffer.vertex_size,
508 actual: data.len() as u8,
509 })
510 }
511 }
512
513 pub fn push_vertices_iter<T>(
521 &mut self,
522 vertices: impl Iterator<Item = T>,
523 ) -> Result<(), ValidationError>
524 where
525 T: VertexTrait + Pod,
526 {
527 if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
528 for vertex in vertices {
529 self.vertex_buffer
530 .data
531 .extend_from_slice(value_as_u8_slice(&vertex));
532 self.vertex_buffer.vertex_count += 1;
533 }
534 Ok(())
535 } else {
536 Err(ValidationError::InvalidVertexSize {
537 expected: self.vertex_buffer.vertex_size,
538 actual: std::mem::size_of::<T>() as u8,
539 })
540 }
541 }
542
543 pub fn push_vertices_transform<T, F>(
552 &mut self,
553 vertices: &[T],
554 mut transformer: F,
555 ) -> Result<(), ValidationError>
556 where
557 T: VertexTrait + Pod,
558 F: FnMut(&T) -> T,
559 {
560 if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
561 for vertex in vertices {
562 let transformed = transformer(vertex);
563
564 self.vertex_buffer
565 .data
566 .extend_from_slice(value_as_u8_slice(&transformed));
567 }
568 self.vertex_buffer.vertex_count += vertices.len() as u32;
569 Ok(())
570 } else {
571 Err(ValidationError::InvalidVertexSize {
572 expected: self.vertex_buffer.vertex_size,
573 actual: std::mem::size_of::<T>() as u8,
574 })
575 }
576 }
577
578 pub fn remove_last_vertex(&mut self) {
580 let range = (self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize)..;
581 self.vertex_buffer.data.drain(range);
582 self.vertex_buffer.vertex_count -= 1;
583 }
584
585 pub fn pop_vertex<T>(&mut self) -> Result<T, ValidationError>
593 where
594 T: VertexTrait,
595 {
596 if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize
597 && self.vertex_buffer.data.len() >= self.vertex_buffer.vertex_size as usize
598 {
599 unsafe {
600 let mut v = MaybeUninit::<T>::uninit();
601 std::ptr::copy_nonoverlapping(
602 self.vertex_buffer.data.as_ptr().add(
603 self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize,
604 ),
605 v.as_mut_ptr() as *mut u8,
606 self.vertex_buffer.vertex_size as usize,
607 );
608 let range =
609 (self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize)..;
610 self.vertex_buffer.data.drain(range);
611 self.vertex_buffer.vertex_count -= 1;
612 Ok(v.assume_init())
613 }
614 } else {
615 Err(ValidationError::InvalidVertexSize {
616 expected: self.vertex_buffer.vertex_size,
617 actual: std::mem::size_of::<T>() as u8,
618 })
619 }
620 }
621
622 pub fn cast_data_mut<T>(&mut self) -> Result<&mut [T], ValidationError>
625 where
626 T: VertexTrait,
627 {
628 if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
629 Ok(unsafe {
630 std::slice::from_raw_parts_mut(
631 self.vertex_buffer.data.as_mut_ptr() as *const T as *mut T,
632 self.vertex_buffer.data.len() / std::mem::size_of::<T>(),
633 )
634 })
635 } else {
636 Err(ValidationError::InvalidVertexSize {
637 expected: self.vertex_buffer.vertex_size,
638 actual: std::mem::size_of::<T>() as u8,
639 })
640 }
641 }
642
643 pub fn iter_mut(&mut self) -> impl Iterator<Item = VertexViewMut<'_>> + '_ {
645 unsafe {
646 VertexViewMutIterator {
647 ptr: self.vertex_buffer.data.as_mut_ptr(),
648 end: self.data.as_mut_ptr().add(
649 self.vertex_buffer.vertex_size as usize
650 * self.vertex_buffer.vertex_count as usize,
651 ),
652 vertex_size: self.vertex_buffer.vertex_size,
653 sparse_layout: &self.vertex_buffer.sparse_layout,
654 marker: PhantomData,
655 }
656 }
657 }
658
659 pub fn get_mut(&mut self, n: usize) -> Option<VertexViewMut<'_>> {
661 let offset = n * self.vertex_buffer.vertex_size as usize;
662 if offset < self.vertex_buffer.data.len() {
663 Some(VertexViewMut {
664 vertex_data: &mut self.vertex_buffer.data.as_slice_mut()
665 [offset..(offset + self.vertex_buffer.vertex_size as usize)],
666 sparse_layout: &self.vertex_buffer.sparse_layout,
667 })
668 } else {
669 None
670 }
671 }
672
673 pub fn duplicate(&mut self, n: usize) {
675 let mut temp = ArrayVec::<u8, 256>::new();
678 temp.try_extend_from_slice(
679 &self.vertex_buffer.data[(n * self.vertex_buffer.vertex_size as usize)
680 ..((n + 1) * self.vertex_buffer.vertex_size as usize)],
681 )
682 .unwrap();
683 self.vertex_buffer.data.extend_from_slice(temp.as_slice());
684 self.vertex_buffer.vertex_count += 1;
685 }
686
687 pub fn add_attribute<T>(
695 &mut self,
696 descriptor: VertexAttributeDescriptor,
697 fill_value: T,
698 ) -> Result<(), ValidationError>
699 where
700 T: Copy + Pod,
701 {
702 if self.vertex_buffer.sparse_layout[descriptor.usage as usize].is_some() {
703 Err(ValidationError::DuplicatedAttributeDescriptor)
704 } else {
705 let vertex_attribute = VertexAttribute {
706 usage: descriptor.usage,
707 data_type: descriptor.data_type,
708 size: descriptor.size,
709 divisor: descriptor.divisor,
710 offset: self.vertex_buffer.vertex_size,
711 shader_location: descriptor.shader_location,
712 normalized: descriptor.normalized,
713 };
714 self.vertex_buffer.sparse_layout[descriptor.usage as usize] = Some(vertex_attribute);
715 self.vertex_buffer.dense_layout.push(vertex_attribute);
716
717 self.layout_hash = calculate_layout_hash(&self.vertex_buffer.dense_layout);
718
719 let mut new_data = Vec::new();
720
721 for chunk in self
722 .vertex_buffer
723 .data
724 .chunks_exact(self.vertex_buffer.vertex_size as usize)
725 {
726 let mut temp = ArrayVec::<u8, 256>::new();
727 temp.try_extend_from_slice(chunk).unwrap();
728 temp.try_extend_from_slice(value_as_u8_slice(&fill_value))
729 .unwrap();
730 new_data.extend_from_slice(&temp);
731 }
732
733 self.vertex_buffer.data = BytesStorage::new(new_data);
734
735 self.vertex_buffer.vertex_size += std::mem::size_of::<T>() as u8;
736
737 Ok(())
738 }
739 }
740
741 pub fn clear(&mut self) {
743 self.data.clear();
744 self.vertex_count = 0;
745 }
746}
747
748#[derive(Debug)]
750pub enum ValidationError {
751 InvalidAttributeSize(usize),
753
754 InvalidDataSize {
756 expected: usize,
758 actual: usize,
760 },
761
762 InvalidVertexSize {
764 expected: u8,
766 actual: u8,
768 },
769
770 DuplicatedAttributeDescriptor,
772
773 ConflictingShaderLocations(usize),
775}
776
777impl Display for ValidationError {
778 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
779 match self {
780 ValidationError::InvalidAttributeSize(v) => {
781 write!(f, "Invalid attribute size {v}. Must be either 1, 2, 3 or 4")
782 }
783 ValidationError::InvalidDataSize { expected, actual } => {
784 write!(f, "Invalid data size. Expected {expected}, got {actual}.")
785 }
786 ValidationError::InvalidVertexSize { expected, actual } => {
787 write!(f, "Invalid vertex size. Expected {expected}, got {actual}.",)
788 }
789 ValidationError::DuplicatedAttributeDescriptor => {
790 write!(f, "A duplicate of a descriptor was found.")
791 }
792 ValidationError::ConflictingShaderLocations(v) => {
793 write!(f, "Duplicate shader locations were found {v}.")
794 }
795 }
796 }
797}
798
799impl VertexBuffer {
800 pub fn new<T>(vertex_count: usize, data: Vec<T>) -> Result<Self, ValidationError>
802 where
803 T: VertexTrait,
804 {
805 Self::new_with_layout(T::layout(), vertex_count, BytesStorage::new(data))
806 }
807
808 pub fn new_with_layout(
810 layout: &[VertexAttributeDescriptor],
811 vertex_count: usize,
812 bytes: BytesStorage,
813 ) -> Result<Self, ValidationError> {
814 for descriptor in layout {
816 for other_descriptor in layout {
817 if !std::ptr::eq(descriptor, other_descriptor) {
818 if descriptor.usage == other_descriptor.usage {
819 return Err(ValidationError::DuplicatedAttributeDescriptor);
820 } else if descriptor.shader_location == other_descriptor.shader_location {
821 return Err(ValidationError::ConflictingShaderLocations(
822 descriptor.shader_location as usize,
823 ));
824 }
825 }
826 }
827 }
828
829 let mut dense_layout = Vec::new();
830
831 let mut sparse_layout = [None; VertexAttributeUsage::Count as usize];
833 let mut vertex_size_bytes = 0u8;
834 for attribute in layout.iter() {
835 if attribute.size < 1 || attribute.size > 4 {
836 return Err(ValidationError::InvalidAttributeSize(
837 attribute.size as usize,
838 ));
839 }
840
841 let vertex_attribute = VertexAttribute {
842 usage: attribute.usage,
843 data_type: attribute.data_type,
844 size: attribute.size,
845 divisor: attribute.divisor,
846 offset: vertex_size_bytes,
847 shader_location: attribute.shader_location,
848 normalized: attribute.normalized,
849 };
850
851 dense_layout.push(vertex_attribute);
852
853 sparse_layout[attribute.usage as usize] = Some(vertex_attribute);
855
856 vertex_size_bytes += attribute.size * attribute.data_type.size();
857 }
858
859 let expected_data_size = vertex_count * vertex_size_bytes as usize;
860 if expected_data_size != bytes.len() {
861 return Err(ValidationError::InvalidDataSize {
862 expected: expected_data_size,
863 actual: bytes.len(),
864 });
865 }
866
867 Ok(Self {
868 vertex_size: vertex_size_bytes,
869 vertex_count: vertex_count as u32,
870 modifications_counter: 0,
871 data: bytes,
872 layout_hash: calculate_layout_hash(&dense_layout),
873 sparse_layout,
874 dense_layout,
875 })
876 }
877
878 pub fn clone_empty(&self, capacity: usize) -> Self {
881 Self {
882 dense_layout: self.dense_layout.clone(),
883 sparse_layout: self.sparse_layout,
884 vertex_size: self.vertex_size,
885 vertex_count: 0,
886 data: BytesStorage::with_capacity(capacity),
887 layout_hash: self.layout_hash,
888 modifications_counter: 0,
889 }
890 }
891
892 pub fn raw_data(&self) -> &[u8] {
894 &self.data
895 }
896
897 pub fn is_empty(&self) -> bool {
899 self.vertex_count == 0
900 }
901
902 pub fn modifications_count(&self) -> u64 {
904 self.modifications_counter
905 }
906
907 pub fn content_hash(&self) -> u64 {
909 calculate_data_hash(&self.data.bytes)
910 }
911
912 pub fn layout_hash(&self) -> u64 {
915 self.layout_hash
916 }
917
918 pub fn modify(&mut self) -> VertexBufferRefMut<'_> {
963 VertexBufferRefMut {
964 vertex_buffer: self,
965 }
966 }
967
968 pub fn has_attribute(&self, usage: VertexAttributeUsage) -> bool {
970 self.sparse_layout[usage as usize].is_some()
971 }
972
973 pub fn layout(&self) -> &[VertexAttribute] {
975 &self.dense_layout
976 }
977
978 pub fn layout_descriptor(&self) -> impl Iterator<Item = VertexAttributeDescriptor> + '_ {
980 self.dense_layout
981 .iter()
982 .map(|attrib| VertexAttributeDescriptor {
983 usage: attrib.usage,
984 data_type: attrib.data_type,
985 size: attrib.size,
986 divisor: attrib.divisor,
987 shader_location: attrib.shader_location,
988 normalized: attrib.normalized,
989 })
990 }
991
992 pub fn cast_data_ref<T>(&self) -> Result<&[T], ValidationError>
995 where
996 T: VertexTrait,
997 {
998 if std::mem::size_of::<T>() == self.vertex_size as usize {
999 Ok(unsafe {
1000 std::slice::from_raw_parts(
1001 self.data.as_ptr() as *const T,
1002 self.data.len() / std::mem::size_of::<T>(),
1003 )
1004 })
1005 } else {
1006 Err(ValidationError::InvalidVertexSize {
1007 expected: self.vertex_size,
1008 actual: std::mem::size_of::<T>() as u8,
1009 })
1010 }
1011 }
1012
1013 pub fn iter(&self) -> impl Iterator<Item = VertexViewRef<'_>> + '_ {
1015 VertexViewRefIterator {
1016 data: &self.data,
1017 offset: 0,
1018 end: self.vertex_size as usize * self.vertex_count as usize,
1019 vertex_size: self.vertex_size,
1020 sparse_layout: &self.sparse_layout,
1021 }
1022 }
1023
1024 pub fn get(&self, n: usize) -> Option<VertexViewRef<'_>> {
1026 let offset = n * self.vertex_size as usize;
1027 if offset < self.data.len() {
1028 Some(VertexViewRef {
1029 vertex_data: &self.data[offset..(offset + self.vertex_size as usize)],
1030 sparse_layout: &self.sparse_layout,
1031 })
1032 } else {
1033 None
1034 }
1035 }
1036
1037 pub fn vertex_count(&self) -> u32 {
1039 self.vertex_count
1040 }
1041
1042 pub fn vertex_size(&self) -> u8 {
1044 self.vertex_size
1045 }
1046
1047 pub fn find_free_shader_location(&self) -> u8 {
1049 let mut location = None;
1050 for attribute in self.dense_layout.chunks_exact(2) {
1051 let left = &attribute[0];
1052 let right = &attribute[1];
1053
1054 if (left.shader_location as i32 - right.shader_location as i32).abs() > 1 {
1055 let origin = left.shader_location.min(right.shader_location);
1057 location = Some(origin + 1);
1058 break;
1059 }
1060 }
1061
1062 location.unwrap_or_else(|| {
1063 self.dense_layout
1064 .last()
1065 .map(|a| a.shader_location)
1066 .unwrap_or(0)
1067 + 1
1068 })
1069 }
1070
1071 #[inline]
1074 pub fn attribute_view<T>(&self, usage: VertexAttributeUsage) -> Option<AttributeViewRef<'_, T>>
1075 where
1076 T: Copy,
1077 {
1078 self.dense_layout
1079 .iter()
1080 .find(|attribute| {
1081 attribute.usage == usage
1082 && attribute.size * attribute.data_type.size() == std::mem::size_of::<T>() as u8
1083 })
1084 .map(|attribute| AttributeViewRef {
1085 ptr: unsafe { self.data.bytes.as_ptr().add(attribute.offset as usize) },
1086 stride: self.vertex_size as usize,
1087 count: self.vertex_count as usize,
1088 phantom: Default::default(),
1089 })
1090 }
1091
1092 #[inline]
1095 pub fn attribute_view_mut<T: Copy>(
1096 &mut self,
1097 usage: VertexAttributeUsage,
1098 ) -> Option<AttributeViewRefMut<'_, T>> {
1099 if let Some(attribute) = self.dense_layout.iter().find(|attribute| {
1100 attribute.usage == usage
1101 && attribute.size * attribute.data_type.size() == std::mem::size_of::<T>() as u8
1102 }) {
1103 Some(AttributeViewRefMut {
1104 ptr: unsafe { self.data.bytes.as_mut_ptr().add(attribute.offset as usize) },
1105 stride: self.vertex_size as usize,
1106 count: self.vertex_count as usize,
1107 phantom: Default::default(),
1108 })
1109 } else {
1110 None
1111 }
1112 }
1113}
1114
1115struct VertexViewRefIterator<'a> {
1116 data: &'a [u8],
1117 sparse_layout: &'a [Option<VertexAttribute>],
1118 offset: usize,
1119 end: usize,
1120 vertex_size: u8,
1121}
1122
1123impl<'a> Iterator for VertexViewRefIterator<'a> {
1124 type Item = VertexViewRef<'a>;
1125
1126 fn next(&mut self) -> Option<Self::Item> {
1127 if self.offset >= self.end {
1128 None
1129 } else {
1130 let view = VertexViewRef {
1131 vertex_data: &self.data[self.offset..(self.offset + self.vertex_size as usize)],
1132 sparse_layout: self.sparse_layout,
1133 };
1134 self.offset += self.vertex_size as usize;
1135 Some(view)
1136 }
1137 }
1138}
1139
1140struct VertexViewMutIterator<'a> {
1141 ptr: *mut u8,
1142 sparse_layout: &'a [Option<VertexAttribute>],
1143 end: *mut u8,
1144 vertex_size: u8,
1145 marker: PhantomData<&'a mut u8>,
1146}
1147
1148impl<'a> Iterator for VertexViewMutIterator<'a> {
1149 type Item = VertexViewMut<'a>;
1150
1151 fn next(&mut self) -> Option<Self::Item> {
1152 if self.ptr >= self.end {
1153 None
1154 } else {
1155 unsafe {
1156 let data = std::slice::from_raw_parts_mut(self.ptr, self.vertex_size as usize);
1157 let view = VertexViewMut {
1158 vertex_data: data,
1159 sparse_layout: self.sparse_layout,
1160 };
1161 self.ptr = self.ptr.add(self.vertex_size as usize);
1162 Some(view)
1163 }
1164 }
1165 }
1166}
1167
1168#[derive(Debug)]
1170pub struct VertexViewRef<'a> {
1171 vertex_data: &'a [u8],
1172 sparse_layout: &'a [Option<VertexAttribute>],
1173}
1174
1175impl PartialEq for VertexViewRef<'_> {
1176 fn eq(&self, other: &Self) -> bool {
1177 self.vertex_data == other.vertex_data
1178 }
1179}
1180
1181#[derive(Debug)]
1183pub struct VertexViewMut<'a> {
1184 vertex_data: &'a mut [u8],
1185 sparse_layout: &'a [Option<VertexAttribute>],
1186}
1187
1188impl PartialEq for VertexViewMut<'_> {
1189 fn eq(&self, other: &Self) -> bool {
1190 self.vertex_data == other.vertex_data
1191 }
1192}
1193
1194#[derive(Debug)]
1196pub enum VertexFetchError {
1197 NoSuchAttribute(VertexAttributeUsage),
1199 SizeMismatch {
1201 expected: u8,
1203 actual: u8,
1205 },
1206 Io(std::io::Error),
1208}
1209
1210impl std::error::Error for VertexFetchError {}
1211
1212impl Display for VertexFetchError {
1213 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1214 match self {
1215 VertexFetchError::NoSuchAttribute(v) => {
1216 write!(f, "No attribute with such usage: {v:?}")
1217 }
1218 VertexFetchError::Io(v) => {
1219 write!(f, "An i/o error has occurred {v:?}")
1220 }
1221 VertexFetchError::SizeMismatch { expected, actual } => {
1222 write!(f, "Size mismatch. Expected {expected}, got {actual}")
1223 }
1224 }
1225 }
1226}
1227
1228impl From<std::io::Error> for VertexFetchError {
1229 fn from(e: Error) -> Self {
1230 Self::Io(e)
1231 }
1232}
1233
1234pub trait VertexReadTrait {
1236 #[doc(hidden)]
1237 fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]);
1238
1239 #[inline(always)]
1242 fn transform<F>(&self, func: &mut F) -> ArrayVec<u8, 256>
1243 where
1244 F: FnMut(VertexViewMut),
1245 {
1246 let (data, layout) = self.data_layout_ref();
1247 let mut transformed = ArrayVec::new();
1248 transformed
1249 .try_extend_from_slice(data)
1250 .expect("Vertex size cannot be larger than 256 bytes!");
1251 func(VertexViewMut {
1252 vertex_data: &mut transformed,
1253 sparse_layout: layout,
1254 });
1255 transformed
1256 }
1257
1258 #[inline(always)]
1260 fn read_2_f32(&self, usage: VertexAttributeUsage) -> Result<Vector2<f32>, VertexFetchError> {
1261 let (data, layout) = self.data_layout_ref();
1262 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1263 let x = LittleEndian::read_f32(&data[(attribute.offset as usize)..]);
1264 let y = LittleEndian::read_f32(&data[(attribute.offset as usize + 4)..]);
1265 Ok(Vector2::new(x, y))
1266 } else {
1267 Err(VertexFetchError::NoSuchAttribute(usage))
1268 }
1269 }
1270
1271 #[inline(always)]
1273 fn read_3_f32(&self, usage: VertexAttributeUsage) -> Result<Vector3<f32>, VertexFetchError> {
1274 let (data, layout) = self.data_layout_ref();
1275 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1276 let x = LittleEndian::read_f32(&data[(attribute.offset as usize)..]);
1277 let y = LittleEndian::read_f32(&data[(attribute.offset as usize + 4)..]);
1278 let z = LittleEndian::read_f32(&data[(attribute.offset as usize + 8)..]);
1279 Ok(Vector3::new(x, y, z))
1280 } else {
1281 Err(VertexFetchError::NoSuchAttribute(usage))
1282 }
1283 }
1284
1285 #[inline(always)]
1287 fn read_4_f32(&self, usage: VertexAttributeUsage) -> Result<Vector4<f32>, VertexFetchError> {
1288 let (data, layout) = self.data_layout_ref();
1289 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1290 let x = LittleEndian::read_f32(&data[(attribute.offset as usize)..]);
1291 let y = LittleEndian::read_f32(&data[(attribute.offset as usize + 4)..]);
1292 let z = LittleEndian::read_f32(&data[(attribute.offset as usize + 8)..]);
1293 let w = LittleEndian::read_f32(&data[(attribute.offset as usize + 12)..]);
1294 Ok(Vector4::new(x, y, z, w))
1295 } else {
1296 Err(VertexFetchError::NoSuchAttribute(usage))
1297 }
1298 }
1299
1300 #[inline(always)]
1302 fn read_4_u8(&self, usage: VertexAttributeUsage) -> Result<Vector4<u8>, VertexFetchError> {
1303 let (data, layout) = self.data_layout_ref();
1304 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1305 let offset = attribute.offset as usize;
1306 let x = data[offset];
1307 let y = data[offset + 1];
1308 let z = data[offset + 2];
1309 let w = data[offset + 3];
1310 Ok(Vector4::new(x, y, z, w))
1311 } else {
1312 Err(VertexFetchError::NoSuchAttribute(usage))
1313 }
1314 }
1315}
1316
1317impl VertexReadTrait for VertexViewRef<'_> {
1318 fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]) {
1319 (self.vertex_data, self.sparse_layout)
1320 }
1321}
1322
1323pub trait VertexWriteTrait: VertexReadTrait {
1325 #[doc(hidden)]
1326 fn data_layout_mut(&mut self) -> (&mut [u8], &[Option<VertexAttribute>]);
1327
1328 #[inline(always)]
1332 fn cast_attribute<T: Copy>(
1333 &mut self,
1334 usage: VertexAttributeUsage,
1335 ) -> Result<&mut T, VertexFetchError> {
1336 let (data, layout) = self.data_layout_mut();
1337 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1338 let expected_size = (attribute.size * attribute.data_type.size()) as usize;
1339 let actual_size = std::mem::size_of::<T>();
1340 if expected_size == std::mem::size_of::<T>() {
1341 Ok(unsafe { &mut *(data.as_mut_ptr().add(attribute.offset as usize) as *mut T) })
1342 } else {
1343 Err(VertexFetchError::SizeMismatch {
1344 expected: expected_size as u8,
1345 actual: actual_size as u8,
1346 })
1347 }
1348 } else {
1349 Err(VertexFetchError::NoSuchAttribute(usage))
1350 }
1351 }
1352
1353 fn write_2_f32(
1355 &mut self,
1356 usage: VertexAttributeUsage,
1357 value: Vector2<f32>,
1358 ) -> Result<(), VertexFetchError>;
1359
1360 fn write_3_f32(
1362 &mut self,
1363 usage: VertexAttributeUsage,
1364 value: Vector3<f32>,
1365 ) -> Result<(), VertexFetchError>;
1366
1367 fn write_4_f32(
1369 &mut self,
1370 usage: VertexAttributeUsage,
1371 value: Vector4<f32>,
1372 ) -> Result<(), VertexFetchError>;
1373
1374 fn write_4_u8(
1376 &mut self,
1377 usage: VertexAttributeUsage,
1378 value: Vector4<u8>,
1379 ) -> Result<(), VertexFetchError>;
1380}
1381
1382impl VertexReadTrait for VertexViewMut<'_> {
1383 fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]) {
1384 (self.vertex_data, self.sparse_layout)
1385 }
1386}
1387
1388impl VertexWriteTrait for VertexViewMut<'_> {
1389 #[inline(always)]
1390 fn data_layout_mut(&mut self) -> (&mut [u8], &[Option<VertexAttribute>]) {
1391 (self.vertex_data, self.sparse_layout)
1392 }
1393
1394 #[inline(always)]
1395 fn write_2_f32(
1396 &mut self,
1397 usage: VertexAttributeUsage,
1398 value: Vector2<f32>,
1399 ) -> Result<(), VertexFetchError> {
1400 let (data, layout) = self.data_layout_mut();
1401 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1402 LittleEndian::write_f32(&mut data[(attribute.offset as usize)..], value.x);
1403 LittleEndian::write_f32(&mut data[(attribute.offset as usize + 4)..], value.y);
1404 Ok(())
1405 } else {
1406 Err(VertexFetchError::NoSuchAttribute(usage))
1407 }
1408 }
1409
1410 #[inline(always)]
1411 fn write_3_f32(
1412 &mut self,
1413 usage: VertexAttributeUsage,
1414 value: Vector3<f32>,
1415 ) -> Result<(), VertexFetchError> {
1416 let (data, layout) = self.data_layout_mut();
1417 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1418 LittleEndian::write_f32(&mut data[(attribute.offset as usize)..], value.x);
1419 LittleEndian::write_f32(&mut data[(attribute.offset as usize + 4)..], value.y);
1420 LittleEndian::write_f32(&mut data[(attribute.offset as usize + 8)..], value.z);
1421 Ok(())
1422 } else {
1423 Err(VertexFetchError::NoSuchAttribute(usage))
1424 }
1425 }
1426
1427 #[inline(always)]
1428 fn write_4_f32(
1429 &mut self,
1430 usage: VertexAttributeUsage,
1431 value: Vector4<f32>,
1432 ) -> Result<(), VertexFetchError> {
1433 let (data, layout) = self.data_layout_mut();
1434 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1435 LittleEndian::write_f32(&mut data[(attribute.offset as usize)..], value.x);
1436 LittleEndian::write_f32(&mut data[(attribute.offset as usize + 4)..], value.y);
1437 LittleEndian::write_f32(&mut data[(attribute.offset as usize + 8)..], value.z);
1438 LittleEndian::write_f32(&mut data[(attribute.offset as usize + 12)..], value.w);
1439 Ok(())
1440 } else {
1441 Err(VertexFetchError::NoSuchAttribute(usage))
1442 }
1443 }
1444
1445 #[inline(always)]
1446 fn write_4_u8(
1447 &mut self,
1448 usage: VertexAttributeUsage,
1449 value: Vector4<u8>,
1450 ) -> Result<(), VertexFetchError> {
1451 let (data, layout) = self.data_layout_mut();
1452 if let Some(attribute) = layout.get(usage as usize).unwrap() {
1453 data[attribute.offset as usize] = value.x;
1454 data[(attribute.offset + 1) as usize] = value.y;
1455 data[(attribute.offset + 2) as usize] = value.z;
1456 data[(attribute.offset + 3) as usize] = value.w;
1457 Ok(())
1458 } else {
1459 Err(VertexFetchError::NoSuchAttribute(usage))
1460 }
1461 }
1462}
1463
1464#[derive(Reflect, Visit, Default, Clone, Debug)]
1466pub struct TriangleBuffer {
1467 triangles: Vec<TriangleDefinition>,
1468 modifications_counter: u64,
1469}
1470
1471fn calculate_triangle_buffer_hash(triangles: &[TriangleDefinition]) -> u64 {
1472 let mut hasher = FxHasher::default();
1473 triangles.hash(&mut hasher);
1474 hasher.finish()
1475}
1476
1477impl TriangleBuffer {
1478 pub fn new(triangles: Vec<TriangleDefinition>) -> Self {
1480 Self {
1481 triangles,
1482 modifications_counter: 0,
1483 }
1484 }
1485
1486 pub fn iter(&self) -> impl Iterator<Item = &TriangleDefinition> {
1488 self.triangles.iter()
1489 }
1490
1491 pub fn triangles_ref(&self) -> &[TriangleDefinition] {
1493 &self.triangles
1494 }
1495
1496 pub fn set_triangles(&mut self, triangles: Vec<TriangleDefinition>) {
1498 self.triangles = triangles;
1499 self.modifications_counter += 1;
1500 }
1501
1502 pub fn len(&self) -> usize {
1504 self.triangles.len()
1505 }
1506
1507 pub fn is_empty(&self) -> bool {
1509 self.triangles.is_empty()
1510 }
1511
1512 pub fn modifications_count(&self) -> u64 {
1514 self.modifications_counter
1515 }
1516
1517 pub fn content_hash(&self) -> u64 {
1519 calculate_triangle_buffer_hash(&self.triangles)
1520 }
1521
1522 pub fn modify(&mut self) -> TriangleBufferRefMut<'_> {
1524 TriangleBufferRefMut {
1525 triangle_buffer: self,
1526 }
1527 }
1528}
1529
1530impl Index<usize> for TriangleBuffer {
1531 type Output = TriangleDefinition;
1532
1533 fn index(&self, index: usize) -> &Self::Output {
1534 &self.triangles[index]
1535 }
1536}
1537
1538pub struct TriangleBufferRefMut<'a> {
1540 triangle_buffer: &'a mut TriangleBuffer,
1541}
1542
1543impl Deref for TriangleBufferRefMut<'_> {
1544 type Target = TriangleBuffer;
1545
1546 fn deref(&self) -> &Self::Target {
1547 self.triangle_buffer
1548 }
1549}
1550
1551impl DerefMut for TriangleBufferRefMut<'_> {
1552 fn deref_mut(&mut self) -> &mut Self::Target {
1553 self.triangle_buffer
1554 }
1555}
1556
1557impl Drop for TriangleBufferRefMut<'_> {
1558 fn drop(&mut self) {
1559 self.triangle_buffer.modifications_counter += 1;
1560 }
1561}
1562
1563impl TriangleBufferRefMut<'_> {
1564 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TriangleDefinition> {
1566 self.triangles.iter_mut()
1567 }
1568
1569 pub fn push(&mut self, triangle: TriangleDefinition) {
1571 self.triangles.push(triangle)
1572 }
1573
1574 pub fn push_triangles_iter_with_offset(
1577 &mut self,
1578 offset: u32,
1579 triangles: impl Iterator<Item = TriangleDefinition>,
1580 ) {
1581 self.triangles.extend(triangles.map(|t| t.add(offset)))
1582 }
1583
1584 pub fn push_triangles(&mut self, triangles: &[TriangleDefinition]) {
1586 self.triangles.extend_from_slice(triangles)
1587 }
1588
1589 pub fn push_triangles_iter(&mut self, triangles: impl Iterator<Item = TriangleDefinition>) {
1591 self.triangles.extend(triangles)
1592 }
1593
1594 pub fn push_triangles_with_offset(&mut self, offset: u32, triangles: &[TriangleDefinition]) {
1597 self.triangles
1598 .extend(triangles.iter().map(|t| t.add(offset)))
1599 }
1600
1601 pub fn clear(&mut self) {
1603 self.triangles.clear();
1604 }
1605}
1606
1607impl Index<usize> for TriangleBufferRefMut<'_> {
1608 type Output = TriangleDefinition;
1609
1610 fn index(&self, index: usize) -> &Self::Output {
1611 &self.triangle_buffer.triangles[index]
1612 }
1613}
1614
1615impl IndexMut<usize> for TriangleBufferRefMut<'_> {
1616 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1617 &mut self.triangle_buffer.triangles[index]
1618 }
1619}
1620
1621pub struct AttributeViewRef<'a, T> {
1623 ptr: *const u8,
1624 stride: usize,
1625 count: usize,
1626 phantom: PhantomData<&'a T>,
1627}
1628
1629impl<'a, T> AttributeViewRef<'a, T> {
1630 pub fn get(&'a self, i: usize) -> Option<&'a T> {
1632 if i < self.count {
1633 Some(unsafe { &*((self.ptr.add(i * self.stride)) as *const T) })
1634 } else {
1635 None
1636 }
1637 }
1638}
1639
1640pub struct AttributeViewRefMut<'a, T> {
1642 ptr: *mut u8,
1643 stride: usize,
1644 count: usize,
1645 phantom: PhantomData<&'a T>,
1646}
1647
1648impl<'a, T> AttributeViewRefMut<'a, T> {
1649 pub fn get(&'a mut self, i: usize) -> Option<&'a mut T> {
1651 if i < self.count {
1652 Some(unsafe { &mut *((self.ptr.add(i * self.stride)) as *mut T) })
1653 } else {
1654 None
1655 }
1656 }
1657}
1658
1659#[cfg(test)]
1660mod test {
1661 use crate::scene::mesh::buffer::VertexTrait;
1662 use crate::{
1663 core::algebra::{Vector2, Vector3, Vector4},
1664 scene::mesh::buffer::{
1665 VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexBuffer,
1666 VertexReadTrait,
1667 },
1668 };
1669
1670 #[derive(Clone, Copy, PartialEq, Debug)]
1671 #[repr(C)]
1672 struct Vertex {
1673 position: Vector3<f32>,
1674 tex_coord: Vector2<f32>,
1675 second_tex_coord: Vector2<f32>,
1676 normal: Vector3<f32>,
1677 tangent: Vector4<f32>,
1678 bone_weights: Vector4<f32>,
1679 bone_indices: Vector4<u8>,
1680 }
1681
1682 impl VertexTrait for Vertex {
1683 fn layout() -> &'static [VertexAttributeDescriptor] {
1684 static LAYOUT: [VertexAttributeDescriptor; 7] = [
1685 VertexAttributeDescriptor {
1686 usage: VertexAttributeUsage::Position,
1687 data_type: VertexAttributeDataType::F32,
1688 size: 3,
1689 divisor: 0,
1690 shader_location: 0,
1691 normalized: false,
1692 },
1693 VertexAttributeDescriptor {
1694 usage: VertexAttributeUsage::TexCoord0,
1695 data_type: VertexAttributeDataType::F32,
1696 size: 2,
1697 divisor: 0,
1698 shader_location: 1,
1699 normalized: false,
1700 },
1701 VertexAttributeDescriptor {
1702 usage: VertexAttributeUsage::TexCoord1,
1703 data_type: VertexAttributeDataType::F32,
1704 size: 2,
1705 divisor: 0,
1706 shader_location: 2,
1707 normalized: false,
1708 },
1709 VertexAttributeDescriptor {
1710 usage: VertexAttributeUsage::Normal,
1711 data_type: VertexAttributeDataType::F32,
1712 size: 3,
1713 divisor: 0,
1714 shader_location: 3,
1715 normalized: false,
1716 },
1717 VertexAttributeDescriptor {
1718 usage: VertexAttributeUsage::Tangent,
1719 data_type: VertexAttributeDataType::F32,
1720 size: 4,
1721 divisor: 0,
1722 shader_location: 4,
1723 normalized: false,
1724 },
1725 VertexAttributeDescriptor {
1726 usage: VertexAttributeUsage::BoneWeight,
1727 data_type: VertexAttributeDataType::F32,
1728 size: 4,
1729 divisor: 0,
1730 shader_location: 5,
1731 normalized: false,
1732 },
1733 VertexAttributeDescriptor {
1734 usage: VertexAttributeUsage::BoneIndices,
1735 data_type: VertexAttributeDataType::U8,
1736 size: 4,
1737 divisor: 0,
1738 shader_location: 6,
1739 normalized: false,
1740 },
1741 ];
1742
1743 &LAYOUT
1744 }
1745 }
1746
1747 const VERTICES: [Vertex; 3] = [
1748 Vertex {
1749 position: Vector3::new(1.0, 2.0, 3.0),
1750 tex_coord: Vector2::new(0.0, 1.0),
1751 second_tex_coord: Vector2::new(1.0, 0.0),
1752 normal: Vector3::new(0.0, 1.0, 0.0),
1753 tangent: Vector4::new(1.0, 0.0, 0.0, 1.0),
1754 bone_weights: Vector4::new(0.25, 0.25, 0.25, 0.25),
1755 bone_indices: Vector4::new(1, 2, 3, 4),
1756 },
1757 Vertex {
1758 position: Vector3::new(3.0, 2.0, 1.0),
1759 tex_coord: Vector2::new(1.0, 0.0),
1760 second_tex_coord: Vector2::new(1.0, 0.0),
1761 normal: Vector3::new(0.0, 1.0, 0.0),
1762 tangent: Vector4::new(1.0, 0.0, 0.0, 1.0),
1763 bone_weights: Vector4::new(0.25, 0.25, 0.25, 0.25),
1764 bone_indices: Vector4::new(1, 2, 3, 4),
1765 },
1766 Vertex {
1767 position: Vector3::new(1.0, 1.0, 1.0),
1768 tex_coord: Vector2::new(1.0, 1.0),
1769 second_tex_coord: Vector2::new(1.0, 0.0),
1770 normal: Vector3::new(0.0, 1.0, 0.0),
1771 tangent: Vector4::new(1.0, 0.0, 0.0, 1.0),
1772 bone_weights: Vector4::new(0.25, 0.25, 0.25, 0.25),
1773 bone_indices: Vector4::new(1, 2, 3, 4),
1774 },
1775 ];
1776
1777 fn test_view_original_equal<T: VertexReadTrait>(view: T, original: &Vertex) {
1778 assert_eq!(
1779 view.read_3_f32(VertexAttributeUsage::Position).unwrap(),
1780 original.position
1781 );
1782 assert_eq!(
1783 view.read_2_f32(VertexAttributeUsage::TexCoord0).unwrap(),
1784 original.tex_coord
1785 );
1786 assert_eq!(
1787 view.read_2_f32(VertexAttributeUsage::TexCoord1).unwrap(),
1788 original.second_tex_coord
1789 );
1790 assert_eq!(
1791 view.read_3_f32(VertexAttributeUsage::Normal).unwrap(),
1792 original.normal
1793 );
1794 assert_eq!(
1795 view.read_4_f32(VertexAttributeUsage::Tangent).unwrap(),
1796 original.tangent
1797 );
1798 assert_eq!(
1799 view.read_4_f32(VertexAttributeUsage::BoneWeight).unwrap(),
1800 original.bone_weights
1801 );
1802 assert_eq!(
1803 view.read_4_u8(VertexAttributeUsage::BoneIndices).unwrap(),
1804 original.bone_indices
1805 );
1806 }
1807
1808 fn create_test_buffer() -> VertexBuffer {
1809 VertexBuffer::new(VERTICES.len(), VERTICES.to_vec()).unwrap()
1810 }
1811
1812 #[test]
1813 fn test_empty() {
1814 VertexBuffer::new::<Vertex>(0, vec![]).unwrap();
1815 }
1816
1817 #[test]
1818 fn test_iter() {
1819 let buffer = create_test_buffer();
1820
1821 for (view, original) in buffer.iter().zip(VERTICES.iter()) {
1822 test_view_original_equal(view, original);
1823 }
1824 }
1825
1826 #[test]
1827 fn test_iter_mut() {
1828 let mut buffer = create_test_buffer();
1829
1830 for (view, original) in buffer.modify().iter_mut().zip(VERTICES.iter()) {
1831 test_view_original_equal(view, original);
1832 }
1833 }
1834
1835 #[test]
1836 fn test_vertex_duplication() {
1837 let mut buffer = create_test_buffer();
1838
1839 buffer.modify().duplicate(0);
1840
1841 assert_eq!(buffer.vertex_count(), 4);
1842 assert_eq!(buffer.get(0).unwrap(), buffer.get(3).unwrap())
1843 }
1844
1845 #[test]
1846 fn test_pop_vertex() {
1847 let mut buffer = create_test_buffer();
1848
1849 let vertex = buffer.modify().pop_vertex::<Vertex>().unwrap();
1850
1851 assert_eq!(buffer.vertex_count(), 2);
1852 assert_eq!(vertex, VERTICES[2]);
1853 }
1854
1855 #[test]
1856 fn test_remove_last_vertex() {
1857 let mut buffer = create_test_buffer();
1858
1859 buffer.modify().remove_last_vertex();
1860
1861 assert_eq!(buffer.vertex_count(), 2);
1862 }
1863
1864 #[test]
1865 fn test_attribute_view() {
1866 let buffer = create_test_buffer();
1867
1868 let position_view = buffer
1869 .attribute_view::<Vector3<f32>>(VertexAttributeUsage::Position)
1870 .unwrap();
1871
1872 assert_eq!(position_view.get(0), Some(&Vector3::new(1.0, 2.0, 3.0)));
1873 assert_eq!(position_view.get(1), Some(&Vector3::new(3.0, 2.0, 1.0)));
1874 assert_eq!(position_view.get(2), Some(&Vector3::new(1.0, 1.0, 1.0)));
1875
1876 let uv_view = buffer
1877 .attribute_view::<Vector2<f32>>(VertexAttributeUsage::TexCoord0)
1878 .unwrap();
1879
1880 assert_eq!(uv_view.get(0), Some(&Vector2::new(0.0, 1.0)));
1881 assert_eq!(uv_view.get(1), Some(&Vector2::new(1.0, 0.0)));
1882 assert_eq!(uv_view.get(2), Some(&Vector2::new(1.0, 1.0)));
1883 }
1884
1885 #[test]
1886 fn test_add_attribute() {
1887 let mut buffer = create_test_buffer();
1888
1889 let fill = Vector2::new(0.25, 0.75);
1890 let test_index = 1;
1891
1892 buffer
1893 .modify()
1894 .add_attribute(
1895 VertexAttributeDescriptor {
1896 usage: VertexAttributeUsage::TexCoord2,
1897 data_type: VertexAttributeDataType::F32,
1898 size: 2,
1899 divisor: 0,
1900 shader_location: 7,
1901 normalized: false,
1902 },
1903 fill,
1904 )
1905 .unwrap();
1906
1907 #[derive(Clone, Copy, PartialEq, Debug)]
1908 #[repr(C)]
1909 struct ExtendedVertex {
1910 position: Vector3<f32>,
1911 tex_coord: Vector2<f32>,
1912 second_tex_coord: Vector2<f32>,
1913 normal: Vector3<f32>,
1914 tangent: Vector4<f32>,
1915 bone_weights: Vector4<f32>,
1916 bone_indices: Vector4<u8>,
1917 third_tex_coord: Vector2<f32>, }
1919
1920 let new_1 = ExtendedVertex {
1921 position: VERTICES[test_index].position,
1922 tex_coord: VERTICES[test_index].tex_coord,
1923 second_tex_coord: VERTICES[test_index].second_tex_coord,
1924 normal: VERTICES[test_index].normal,
1925 tangent: VERTICES[test_index].tangent,
1926 bone_weights: VERTICES[test_index].bone_weights,
1927 bone_indices: VERTICES[test_index].bone_indices,
1928 third_tex_coord: fill,
1929 };
1930
1931 assert_eq!(
1932 buffer.vertex_size,
1933 std::mem::size_of::<ExtendedVertex>() as u8
1934 );
1935 let view = buffer.get(test_index).unwrap();
1936 assert_eq!(
1937 view.read_3_f32(VertexAttributeUsage::Position).unwrap(),
1938 new_1.position
1939 );
1940 assert_eq!(
1941 view.read_2_f32(VertexAttributeUsage::TexCoord0).unwrap(),
1942 new_1.tex_coord
1943 );
1944 assert_eq!(
1945 view.read_2_f32(VertexAttributeUsage::TexCoord1).unwrap(),
1946 new_1.second_tex_coord
1947 );
1948 assert_eq!(
1949 view.read_2_f32(VertexAttributeUsage::TexCoord2).unwrap(),
1950 new_1.third_tex_coord
1951 );
1952 assert_eq!(
1953 view.read_3_f32(VertexAttributeUsage::Normal).unwrap(),
1954 new_1.normal
1955 );
1956 assert_eq!(
1957 view.read_4_f32(VertexAttributeUsage::Tangent).unwrap(),
1958 new_1.tangent
1959 );
1960 assert_eq!(
1961 view.read_4_f32(VertexAttributeUsage::BoneWeight).unwrap(),
1962 new_1.bone_weights
1963 );
1964 assert_eq!(
1965 view.read_4_u8(VertexAttributeUsage::BoneIndices).unwrap(),
1966 new_1.bone_indices
1967 );
1968 }
1969}