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