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