Skip to main content

fyrox_impl/scene/mesh/
buffer.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Vertex buffer with dynamic layout. See [`VertexBuffer`] docs for more info and usage examples.
22
23use 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
49/// A common trait for all vertex types. **IMPORTANT:** Implementors **must** use `#[repr(C)]` attribute, otherwise the compiler
50/// is free to reorder fields and you might get weird results, because definition order will be different from memory order! See
51/// examples in [`VertexBuffer`] docs.
52pub trait VertexTrait: Copy + 'static {
53    /// Returns memory layout of the vertex. It basically tells a GPU how to interpret every byte range
54    /// of your vertex type; which kind of information it holds.
55    fn layout() -> &'static [VertexAttributeDescriptor];
56}
57
58/// Data type for a vertex attribute component.
59#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
60#[repr(u8)]
61#[derive(Default)]
62pub enum VertexAttributeDataType {
63    /// 32-bit floating-point.
64    #[default]
65    F32,
66    /// 32-bit unsigned integer.
67    U32,
68    /// 16-bit unsigned integer.
69    U16,
70    /// 8-bit unsigned integer.
71    U8,
72}
73
74impl VertexAttributeDataType {
75    /// Returns size of data in bytes.
76    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/// An usage for vertex attribute. It is a fixed set, but there are plenty
86/// room for any custom data - it may be fit into `TexCoordN` attributes.
87#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
88#[repr(u32)]
89#[derive(Default)]
90pub enum VertexAttributeUsage {
91    /// Vertex position. Usually `Vector2<f32>` or `Vector3<f32>`.
92    #[default]
93    Position = 0,
94    /// Vertex normal. Usually `Vector3<f32>`, more rare `Vector3<u16>` (F16).
95    Normal = 1,
96    /// Vertex tangent. Usually `Vector3<f32>`.
97    Tangent = 2,
98    /// First texture coordinates. Usually `Vector2<f32>`.
99    /// It may be used for everything else, not only for texture coordinates.
100    TexCoord0 = 3,
101    /// Second texture coordinates.
102    TexCoord1 = 4,
103    /// Third texture coordinates.
104    TexCoord2 = 5,
105    /// Fourth texture coordinates.
106    TexCoord3 = 6,
107    /// Fifth texture coordinates.
108    TexCoord4 = 7,
109    /// Sixth texture coordinates.
110    TexCoord5 = 8,
111    /// Seventh texture coordinates.
112    TexCoord6 = 9,
113    /// Eighth texture coordinates.
114    TexCoord7 = 10,
115    /// Bone weights. Usually `Vector4<f32>`.
116    BoneWeight = 11,
117    /// Bone indices. Usually `Vector4<u8>`.
118    BoneIndices = 12,
119    /// Color. Usually `Vector4<u8>`.
120    Color = 13,
121    /// First custom attribute with arbitrary, context-dependent meaning.
122    Custom0 = 14,
123    /// Second custom attribute with arbitrary, context-dependent meaning.
124    Custom1 = 15,
125    /// Third custom attribute with arbitrary, context-dependent meaning.
126    Custom2 = 16,
127    /// Fourth custom attribute with arbitrary, context-dependent meaning.
128    Custom3 = 17,
129    /// Fifth custom attribute with arbitrary, context-dependent meaning.
130    Custom4 = 18,
131    /// Sixth custom attribute with arbitrary, context-dependent meaning.
132    Custom5 = 19,
133    /// Seventh custom attribute with arbitrary, context-dependent meaning.
134    Custom6 = 20,
135    /// Eigth custom attribute with arbitrary, context-dependent meaning.
136    Custom7 = 21,
137    /// Maximum amount of attribute kinds.
138    Count,
139}
140
141/// Input vertex attribute descriptor used to construct layouts and feed vertex buffer.
142#[derive(Debug, Hash)]
143pub struct VertexAttributeDescriptor {
144    /// Claimed usage of the attribute. It could be Position, Normal, etc.
145    pub usage: VertexAttributeUsage,
146    /// Data type of every component of the attribute. It could be F32, U32, U16, etc.
147    pub data_type: VertexAttributeDataType,
148    /// Size of attribute expressed in components. For example, for `Position` it could
149    /// be 3 - which means there are 3 components in attribute of `data_type`.
150    pub size: u8,
151    /// Sets a "fetch rate" for vertex shader at which it will read vertex attribute:
152    ///  0 - per vertex (default)
153    ///  1 - per instance
154    ///  2 - per 2 instances and so on.
155    pub divisor: u8,
156    /// Defines location of the attribute in a shader (`layout(location = x) attrib;`)
157    pub shader_location: u8,
158    /// Whether the attribute values should be normalized into `0.0..1.0` range or not.
159    /// If this field is set to `false`, then the numbers will appear "as-is" when fetching
160    /// them in a shader. On the other hand, if it is `true`, then any numeric value will be
161    /// normalized by applying `normalized = num / T::max()` equation. This way all numbers will
162    /// always stay in `0.0..1.0` range.
163    ///
164    /// For example, normalization could be useful for RGB colors that expressed as three bytes (u8).
165    /// In this case normalization will turn the color into `0.0..1.0` range.  
166    pub normalized: bool,
167}
168
169/// Vertex attribute is a simple "bridge" between raw data and its interpretation. In
170/// other words it defines how to treat raw data in vertex shader.
171#[derive(Reflect, Visit, Copy, Clone, Default, Debug, Hash)]
172pub struct VertexAttribute {
173    /// Claimed usage of the attribute. It could be Position, Normal, etc.
174    pub usage: VertexAttributeUsage,
175    /// Data type of every component of the attribute. It could be F32, U32, U16, etc.
176    pub data_type: VertexAttributeDataType,
177    /// Size of attribute expressed in components. For example, for `Position` it could
178    /// be 3 - which means there are 3 components in attribute of `data_type`.
179    pub size: u8,
180    /// Sets a "fetch rate" for vertex shader at which it will read vertex attribute:
181    ///  0 - per vertex (default)
182    ///  1 - per instance
183    ///  2 - per 2 instances and so on.
184    pub divisor: u8,
185    /// Offset in bytes from beginning of the vertex.
186    pub offset: u8,
187    /// Defines location of the attribute in a shader (`layout(location = x) attrib;`)
188    pub shader_location: u8,
189    /// Whether the attribute values should be normalized into `0.0..1.0` range or not.
190    /// If this field is set to `false`, then the numbers will appear "as-is" when fetching
191    /// them in a shader. On the other hand, if it is `true`, then any numeric value will be
192    /// normalized by applying `normalized = num / T::max()` equation. This way all numbers will
193    /// always stay in `0.0..1.0` range.
194    ///
195    /// For example, normalization could be useful for RGB colors that expressed as three bytes (u8).
196    /// In this case normalization will turn the color into `0.0..1.0` range.  
197    #[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/// Bytes storage of a vertex buffer.
219#[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    /// Creates new empty bytes storage with the given capacity.
253    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    /// Creates new bytes storage from the given data buffer.
261    pub fn new<T>(data: Vec<T>) -> Self {
262        // Prevent destructor to be called on `data`, this is needed because we're taking its
263        // data storage and treat it as a simple bytes block.
264        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            // Preserve initial memory layout, to ensure that the memory block will be deallocated
276            // with initial memory layout.
277            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            // Realloc backing storage manually if the alignment is anything else than 1.
284            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        // Dealloc manually with initial memory layout.
317        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/// Vertex buffer with dynamic layout. It is used to store multiple vertices of a single type, that implements [`VertexTrait`].
332/// Different vertex types used to for efficient memory usage. For example, you could have a simple vertex with only position
333/// expressed as Vector3 and it will be enough for simple cases, when only position is required. However, if you want to draw
334/// a mesh with skeletal animation, that also supports texturing, lighting, you need to provide a lot more data (bone indices,
335/// bone weights, normals, tangents, texture coordinates).
336///
337/// ## Examples
338///
339/// ```rust
340/// # use fyrox_impl::{
341/// #     core::algebra::Vector3,
342/// #     scene::mesh::buffer::{
343/// #         VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexBuffer,
344/// #         VertexTrait,
345/// #     },
346/// # };
347/// #
348/// #[derive(Copy, Clone)]
349/// #[repr(C)]
350/// struct MyVertex {
351///     position: Vector3<f32>,
352/// }
353///
354/// impl VertexTrait for MyVertex {
355///     fn layout() -> &'static [VertexAttributeDescriptor] {
356///         &[VertexAttributeDescriptor {
357///             usage: VertexAttributeUsage::Position,
358///             data_type: VertexAttributeDataType::F32,
359///             size: 3,
360///             divisor: 0,
361///             shader_location: 0,
362///             normalized: false
363///         }]
364///     }
365/// }
366///
367/// fn create_triangle_vertex_buffer() -> VertexBuffer {
368///     VertexBuffer::new(
369///         3,
370///         vec![
371///             MyVertex {
372///                 position: Vector3::new(0.0, 0.0, 0.0),
373///             },
374///             MyVertex {
375///                 position: Vector3::new(0.0, 1.0, 0.0),
376///             },
377///             MyVertex {
378///                 position: Vector3::new(1.0, 1.0, 0.0),
379///             },
380///         ],
381///     )
382///     .unwrap()
383/// }  
384/// ```
385///
386/// This example creates a simple vertex buffer that contains a single triangle with custom vertex format. The most important
387/// part here is [`VertexTrait::layout`] implementation - it describes each "attribute" of your vertex, if your layout does not
388/// match the actual content of the vertex (in terms of size in bytes), then vertex buffer cannot be created and [`VertexBuffer::new`]
389/// will return [`None`].
390///
391/// The second, but not least important is `#[repr(C)]` attribute - it is mandatory for every vertex type, it forbids fields
392/// reordering of you vertex structure and guarantees that they will have the same layout in memory as their declaration order.
393///
394/// ## Limitations
395///
396/// Vertex size cannot be more than 256 bytes, this limitation shouldn't be a problem because almost every GPU supports up to
397/// 16 vertex attributes with 16 bytes of size each, which gives exactly 256 bytes.
398#[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
423/// See VertexBuffer::modify for more info.
424pub 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    /// Tries to append a vertex to the buffer.
450    ///
451    /// # Safety and validation
452    ///
453    /// This method accepts any type that has appropriate size, the size must be equal
454    /// with the size defined by layout. The Copy trait bound is required to ensure that
455    /// the type does not have any custom destructors.
456    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    /// Tries to append a slice of vertices to the buffer.
475    ///
476    /// # Safety and validation
477    ///
478    /// This method accepts any type that has appropriate size, the size must be equal
479    /// with the size defined by layout. The Copy trait bound is required to ensure that
480    /// the type does not have any custom destructors.
481    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    /// Tries to append a raw vertex data to the vertex buffer. This method will fail if the `data`
500    /// size does not match the vertex size of the buffer.
501    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    /// Tries to append the vertices that the given iterator produces.
515    ///
516    /// # Safety and validation
517    ///
518    /// This method accepts any type that has appropriate size, the size must be equal
519    /// with the size defined by layout. The Copy trait bound is required to ensure that
520    /// the type does not have any custom destructors.
521    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    /// Tries to append a slice of vertices to the buffer. Each vertex will be transformed using
545    /// `transformer` callback.
546    ///
547    /// # Safety and validation
548    ///
549    /// This method accepts any type that has appropriate size, the size must be equal
550    /// with the size defined by layout. The Copy trait bound is required to ensure that
551    /// the type does not have any custom destructors.
552    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    /// Removes last vertex from the buffer.
580    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    /// Copies data of last vertex from the buffer to an instance of variable of a type.
587    ///
588    /// # Safety and validation
589    ///
590    /// This method accepts any type that has appropriate size, the size must be equal
591    /// with the size defined by layout. The Copy trait bound is required to ensure that
592    /// the type does not have any custom destructors.
593    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    /// Tries to cast internal data buffer to a slice of given type. It may fail if
624    /// size of type is not equal with claimed size (which is set by the layout).
625    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    /// Creates iterator that emits read/write accessors for vertices.
645    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    /// Returns a read/write accessor of n-th vertex.
661    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    /// Duplicates n-th vertex and puts it at the back of the buffer.
675    pub fn duplicate(&mut self, n: usize) {
676        // Vertex cannot be larger than 256 bytes, so having temporary array of
677        // such size is ok.
678        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    /// Adds new attribute at the end of layout, reorganizes internal data storage to be
689    /// able to contain new attribute. Default value of the new attribute in the buffer
690    /// becomes `fill_value`. Graphically this could be represented like so:
691    ///
692    /// Add secondary texture coordinates:
693    ///  Before: P1_N1_TC1_P2_N2_TC2...
694    ///  After: P1_N1_TC1_TC2(fill_value)_P2_N2_TC2_TC2(fill_value)...
695    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    /// Clears the buffer making it empty.
743    pub fn clear(&mut self) {
744        self.data.clear();
745        self.vertex_count = 0;
746    }
747}
748
749/// An error that may occur during input data and layout validation.
750#[derive(Debug)]
751pub enum ValidationError {
752    /// Attribute size must be either 1, 2, 3 or 4.
753    InvalidAttributeSize(usize),
754
755    /// Data size is not correct.
756    InvalidDataSize {
757        /// Expected data size in bytes.
758        expected: usize,
759        /// Actual data size in bytes.
760        actual: usize,
761    },
762
763    /// Trying to add vertex of incorrect size.
764    InvalidVertexSize {
765        /// Expected vertex size.
766        expected: u8,
767        /// Actual vertex size.
768        actual: u8,
769    },
770
771    /// A duplicate of a descriptor was found.
772    DuplicatedAttributeDescriptor,
773
774    /// Duplicate shader locations were found.
775    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    /// Creates new vertex buffer from provided data and with the given layout of the vertex type `T`.
802    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    /// Creates new vertex buffer from the given layout, vertex count and bytes storage.
810    pub fn new_with_layout(
811        layout: &[VertexAttributeDescriptor],
812        vertex_count: usize,
813        bytes: BytesStorage,
814    ) -> Result<Self, ValidationError> {
815        // Validate for duplicates and invalid layout.
816        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        // Validate everything as much as possible and calculate vertex size.
833        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            // Map dense to sparse layout to increase performance.
855            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    /// Creates a new empty vertex buffer with the same layout and vertex size, but with an empty
880    /// inner buffer of the specified capacity.  
881    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    /// Returns a reference to underlying data buffer slice.
894    pub fn raw_data(&self) -> &[u8] {
895        &self.data
896    }
897
898    /// Returns true if buffer does not contain any vertex, false - otherwise.
899    pub fn is_empty(&self) -> bool {
900        self.vertex_count == 0
901    }
902
903    /// Returns the total amount of times the buffer was modified.
904    pub fn modifications_count(&self) -> u64 {
905        self.modifications_counter
906    }
907
908    /// Calculates inner data hash.
909    pub fn content_hash(&self) -> u64 {
910        calculate_data_hash(&self.data.bytes)
911    }
912
913    /// Returns hash of vertex buffer layout. Cached value is guaranteed to be in actual state.
914    /// The hash could be used to check if the layout has changed.
915    pub fn layout_hash(&self) -> u64 {
916        self.layout_hash
917    }
918
919    /// Provides mutable access to content of the buffer.
920    ///
921    /// # Performance
922    ///
923    /// This method returns a special structure which has custom destructor that increases use
924    /// counter of the data once modification is over. You **must** hold this structure as long as
925    /// possible while modifying the contents of the buffer. Do **not** even try to do this:
926    ///
927    /// ```no_run
928    /// use fyrox_impl::{
929    ///     scene::mesh::buffer::{VertexBuffer, VertexWriteTrait, VertexAttributeUsage},
930    ///     core::algebra::Vector3
931    /// };
932    /// fn do_something(buffer: &mut VertexBuffer) {
933    ///     for i in 0..buffer.vertex_count() {
934    ///         buffer
935    ///             .modify() // Doing this in a loop will cause performance issues!
936    ///             .get_mut(i as usize)
937    ///             .unwrap()
938    ///             .write_3_f32(VertexAttributeUsage::Position, Vector3::<f32>::default())
939    ///             .unwrap();
940    ///     }
941    /// }
942    /// ```
943    ///
944    /// Instead, do this:
945    ///
946    /// ```no_run
947    /// use fyrox_impl::{
948    ///     scene::mesh::buffer::{VertexBuffer, VertexWriteTrait, VertexAttributeUsage},
949    ///     core::algebra::Vector3
950    /// };
951    /// fn do_something(buffer: &mut VertexBuffer) {
952    ///     let mut buffer_modifier = buffer.modify();
953    ///     for mut vertex in buffer_modifier.iter_mut() {
954    ///         vertex
955    ///             .write_3_f32(VertexAttributeUsage::Position, Vector3::<f32>::default())
956    ///             .unwrap();
957    ///     }
958    /// }
959    /// ```
960    ///
961    /// Why do we even need such complications? It is used to notify the GPU that the content has
962    /// changed and must be re-uploaded to the GPU.
963    pub fn modify(&mut self) -> VertexBufferRefMut<'_> {
964        VertexBufferRefMut {
965            vertex_buffer: self,
966        }
967    }
968
969    /// Checks if an attribute of `usage` exists.
970    pub fn has_attribute(&self, usage: VertexAttributeUsage) -> bool {
971        self.sparse_layout[usage as usize].is_some()
972    }
973
974    /// Returns vertex buffer layout.
975    pub fn layout(&self) -> &[VertexAttribute] {
976        &self.dense_layout
977    }
978
979    /// Returns vertex buffer layout.
980    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    /// Tries to cast internal data buffer to a slice of given type. It may fail if
994    /// size of type is not equal with claimed size (which is set by the layout).
995    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    /// Creates iterator that emits read accessors for vertices.
1015    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    /// Returns a read accessor of n-th vertex.
1026    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    /// Returns exact amount of vertices in the buffer.
1039    pub fn vertex_count(&self) -> u32 {
1040        self.vertex_count
1041    }
1042
1043    /// Return vertex size of the buffer.
1044    pub fn vertex_size(&self) -> u8 {
1045        self.vertex_size
1046    }
1047
1048    /// Finds free location for an attribute in the layout.
1049    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                // We have a gap, use some value from it.
1057                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    /// Tries to find an attribute with the given `usage` and if it exists, returns its "view", that
1073    /// allows you to fetch data like in ordinary array.
1074    #[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    /// Tries to find an attribute with the given `usage` and if it exists, returns its "view", that
1094    /// allows you to fetch data like in ordinary array.
1095    #[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/// Read accessor for a vertex with some layout.
1170#[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/// Read/write accessor for a vertex with some layout.
1183#[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/// An error that may occur during fetching using vertex read/write accessor.
1196#[derive(Debug)]
1197pub enum VertexFetchError {
1198    /// Trying to read/write non-existent attribute.
1199    NoSuchAttribute(VertexAttributeUsage),
1200    /// Size mistmatch.
1201    SizeMismatch {
1202        /// Expected size in bytes.
1203        expected: u8,
1204        /// Actual size in bytes.
1205        actual: u8,
1206    },
1207    /// IO error.
1208    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
1235/// A trait for read-only vertex data accessor.
1236pub trait VertexReadTrait {
1237    #[doc(hidden)]
1238    fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]);
1239
1240    /// Clones the vertex and applies the given transformer closure to it and returns a stack-allocated
1241    /// data buffer representing the transformed vertex.
1242    #[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    /// Tries to read an attribute with given usage as a pair of two f32.
1260    #[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    /// Tries to read an attribute with given usage as a pair of three f32.
1273    #[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    /// Tries to read an attribute with given usage as a pair of four f32.
1287    #[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    /// Tries to read an attribute with given usage as a pair of four u8.
1302    #[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
1324/// A trait for read/write vertex data accessor.
1325pub trait VertexWriteTrait: VertexReadTrait {
1326    #[doc(hidden)]
1327    fn data_layout_mut(&mut self) -> (&mut [u8], &[Option<VertexAttribute>]);
1328
1329    /// Tries to find an attribute of the given type and returns a mutable reference of the specified
1330    /// type. Type casting will fail if the size of the destination type `T` does not match the
1331    /// actual attribute size.
1332    #[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    /// Tries to write an attribute with given usage as a pair of two f32.
1355    fn write_2_f32(
1356        &mut self,
1357        usage: VertexAttributeUsage,
1358        value: Vector2<f32>,
1359    ) -> Result<(), VertexFetchError>;
1360
1361    /// Tries to write an attribute with given usage as a pair of three f32.
1362    fn write_3_f32(
1363        &mut self,
1364        usage: VertexAttributeUsage,
1365        value: Vector3<f32>,
1366    ) -> Result<(), VertexFetchError>;
1367
1368    /// Tries to write an attribute with given usage as a pair of four f32.
1369    fn write_4_f32(
1370        &mut self,
1371        usage: VertexAttributeUsage,
1372        value: Vector4<f32>,
1373    ) -> Result<(), VertexFetchError>;
1374
1375    /// Tries to write an attribute with given usage as a pair of four u8.
1376    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/// A buffer for data that defines connections between vertices.
1466#[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    /// Creates new triangle buffer with given set of triangles.
1491    pub fn new(triangles: Vec<TriangleDefinition>) -> Self {
1492        Self {
1493            triangles,
1494            modifications_counter: 0,
1495        }
1496    }
1497
1498    /// Creates new ref iterator.
1499    pub fn iter(&self) -> impl Iterator<Item = &TriangleDefinition> {
1500        self.triangles.iter()
1501    }
1502
1503    /// Returns a ref to inner data with triangles.
1504    pub fn triangles_ref(&self) -> &[TriangleDefinition] {
1505        &self.triangles
1506    }
1507
1508    /// Sets a new set of triangles.
1509    pub fn set_triangles(&mut self, triangles: Vec<TriangleDefinition>) {
1510        self.triangles = triangles;
1511        self.modifications_counter += 1;
1512    }
1513
1514    /// Returns amount of triangles in the buffer.
1515    pub fn len(&self) -> usize {
1516        self.triangles.len()
1517    }
1518
1519    /// Returns true if the buffer is empty, false - otherwise.
1520    pub fn is_empty(&self) -> bool {
1521        self.triangles.is_empty()
1522    }
1523
1524    /// Returns the total amount of times the buffer was modified.
1525    pub fn modifications_count(&self) -> u64 {
1526        self.modifications_counter
1527    }
1528
1529    /// Calculates inner data hash.
1530    pub fn content_hash(&self) -> u64 {
1531        calculate_triangle_buffer_hash(&self.triangles)
1532    }
1533
1534    /// See VertexBuffer::modify for more info.
1535    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
1550/// See VertexBuffer::modify for more info.
1551pub 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    /// Returns mutable iterator.
1577    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TriangleDefinition> {
1578        self.triangles.iter_mut()
1579    }
1580
1581    /// Adds new triangle in the buffer.
1582    pub fn push(&mut self, triangle: TriangleDefinition) {
1583        self.triangles.push(triangle)
1584    }
1585
1586    /// Adds triangles from the given iterator to the current buffer. Offsets each triangle by the
1587    /// given `offset` value.
1588    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    /// Adds triangles from the given slice to the current buffer.
1597    pub fn push_triangles(&mut self, triangles: &[TriangleDefinition]) {
1598        self.triangles.extend_from_slice(triangles)
1599    }
1600
1601    /// Adds triangles from the given iterator to the current buffer.
1602    pub fn push_triangles_iter(&mut self, triangles: impl Iterator<Item = TriangleDefinition>) {
1603        self.triangles.extend(triangles)
1604    }
1605
1606    /// Adds triangles from the given slice to the current buffer. Offsets each triangle by the
1607    /// given `offset` value.
1608    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    /// Clears the buffer.
1614    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
1633/// A typed attribute view for a specific vertex attribute in a vertex buffer.
1634pub 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    /// Tries to fetch attribute data at the given index.
1643    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
1652/// A typed attribute view for a specific vertex attribute in a vertex buffer.
1653pub 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    /// Tries to fetch attribute data at the given index.
1662    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>, // NEW
1930        }
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}