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 std::{
39    alloc::Layout,
40    fmt::{Display, Formatter},
41    hash::{Hash, Hasher},
42    marker::PhantomData,
43    mem::MaybeUninit,
44    ops::{Deref, DerefMut, Index, IndexMut, RangeBounds},
45    vec::Drain,
46};
47
48/// A common trait for all vertex types. **IMPORTANT:** Implementors **must** use `#[repr(C)]` attribute, otherwise the compiler
49/// is free to reorder fields and you might get weird results, because definition order will be different from memory order! See
50/// examples in [`VertexBuffer`] docs.
51pub trait VertexTrait: Copy + 'static {
52    /// Returns memory layout of the vertex. It basically tells a GPU how to interpret every byte range
53    /// of your vertex type; which kind of information it holds.
54    fn layout() -> &'static [VertexAttributeDescriptor];
55}
56
57/// Data type for a vertex attribute component.
58#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
59#[repr(u8)]
60#[derive(Default)]
61pub enum VertexAttributeDataType {
62    /// 32-bit floating-point.
63    #[default]
64    F32,
65    /// 32-bit unsigned integer.
66    U32,
67    /// 16-bit unsigned integer.
68    U16,
69    /// 8-bit unsigned integer.
70    U8,
71}
72
73impl VertexAttributeDataType {
74    /// Returns size of data in bytes.
75    pub fn size(self) -> u8 {
76        match self {
77            VertexAttributeDataType::F32 | VertexAttributeDataType::U32 => 4,
78            VertexAttributeDataType::U16 => 2,
79            VertexAttributeDataType::U8 => 1,
80        }
81    }
82}
83
84/// An usage for vertex attribute. It is a fixed set, but there are plenty
85/// room for any custom data - it may be fit into `TexCoordN` attributes.
86#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
87#[repr(u32)]
88#[derive(Default)]
89pub enum VertexAttributeUsage {
90    /// Vertex position. Usually `Vector2<f32>` or `Vector3<f32>`.
91    #[default]
92    Position = 0,
93    /// Vertex normal. Usually `Vector3<f32>`, more rare `Vector3<u16>` (F16).
94    Normal = 1,
95    /// Vertex tangent. Usually `Vector3<f32>`.
96    Tangent = 2,
97    /// First texture coordinates. Usually `Vector2<f32>`.
98    /// It may be used for everything else, not only for texture coordinates.
99    TexCoord0 = 3,
100    /// Second texture coordinates.
101    TexCoord1 = 4,
102    /// Third texture coordinates.
103    TexCoord2 = 5,
104    /// Fourth texture coordinates.
105    TexCoord3 = 6,
106    /// Fifth texture coordinates.
107    TexCoord4 = 7,
108    /// Sixth texture coordinates.
109    TexCoord5 = 8,
110    /// Seventh texture coordinates.
111    TexCoord6 = 9,
112    /// Eighth texture coordinates.
113    TexCoord7 = 10,
114    /// Bone weights. Usually `Vector4<f32>`.
115    BoneWeight = 11,
116    /// Bone indices. Usually `Vector4<u8>`.
117    BoneIndices = 12,
118    /// Color. Usually `Vector4<u8>`.
119    Color = 13,
120    /// First custom attribute with arbitrary, context-dependent meaning.
121    Custom0 = 14,
122    /// Second custom attribute with arbitrary, context-dependent meaning.
123    Custom1 = 15,
124    /// Third custom attribute with arbitrary, context-dependent meaning.
125    Custom2 = 16,
126    /// Fourth custom attribute with arbitrary, context-dependent meaning.
127    Custom3 = 17,
128    /// Fifth custom attribute with arbitrary, context-dependent meaning.
129    Custom4 = 18,
130    /// Sixth custom attribute with arbitrary, context-dependent meaning.
131    Custom5 = 19,
132    /// Seventh custom attribute with arbitrary, context-dependent meaning.
133    Custom6 = 20,
134    /// Eigth custom attribute with arbitrary, context-dependent meaning.
135    Custom7 = 21,
136    /// Maximum amount of attribute kinds.
137    Count,
138}
139
140/// Input vertex attribute descriptor used to construct layouts and feed vertex buffer.
141#[derive(Debug, Hash)]
142pub struct VertexAttributeDescriptor {
143    /// Claimed usage of the attribute. It could be Position, Normal, etc.
144    pub usage: VertexAttributeUsage,
145    /// Data type of every component of the attribute. It could be F32, U32, U16, etc.
146    pub data_type: VertexAttributeDataType,
147    /// Size of attribute expressed in components. For example, for `Position` it could
148    /// be 3 - which means there are 3 components in attribute of `data_type`.
149    pub size: u8,
150    /// Sets a "fetch rate" for vertex shader at which it will read vertex attribute:
151    ///  0 - per vertex (default)
152    ///  1 - per instance
153    ///  2 - per 2 instances and so on.
154    pub divisor: u8,
155    /// Defines location of the attribute in a shader (`layout(location = x) attrib;`)
156    pub shader_location: u8,
157    /// Whether the attribute values should be normalized into `0.0..1.0` range or not.
158    /// If this field is set to `false`, then the numbers will appear "as-is" when fetching
159    /// them in a shader. On the other hand, if it is `true`, then any numeric value will be
160    /// normalized by applying `normalized = num / T::max()` equation. This way all numbers will
161    /// always stay in `0.0..1.0` range.
162    ///
163    /// For example, normalization could be useful for RGB colors that expressed as three bytes (u8).
164    /// In this case normalization will turn the color into `0.0..1.0` range.  
165    pub normalized: bool,
166}
167
168/// Vertex attribute is a simple "bridge" between raw data and its interpretation. In
169/// other words it defines how to treat raw data in vertex shader.
170#[derive(Reflect, Visit, Copy, Clone, Default, Debug, Hash)]
171pub struct VertexAttribute {
172    /// Claimed usage of the attribute. It could be Position, Normal, etc.
173    pub usage: VertexAttributeUsage,
174    /// Data type of every component of the attribute. It could be F32, U32, U16, etc.
175    pub data_type: VertexAttributeDataType,
176    /// Size of attribute expressed in components. For example, for `Position` it could
177    /// be 3 - which means there are 3 components in attribute of `data_type`.
178    pub size: u8,
179    /// Sets a "fetch rate" for vertex shader at which it will read vertex attribute:
180    ///  0 - per vertex (default)
181    ///  1 - per instance
182    ///  2 - per 2 instances and so on.
183    pub divisor: u8,
184    /// Offset in bytes from beginning of the vertex.
185    pub offset: u8,
186    /// Defines location of the attribute in a shader (`layout(location = x) attrib;`)
187    pub shader_location: u8,
188    /// Whether the attribute values should be normalized into `0.0..1.0` range or not.
189    /// If this field is set to `false`, then the numbers will appear "as-is" when fetching
190    /// them in a shader. On the other hand, if it is `true`, then any numeric value will be
191    /// normalized by applying `normalized = num / T::max()` equation. This way all numbers will
192    /// always stay in `0.0..1.0` range.
193    ///
194    /// For example, normalization could be useful for RGB colors that expressed as three bytes (u8).
195    /// In this case normalization will turn the color into `0.0..1.0` range.  
196    #[visit(optional)]
197    pub normalized: bool,
198}
199
200impl Display for VertexAttribute {
201    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
202        write!(
203            f,
204            "Vertex Attribute:\n\tUsage: {:?}\n\tData Type: {:?}\n\tComponent Count: {}\n\t\
205            Divisor: {}\n\tOffset: {}\n\tBinding Point:{}\n\tNormalized: {}",
206            self.usage,
207            self.data_type,
208            self.size,
209            self.divisor,
210            self.offset,
211            self.shader_location,
212            self.normalized
213        )
214    }
215}
216
217/// Bytes storage of a vertex buffer.
218#[derive(Reflect, Clone, Debug)]
219pub struct BytesStorage {
220    bytes: Vec<u8>,
221    #[reflect(hidden)]
222    layout: Layout,
223}
224
225impl Visit for BytesStorage {
226    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
227        let mut bytes_adapter = PodVecView::from_pod_vec(&mut self.bytes);
228        if bytes_adapter.visit(name, visitor).is_err() {
229            let mut bytes = Vec::<u8>::new();
230            bytes.visit(name, visitor)?;
231            self.bytes = bytes;
232        }
233
234        if visitor.is_reading() {
235            self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
236        }
237        Ok(())
238    }
239}
240
241impl Default for BytesStorage {
242    fn default() -> Self {
243        Self {
244            bytes: Default::default(),
245            layout: Layout::array::<u8>(0).unwrap(),
246        }
247    }
248}
249
250impl BytesStorage {
251    /// Creates new empty bytes storage with the given capacity.
252    pub fn with_capacity(capacity: usize) -> Self {
253        Self {
254            bytes: Vec::with_capacity(capacity),
255            layout: Layout::array::<u8>(capacity).unwrap(),
256        }
257    }
258
259    /// Creates new bytes storage from the given data buffer.
260    pub fn new<T>(data: Vec<T>) -> Self {
261        // Prevent destructor to be called on `data`, this is needed because we're taking its
262        // data storage and treat it as a simple bytes block.
263        let mut data = std::mem::ManuallyDrop::new(data);
264        let bytes_length = data.len() * std::mem::size_of::<T>();
265        let bytes_capacity = data.capacity() * std::mem::size_of::<T>();
266        Self {
267            bytes: unsafe {
268                Vec::<u8>::from_raw_parts(
269                    data.as_mut_ptr() as *mut u8,
270                    bytes_length,
271                    bytes_capacity,
272                )
273            },
274            // Preserve initial memory layout, to ensure that the memory block will be deallocated
275            // with initial memory layout.
276            layout: Layout::array::<T>(data.capacity()).unwrap(),
277        }
278    }
279
280    fn extend_from_slice(&mut self, slice: &[u8]) {
281        if self.layout.align() != 1 {
282            // Realloc backing storage manually if the alignment is anything else than 1.
283            let new_storage = Vec::with_capacity(self.bytes.len());
284            let old_storage = std::mem::replace(&mut self.bytes, new_storage);
285            self.bytes.extend_from_slice(old_storage.as_slice());
286            self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
287        }
288        self.bytes.extend_from_slice(slice);
289        self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
290    }
291
292    fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
293    where
294        R: RangeBounds<usize>,
295    {
296        self.bytes.drain(range)
297    }
298
299    fn as_mut_ptr(&mut self) -> *mut u8 {
300        self.bytes.as_mut_ptr()
301    }
302
303    fn as_slice_mut(&mut self) -> &mut [u8] {
304        self.bytes.as_mut_slice()
305    }
306
307    fn clear(&mut self) {
308        self.bytes.clear()
309    }
310}
311
312impl Drop for BytesStorage {
313    fn drop(&mut self) {
314        let mut bytes = std::mem::ManuallyDrop::new(std::mem::take(&mut self.bytes));
315        // Dealloc manually with initial memory layout.
316        if bytes.capacity() != 0 {
317            unsafe { std::alloc::dealloc(bytes.as_mut_ptr(), self.layout) }
318        }
319    }
320}
321
322impl Deref for BytesStorage {
323    type Target = Vec<u8>;
324
325    fn deref(&self) -> &Self::Target {
326        &self.bytes
327    }
328}
329
330/// Vertex buffer with dynamic layout. It is used to store multiple vertices of a single type, that implements [`VertexTrait`].
331/// Different vertex types used to for efficient memory usage. For example, you could have a simple vertex with only position
332/// expressed as Vector3 and it will be enough for simple cases, when only position is required. However, if you want to draw
333/// a mesh with skeletal animation, that also supports texturing, lighting, you need to provide a lot more data (bone indices,
334/// bone weights, normals, tangents, texture coordinates).
335///
336/// ## Examples
337///
338/// ```rust
339/// # use fyrox_impl::{
340/// #     core::algebra::Vector3,
341/// #     scene::mesh::buffer::{
342/// #         VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexBuffer,
343/// #         VertexTrait,
344/// #     },
345/// # };
346/// #
347/// #[derive(Copy, Clone)]
348/// #[repr(C)]
349/// struct MyVertex {
350///     position: Vector3<f32>,
351/// }
352///
353/// impl VertexTrait for MyVertex {
354///     fn layout() -> &'static [VertexAttributeDescriptor] {
355///         &[VertexAttributeDescriptor {
356///             usage: VertexAttributeUsage::Position,
357///             data_type: VertexAttributeDataType::F32,
358///             size: 3,
359///             divisor: 0,
360///             shader_location: 0,
361///             normalized: false
362///         }]
363///     }
364/// }
365///
366/// fn create_triangle_vertex_buffer() -> VertexBuffer {
367///     VertexBuffer::new(
368///         3,
369///         vec![
370///             MyVertex {
371///                 position: Vector3::new(0.0, 0.0, 0.0),
372///             },
373///             MyVertex {
374///                 position: Vector3::new(0.0, 1.0, 0.0),
375///             },
376///             MyVertex {
377///                 position: Vector3::new(1.0, 1.0, 0.0),
378///             },
379///         ],
380///     )
381///     .unwrap()
382/// }  
383/// ```
384///
385/// This example creates a simple vertex buffer that contains a single triangle with custom vertex format. The most important
386/// part here is [`VertexTrait::layout`] implementation - it describes each "attribute" of your vertex, if your layout does not
387/// match the actual content of the vertex (in terms of size in bytes), then vertex buffer cannot be created and [`VertexBuffer::new`]
388/// will return [`None`].
389///
390/// The second, but not least important is `#[repr(C)]` attribute - it is mandatory for every vertex type, it forbids fields
391/// reordering of you vertex structure and guarantees that they will have the same layout in memory as their declaration order.
392///
393/// ## Limitations
394///
395/// Vertex size cannot be more than 256 bytes, this limitation shouldn't be a problem because almost every GPU supports up to
396/// 16 vertex attributes with 16 bytes of size each, which gives exactly 256 bytes.
397#[derive(Reflect, Clone, Visit, Default, Debug)]
398pub struct VertexBuffer {
399    dense_layout: Vec<VertexAttribute>,
400    sparse_layout: [Option<VertexAttribute>; VertexAttributeUsage::Count as usize],
401    vertex_size: u8,
402    vertex_count: u32,
403    data: BytesStorage,
404    #[visit(optional)]
405    layout_hash: u64,
406    #[visit(optional)]
407    modifications_counter: u64,
408}
409
410fn calculate_layout_hash(layout: &[VertexAttribute]) -> u64 {
411    let mut hasher = FxHasher::default();
412    layout.hash(&mut hasher);
413    hasher.finish()
414}
415
416fn calculate_data_hash(data: &[u8]) -> u64 {
417    let mut hasher = FxHasher::default();
418    data.hash(&mut hasher);
419    hasher.finish()
420}
421
422/// See VertexBuffer::modify for more info.
423pub struct VertexBufferRefMut<'a> {
424    vertex_buffer: &'a mut VertexBuffer,
425}
426
427impl Drop for VertexBufferRefMut<'_> {
428    fn drop(&mut self) {
429        self.vertex_buffer.modifications_counter += 1;
430    }
431}
432
433impl Deref for VertexBufferRefMut<'_> {
434    type Target = VertexBuffer;
435
436    fn deref(&self) -> &Self::Target {
437        self.vertex_buffer
438    }
439}
440
441impl DerefMut for VertexBufferRefMut<'_> {
442    fn deref_mut(&mut self) -> &mut Self::Target {
443        self.vertex_buffer
444    }
445}
446
447impl VertexBufferRefMut<'_> {
448    /// Tries to append a vertex to the buffer.
449    ///
450    /// # Safety and validation
451    ///
452    /// This method accepts any type that has appropriate size, the size must be equal
453    /// with the size defined by layout. The Copy trait bound is required to ensure that
454    /// the type does not have any custom destructors.
455    pub fn push_vertex<T>(&mut self, vertex: &T) -> Result<(), ValidationError>
456    where
457        T: VertexTrait + bytemuck::Pod,
458    {
459        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
460            self.vertex_buffer
461                .data
462                .extend_from_slice(value_as_u8_slice(vertex));
463            self.vertex_buffer.vertex_count += 1;
464            Ok(())
465        } else {
466            Err(ValidationError::InvalidVertexSize {
467                expected: self.vertex_buffer.vertex_size,
468                actual: std::mem::size_of::<T>() as u8,
469            })
470        }
471    }
472
473    /// Tries to append a slice of vertices to the buffer.
474    ///
475    /// # Safety and validation
476    ///
477    /// This method accepts any type that has appropriate size, the size must be equal
478    /// with the size defined by layout. The Copy trait bound is required to ensure that
479    /// the type does not have any custom destructors.
480    pub fn push_vertices<T>(&mut self, vertices: &[T]) -> Result<(), ValidationError>
481    where
482        T: VertexTrait + Pod,
483    {
484        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
485            self.vertex_buffer
486                .data
487                .extend_from_slice(array_as_u8_slice(vertices));
488            self.vertex_buffer.vertex_count += vertices.len() as u32;
489            Ok(())
490        } else {
491            Err(ValidationError::InvalidVertexSize {
492                expected: self.vertex_buffer.vertex_size,
493                actual: std::mem::size_of::<T>() as u8,
494            })
495        }
496    }
497
498    /// Tries to append a raw vertex data to the vertex buffer. This method will fail if the `data`
499    /// size does not match the vertex size of the buffer.
500    pub fn push_vertex_raw(&mut self, data: &[u8]) -> Result<(), ValidationError> {
501        if data.len() == self.vertex_buffer.vertex_size as usize {
502            self.vertex_buffer.data.extend_from_slice(data);
503            self.vertex_buffer.vertex_count += 1;
504            Ok(())
505        } else {
506            Err(ValidationError::InvalidVertexSize {
507                expected: self.vertex_buffer.vertex_size,
508                actual: data.len() as u8,
509            })
510        }
511    }
512
513    /// Tries to append the vertices that the given iterator produces.
514    ///
515    /// # Safety and validation
516    ///
517    /// This method accepts any type that has appropriate size, the size must be equal
518    /// with the size defined by layout. The Copy trait bound is required to ensure that
519    /// the type does not have any custom destructors.
520    pub fn push_vertices_iter<T>(
521        &mut self,
522        vertices: impl Iterator<Item = T>,
523    ) -> Result<(), ValidationError>
524    where
525        T: VertexTrait + Pod,
526    {
527        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
528            for vertex in vertices {
529                self.vertex_buffer
530                    .data
531                    .extend_from_slice(value_as_u8_slice(&vertex));
532                self.vertex_buffer.vertex_count += 1;
533            }
534            Ok(())
535        } else {
536            Err(ValidationError::InvalidVertexSize {
537                expected: self.vertex_buffer.vertex_size,
538                actual: std::mem::size_of::<T>() as u8,
539            })
540        }
541    }
542
543    /// Tries to append a slice of vertices to the buffer. Each vertex will be transformed using
544    /// `transformer` callback.
545    ///
546    /// # Safety and validation
547    ///
548    /// This method accepts any type that has appropriate size, the size must be equal
549    /// with the size defined by layout. The Copy trait bound is required to ensure that
550    /// the type does not have any custom destructors.
551    pub fn push_vertices_transform<T, F>(
552        &mut self,
553        vertices: &[T],
554        mut transformer: F,
555    ) -> Result<(), ValidationError>
556    where
557        T: VertexTrait + Pod,
558        F: FnMut(&T) -> T,
559    {
560        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
561            for vertex in vertices {
562                let transformed = transformer(vertex);
563
564                self.vertex_buffer
565                    .data
566                    .extend_from_slice(value_as_u8_slice(&transformed));
567            }
568            self.vertex_buffer.vertex_count += vertices.len() as u32;
569            Ok(())
570        } else {
571            Err(ValidationError::InvalidVertexSize {
572                expected: self.vertex_buffer.vertex_size,
573                actual: std::mem::size_of::<T>() as u8,
574            })
575        }
576    }
577
578    /// Removes last vertex from the buffer.
579    pub fn remove_last_vertex(&mut self) {
580        let range = (self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize)..;
581        self.vertex_buffer.data.drain(range);
582        self.vertex_buffer.vertex_count -= 1;
583    }
584
585    /// Copies data of last vertex from the buffer to an instance of variable of a type.
586    ///
587    /// # Safety and validation
588    ///
589    /// This method accepts any type that has appropriate size, the size must be equal
590    /// with the size defined by layout. The Copy trait bound is required to ensure that
591    /// the type does not have any custom destructors.
592    pub fn pop_vertex<T>(&mut self) -> Result<T, ValidationError>
593    where
594        T: VertexTrait,
595    {
596        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize
597            && self.vertex_buffer.data.len() >= self.vertex_buffer.vertex_size as usize
598        {
599            unsafe {
600                let mut v = MaybeUninit::<T>::uninit();
601                std::ptr::copy_nonoverlapping(
602                    self.vertex_buffer.data.as_ptr().add(
603                        self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize,
604                    ),
605                    v.as_mut_ptr() as *mut u8,
606                    self.vertex_buffer.vertex_size as usize,
607                );
608                let range =
609                    (self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize)..;
610                self.vertex_buffer.data.drain(range);
611                self.vertex_buffer.vertex_count -= 1;
612                Ok(v.assume_init())
613            }
614        } else {
615            Err(ValidationError::InvalidVertexSize {
616                expected: self.vertex_buffer.vertex_size,
617                actual: std::mem::size_of::<T>() as u8,
618            })
619        }
620    }
621
622    /// Tries to cast internal data buffer to a slice of given type. It may fail if
623    /// size of type is not equal with claimed size (which is set by the layout).
624    pub fn cast_data_mut<T>(&mut self) -> Result<&mut [T], ValidationError>
625    where
626        T: VertexTrait,
627    {
628        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
629            Ok(unsafe {
630                std::slice::from_raw_parts_mut(
631                    self.vertex_buffer.data.as_mut_ptr() as *const T as *mut T,
632                    self.vertex_buffer.data.len() / std::mem::size_of::<T>(),
633                )
634            })
635        } else {
636            Err(ValidationError::InvalidVertexSize {
637                expected: self.vertex_buffer.vertex_size,
638                actual: std::mem::size_of::<T>() as u8,
639            })
640        }
641    }
642
643    /// Creates iterator that emits read/write accessors for vertices.
644    pub fn iter_mut(&mut self) -> impl Iterator<Item = VertexViewMut<'_>> + '_ {
645        unsafe {
646            VertexViewMutIterator {
647                ptr: self.vertex_buffer.data.as_mut_ptr(),
648                end: self.data.as_mut_ptr().add(
649                    self.vertex_buffer.vertex_size as usize
650                        * self.vertex_buffer.vertex_count as usize,
651                ),
652                vertex_size: self.vertex_buffer.vertex_size,
653                sparse_layout: &self.vertex_buffer.sparse_layout,
654                marker: PhantomData,
655            }
656        }
657    }
658
659    /// Returns a read/write accessor of n-th vertex.
660    pub fn get_mut(&mut self, n: usize) -> Option<VertexViewMut<'_>> {
661        let offset = n * self.vertex_buffer.vertex_size as usize;
662        if offset < self.vertex_buffer.data.len() {
663            Some(VertexViewMut {
664                vertex_data: &mut self.vertex_buffer.data.as_slice_mut()
665                    [offset..(offset + self.vertex_buffer.vertex_size as usize)],
666                sparse_layout: &self.vertex_buffer.sparse_layout,
667            })
668        } else {
669            None
670        }
671    }
672
673    /// Duplicates n-th vertex and puts it at the back of the buffer.
674    pub fn duplicate(&mut self, n: usize) {
675        // Vertex cannot be larger than 256 bytes, so having temporary array of
676        // such size is ok.
677        let mut temp = ArrayVec::<u8, 256>::new();
678        temp.try_extend_from_slice(
679            &self.vertex_buffer.data[(n * self.vertex_buffer.vertex_size as usize)
680                ..((n + 1) * self.vertex_buffer.vertex_size as usize)],
681        )
682        .unwrap();
683        self.vertex_buffer.data.extend_from_slice(temp.as_slice());
684        self.vertex_buffer.vertex_count += 1;
685    }
686
687    /// Adds new attribute at the end of layout, reorganizes internal data storage to be
688    /// able to contain new attribute. Default value of the new attribute in the buffer
689    /// becomes `fill_value`. Graphically this could be represented like so:
690    ///
691    /// Add secondary texture coordinates:
692    ///  Before: P1_N1_TC1_P2_N2_TC2...
693    ///  After: P1_N1_TC1_TC2(fill_value)_P2_N2_TC2_TC2(fill_value)...
694    pub fn add_attribute<T>(
695        &mut self,
696        descriptor: VertexAttributeDescriptor,
697        fill_value: T,
698    ) -> Result<(), ValidationError>
699    where
700        T: Copy + Pod,
701    {
702        if self.vertex_buffer.sparse_layout[descriptor.usage as usize].is_some() {
703            Err(ValidationError::DuplicatedAttributeDescriptor)
704        } else {
705            let vertex_attribute = VertexAttribute {
706                usage: descriptor.usage,
707                data_type: descriptor.data_type,
708                size: descriptor.size,
709                divisor: descriptor.divisor,
710                offset: self.vertex_buffer.vertex_size,
711                shader_location: descriptor.shader_location,
712                normalized: descriptor.normalized,
713            };
714            self.vertex_buffer.sparse_layout[descriptor.usage as usize] = Some(vertex_attribute);
715            self.vertex_buffer.dense_layout.push(vertex_attribute);
716
717            self.layout_hash = calculate_layout_hash(&self.vertex_buffer.dense_layout);
718
719            let mut new_data = Vec::new();
720
721            for chunk in self
722                .vertex_buffer
723                .data
724                .chunks_exact(self.vertex_buffer.vertex_size as usize)
725            {
726                let mut temp = ArrayVec::<u8, 256>::new();
727                temp.try_extend_from_slice(chunk).unwrap();
728                temp.try_extend_from_slice(value_as_u8_slice(&fill_value))
729                    .unwrap();
730                new_data.extend_from_slice(&temp);
731            }
732
733            self.vertex_buffer.data = BytesStorage::new(new_data);
734
735            self.vertex_buffer.vertex_size += std::mem::size_of::<T>() as u8;
736
737            Ok(())
738        }
739    }
740
741    /// Clears the buffer making it empty.
742    pub fn clear(&mut self) {
743        self.data.clear();
744        self.vertex_count = 0;
745    }
746}
747
748/// An error that may occur during input data and layout validation.
749#[derive(Debug)]
750pub enum ValidationError {
751    /// Attribute size must be either 1, 2, 3 or 4.
752    InvalidAttributeSize(usize),
753
754    /// Data size is not correct.
755    InvalidDataSize {
756        /// Expected data size in bytes.
757        expected: usize,
758        /// Actual data size in bytes.
759        actual: usize,
760    },
761
762    /// Trying to add vertex of incorrect size.
763    InvalidVertexSize {
764        /// Expected vertex size.
765        expected: u8,
766        /// Actual vertex size.
767        actual: u8,
768    },
769
770    /// A duplicate of a descriptor was found.
771    DuplicatedAttributeDescriptor,
772
773    /// Duplicate shader locations were found.
774    ConflictingShaderLocations(usize),
775}
776
777impl Display for ValidationError {
778    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
779        match self {
780            ValidationError::InvalidAttributeSize(v) => {
781                write!(f, "Invalid attribute size {v}. Must be either 1, 2, 3 or 4")
782            }
783            ValidationError::InvalidDataSize { expected, actual } => {
784                write!(f, "Invalid data size. Expected {expected}, got {actual}.")
785            }
786            ValidationError::InvalidVertexSize { expected, actual } => {
787                write!(f, "Invalid vertex size. Expected {expected}, got {actual}.",)
788            }
789            ValidationError::DuplicatedAttributeDescriptor => {
790                write!(f, "A duplicate of a descriptor was found.")
791            }
792            ValidationError::ConflictingShaderLocations(v) => {
793                write!(f, "Duplicate shader locations were found {v}.")
794            }
795        }
796    }
797}
798
799impl VertexBuffer {
800    /// Creates new vertex buffer from provided data and with the given layout of the vertex type `T`.
801    pub fn new<T>(vertex_count: usize, data: Vec<T>) -> Result<Self, ValidationError>
802    where
803        T: VertexTrait,
804    {
805        Self::new_with_layout(T::layout(), vertex_count, BytesStorage::new(data))
806    }
807
808    /// Creates new vertex buffer from the given layout, vertex count and bytes storage.
809    pub fn new_with_layout(
810        layout: &[VertexAttributeDescriptor],
811        vertex_count: usize,
812        bytes: BytesStorage,
813    ) -> Result<Self, ValidationError> {
814        // Validate for duplicates and invalid layout.
815        for descriptor in layout {
816            for other_descriptor in layout {
817                if !std::ptr::eq(descriptor, other_descriptor) {
818                    if descriptor.usage == other_descriptor.usage {
819                        return Err(ValidationError::DuplicatedAttributeDescriptor);
820                    } else if descriptor.shader_location == other_descriptor.shader_location {
821                        return Err(ValidationError::ConflictingShaderLocations(
822                            descriptor.shader_location as usize,
823                        ));
824                    }
825                }
826            }
827        }
828
829        let mut dense_layout = Vec::new();
830
831        // Validate everything as much as possible and calculate vertex size.
832        let mut sparse_layout = [None; VertexAttributeUsage::Count as usize];
833        let mut vertex_size_bytes = 0u8;
834        for attribute in layout.iter() {
835            if attribute.size < 1 || attribute.size > 4 {
836                return Err(ValidationError::InvalidAttributeSize(
837                    attribute.size as usize,
838                ));
839            }
840
841            let vertex_attribute = VertexAttribute {
842                usage: attribute.usage,
843                data_type: attribute.data_type,
844                size: attribute.size,
845                divisor: attribute.divisor,
846                offset: vertex_size_bytes,
847                shader_location: attribute.shader_location,
848                normalized: attribute.normalized,
849            };
850
851            dense_layout.push(vertex_attribute);
852
853            // Map dense to sparse layout to increase performance.
854            sparse_layout[attribute.usage as usize] = Some(vertex_attribute);
855
856            vertex_size_bytes += attribute.size * attribute.data_type.size();
857        }
858
859        let expected_data_size = vertex_count * vertex_size_bytes as usize;
860        if expected_data_size != bytes.len() {
861            return Err(ValidationError::InvalidDataSize {
862                expected: expected_data_size,
863                actual: bytes.len(),
864            });
865        }
866
867        Ok(Self {
868            vertex_size: vertex_size_bytes,
869            vertex_count: vertex_count as u32,
870            modifications_counter: 0,
871            data: bytes,
872            layout_hash: calculate_layout_hash(&dense_layout),
873            sparse_layout,
874            dense_layout,
875        })
876    }
877
878    /// Creates a new empty vertex buffer with the same layout and vertex size, but with an empty
879    /// inner buffer of the specified capacity.  
880    pub fn clone_empty(&self, capacity: usize) -> Self {
881        Self {
882            dense_layout: self.dense_layout.clone(),
883            sparse_layout: self.sparse_layout,
884            vertex_size: self.vertex_size,
885            vertex_count: 0,
886            data: BytesStorage::with_capacity(capacity),
887            layout_hash: self.layout_hash,
888            modifications_counter: 0,
889        }
890    }
891
892    /// Returns a reference to underlying data buffer slice.
893    pub fn raw_data(&self) -> &[u8] {
894        &self.data
895    }
896
897    /// Returns true if buffer does not contain any vertex, false - otherwise.
898    pub fn is_empty(&self) -> bool {
899        self.vertex_count == 0
900    }
901
902    /// Returns the total amount of times the buffer was modified.
903    pub fn modifications_count(&self) -> u64 {
904        self.modifications_counter
905    }
906
907    /// Calculates inner data hash.
908    pub fn content_hash(&self) -> u64 {
909        calculate_data_hash(&self.data.bytes)
910    }
911
912    /// Returns hash of vertex buffer layout. Cached value is guaranteed to be in actual state.
913    /// The hash could be used to check if the layout has changed.
914    pub fn layout_hash(&self) -> u64 {
915        self.layout_hash
916    }
917
918    /// Provides mutable access to content of the buffer.
919    ///
920    /// # Performance
921    ///
922    /// This method returns a special structure which has custom destructor that increases use
923    /// counter of the data once modification is over. You **must** hold this structure as long as
924    /// possible while modifying the contents of the buffer. Do **not** even try to do this:
925    ///
926    /// ```no_run
927    /// use fyrox_impl::{
928    ///     scene::mesh::buffer::{VertexBuffer, VertexWriteTrait, VertexAttributeUsage},
929    ///     core::algebra::Vector3
930    /// };
931    /// fn do_something(buffer: &mut VertexBuffer) {
932    ///     for i in 0..buffer.vertex_count() {
933    ///         buffer
934    ///             .modify() // Doing this in a loop will cause performance issues!
935    ///             .get_mut(i as usize)
936    ///             .unwrap()
937    ///             .write_3_f32(VertexAttributeUsage::Position, Vector3::<f32>::default())
938    ///             .unwrap();
939    ///     }
940    /// }
941    /// ```
942    ///
943    /// Instead, do this:
944    ///
945    /// ```no_run
946    /// use fyrox_impl::{
947    ///     scene::mesh::buffer::{VertexBuffer, VertexWriteTrait, VertexAttributeUsage},
948    ///     core::algebra::Vector3
949    /// };
950    /// fn do_something(buffer: &mut VertexBuffer) {
951    ///     let mut buffer_modifier = buffer.modify();
952    ///     for mut vertex in buffer_modifier.iter_mut() {
953    ///         vertex
954    ///             .write_3_f32(VertexAttributeUsage::Position, Vector3::<f32>::default())
955    ///             .unwrap();
956    ///     }
957    /// }
958    /// ```
959    ///
960    /// Why do we even need such complications? It is used to notify the GPU that the content has
961    /// changed and must be re-uploaded to the GPU.
962    pub fn modify(&mut self) -> VertexBufferRefMut<'_> {
963        VertexBufferRefMut {
964            vertex_buffer: self,
965        }
966    }
967
968    /// Checks if an attribute of `usage` exists.
969    pub fn has_attribute(&self, usage: VertexAttributeUsage) -> bool {
970        self.sparse_layout[usage as usize].is_some()
971    }
972
973    /// Returns vertex buffer layout.
974    pub fn layout(&self) -> &[VertexAttribute] {
975        &self.dense_layout
976    }
977
978    /// Returns vertex buffer layout.
979    pub fn layout_descriptor(&self) -> impl Iterator<Item = VertexAttributeDescriptor> + '_ {
980        self.dense_layout
981            .iter()
982            .map(|attrib| VertexAttributeDescriptor {
983                usage: attrib.usage,
984                data_type: attrib.data_type,
985                size: attrib.size,
986                divisor: attrib.divisor,
987                shader_location: attrib.shader_location,
988                normalized: attrib.normalized,
989            })
990    }
991
992    /// Tries to cast internal data buffer to a slice of given type. It may fail if
993    /// size of type is not equal with claimed size (which is set by the layout).
994    pub fn cast_data_ref<T>(&self) -> Result<&[T], ValidationError>
995    where
996        T: VertexTrait,
997    {
998        if std::mem::size_of::<T>() == self.vertex_size as usize {
999            Ok(unsafe {
1000                std::slice::from_raw_parts(
1001                    self.data.as_ptr() as *const T,
1002                    self.data.len() / std::mem::size_of::<T>(),
1003                )
1004            })
1005        } else {
1006            Err(ValidationError::InvalidVertexSize {
1007                expected: self.vertex_size,
1008                actual: std::mem::size_of::<T>() as u8,
1009            })
1010        }
1011    }
1012
1013    /// Creates iterator that emits read accessors for vertices.
1014    pub fn iter(&self) -> impl Iterator<Item = VertexViewRef<'_>> + '_ {
1015        VertexViewRefIterator {
1016            data: &self.data,
1017            offset: 0,
1018            end: self.vertex_size as usize * self.vertex_count as usize,
1019            vertex_size: self.vertex_size,
1020            sparse_layout: &self.sparse_layout,
1021        }
1022    }
1023
1024    /// Returns a read accessor of n-th vertex.
1025    pub fn get(&self, n: usize) -> Option<VertexViewRef<'_>> {
1026        let offset = n * self.vertex_size as usize;
1027        if offset < self.data.len() {
1028            Some(VertexViewRef {
1029                vertex_data: &self.data[offset..(offset + self.vertex_size as usize)],
1030                sparse_layout: &self.sparse_layout,
1031            })
1032        } else {
1033            None
1034        }
1035    }
1036
1037    /// Returns exact amount of vertices in the buffer.
1038    pub fn vertex_count(&self) -> u32 {
1039        self.vertex_count
1040    }
1041
1042    /// Return vertex size of the buffer.
1043    pub fn vertex_size(&self) -> u8 {
1044        self.vertex_size
1045    }
1046
1047    /// Finds free location for an attribute in the layout.
1048    pub fn find_free_shader_location(&self) -> u8 {
1049        let mut location = None;
1050        for attribute in self.dense_layout.chunks_exact(2) {
1051            let left = &attribute[0];
1052            let right = &attribute[1];
1053
1054            if (left.shader_location as i32 - right.shader_location as i32).abs() > 1 {
1055                // We have a gap, use some value from it.
1056                let origin = left.shader_location.min(right.shader_location);
1057                location = Some(origin + 1);
1058                break;
1059            }
1060        }
1061
1062        location.unwrap_or_else(|| {
1063            self.dense_layout
1064                .last()
1065                .map(|a| a.shader_location)
1066                .unwrap_or(0)
1067                + 1
1068        })
1069    }
1070
1071    /// Tries to find an attribute with the given `usage` and if it exists, returns its "view", that
1072    /// allows you to fetch data like in ordinary array.
1073    #[inline]
1074    pub fn attribute_view<T>(&self, usage: VertexAttributeUsage) -> Option<AttributeViewRef<'_, T>>
1075    where
1076        T: Copy,
1077    {
1078        self.dense_layout
1079            .iter()
1080            .find(|attribute| {
1081                attribute.usage == usage
1082                    && attribute.size * attribute.data_type.size() == std::mem::size_of::<T>() as u8
1083            })
1084            .map(|attribute| AttributeViewRef {
1085                ptr: unsafe { self.data.bytes.as_ptr().add(attribute.offset as usize) },
1086                stride: self.vertex_size as usize,
1087                count: self.vertex_count as usize,
1088                phantom: Default::default(),
1089            })
1090    }
1091
1092    /// Tries to find an attribute with the given `usage` and if it exists, returns its "view", that
1093    /// allows you to fetch data like in ordinary array.
1094    #[inline]
1095    pub fn attribute_view_mut<T: Copy>(
1096        &mut self,
1097        usage: VertexAttributeUsage,
1098    ) -> Option<AttributeViewRefMut<'_, T>> {
1099        if let Some(attribute) = self.dense_layout.iter().find(|attribute| {
1100            attribute.usage == usage
1101                && attribute.size * attribute.data_type.size() == std::mem::size_of::<T>() as u8
1102        }) {
1103            Some(AttributeViewRefMut {
1104                ptr: unsafe { self.data.bytes.as_mut_ptr().add(attribute.offset as usize) },
1105                stride: self.vertex_size as usize,
1106                count: self.vertex_count as usize,
1107                phantom: Default::default(),
1108            })
1109        } else {
1110            None
1111        }
1112    }
1113}
1114
1115struct VertexViewRefIterator<'a> {
1116    data: &'a [u8],
1117    sparse_layout: &'a [Option<VertexAttribute>],
1118    offset: usize,
1119    end: usize,
1120    vertex_size: u8,
1121}
1122
1123impl<'a> Iterator for VertexViewRefIterator<'a> {
1124    type Item = VertexViewRef<'a>;
1125
1126    fn next(&mut self) -> Option<Self::Item> {
1127        if self.offset >= self.end {
1128            None
1129        } else {
1130            let view = VertexViewRef {
1131                vertex_data: &self.data[self.offset..(self.offset + self.vertex_size as usize)],
1132                sparse_layout: self.sparse_layout,
1133            };
1134            self.offset += self.vertex_size as usize;
1135            Some(view)
1136        }
1137    }
1138}
1139
1140struct VertexViewMutIterator<'a> {
1141    ptr: *mut u8,
1142    sparse_layout: &'a [Option<VertexAttribute>],
1143    end: *mut u8,
1144    vertex_size: u8,
1145    marker: PhantomData<&'a mut u8>,
1146}
1147
1148impl<'a> Iterator for VertexViewMutIterator<'a> {
1149    type Item = VertexViewMut<'a>;
1150
1151    fn next(&mut self) -> Option<Self::Item> {
1152        if self.ptr >= self.end {
1153            None
1154        } else {
1155            unsafe {
1156                let data = std::slice::from_raw_parts_mut(self.ptr, self.vertex_size as usize);
1157                let view = VertexViewMut {
1158                    vertex_data: data,
1159                    sparse_layout: self.sparse_layout,
1160                };
1161                self.ptr = self.ptr.add(self.vertex_size as usize);
1162                Some(view)
1163            }
1164        }
1165    }
1166}
1167
1168/// Read accessor for a vertex with some layout.
1169#[derive(Debug)]
1170pub struct VertexViewRef<'a> {
1171    vertex_data: &'a [u8],
1172    sparse_layout: &'a [Option<VertexAttribute>],
1173}
1174
1175impl PartialEq for VertexViewRef<'_> {
1176    fn eq(&self, other: &Self) -> bool {
1177        self.vertex_data == other.vertex_data
1178    }
1179}
1180
1181/// Read/write accessor for a vertex with some layout.
1182#[derive(Debug)]
1183pub struct VertexViewMut<'a> {
1184    vertex_data: &'a mut [u8],
1185    sparse_layout: &'a [Option<VertexAttribute>],
1186}
1187
1188impl PartialEq for VertexViewMut<'_> {
1189    fn eq(&self, other: &Self) -> bool {
1190        self.vertex_data == other.vertex_data
1191    }
1192}
1193
1194/// An error that may occur during fetching using vertex read/write accessor.
1195#[derive(Debug)]
1196pub enum VertexFetchError {
1197    /// Trying to read/write non-existent attribute.
1198    NoSuchAttribute(VertexAttributeUsage),
1199    /// Size mistmatch.
1200    SizeMismatch {
1201        /// Expected size in bytes.
1202        expected: u8,
1203        /// Actual size in bytes.
1204        actual: u8,
1205    },
1206    /// IO error.
1207    Io(std::io::Error),
1208}
1209
1210impl std::error::Error for VertexFetchError {}
1211
1212impl Display for VertexFetchError {
1213    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1214        match self {
1215            VertexFetchError::NoSuchAttribute(v) => {
1216                write!(f, "No attribute with such usage: {v:?}")
1217            }
1218            VertexFetchError::Io(v) => {
1219                write!(f, "An i/o error has occurred {v:?}")
1220            }
1221            VertexFetchError::SizeMismatch { expected, actual } => {
1222                write!(f, "Size mismatch. Expected {expected}, got {actual}")
1223            }
1224        }
1225    }
1226}
1227
1228impl From<std::io::Error> for VertexFetchError {
1229    fn from(e: Error) -> Self {
1230        Self::Io(e)
1231    }
1232}
1233
1234/// A trait for read-only vertex data accessor.
1235pub trait VertexReadTrait {
1236    #[doc(hidden)]
1237    fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]);
1238
1239    /// Clones the vertex and applies the given transformer closure to it and returns a stack-allocated
1240    /// data buffer representing the transformed vertex.
1241    #[inline(always)]
1242    fn transform<F>(&self, func: &mut F) -> ArrayVec<u8, 256>
1243    where
1244        F: FnMut(VertexViewMut),
1245    {
1246        let (data, layout) = self.data_layout_ref();
1247        let mut transformed = ArrayVec::new();
1248        transformed
1249            .try_extend_from_slice(data)
1250            .expect("Vertex size cannot be larger than 256 bytes!");
1251        func(VertexViewMut {
1252            vertex_data: &mut transformed,
1253            sparse_layout: layout,
1254        });
1255        transformed
1256    }
1257
1258    /// Tries to read an attribute with given usage as a pair of two f32.
1259    #[inline(always)]
1260    fn read_2_f32(&self, usage: VertexAttributeUsage) -> Result<Vector2<f32>, VertexFetchError> {
1261        let (data, layout) = self.data_layout_ref();
1262        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1263            let x = LittleEndian::read_f32(&data[(attribute.offset as usize)..]);
1264            let y = LittleEndian::read_f32(&data[(attribute.offset as usize + 4)..]);
1265            Ok(Vector2::new(x, y))
1266        } else {
1267            Err(VertexFetchError::NoSuchAttribute(usage))
1268        }
1269    }
1270
1271    /// Tries to read an attribute with given usage as a pair of three f32.
1272    #[inline(always)]
1273    fn read_3_f32(&self, usage: VertexAttributeUsage) -> Result<Vector3<f32>, VertexFetchError> {
1274        let (data, layout) = self.data_layout_ref();
1275        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1276            let x = LittleEndian::read_f32(&data[(attribute.offset as usize)..]);
1277            let y = LittleEndian::read_f32(&data[(attribute.offset as usize + 4)..]);
1278            let z = LittleEndian::read_f32(&data[(attribute.offset as usize + 8)..]);
1279            Ok(Vector3::new(x, y, z))
1280        } else {
1281            Err(VertexFetchError::NoSuchAttribute(usage))
1282        }
1283    }
1284
1285    /// Tries to read an attribute with given usage as a pair of four f32.
1286    #[inline(always)]
1287    fn read_4_f32(&self, usage: VertexAttributeUsage) -> Result<Vector4<f32>, VertexFetchError> {
1288        let (data, layout) = self.data_layout_ref();
1289        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1290            let x = LittleEndian::read_f32(&data[(attribute.offset as usize)..]);
1291            let y = LittleEndian::read_f32(&data[(attribute.offset as usize + 4)..]);
1292            let z = LittleEndian::read_f32(&data[(attribute.offset as usize + 8)..]);
1293            let w = LittleEndian::read_f32(&data[(attribute.offset as usize + 12)..]);
1294            Ok(Vector4::new(x, y, z, w))
1295        } else {
1296            Err(VertexFetchError::NoSuchAttribute(usage))
1297        }
1298    }
1299
1300    /// Tries to read an attribute with given usage as a pair of four u8.
1301    #[inline(always)]
1302    fn read_4_u8(&self, usage: VertexAttributeUsage) -> Result<Vector4<u8>, VertexFetchError> {
1303        let (data, layout) = self.data_layout_ref();
1304        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1305            let offset = attribute.offset as usize;
1306            let x = data[offset];
1307            let y = data[offset + 1];
1308            let z = data[offset + 2];
1309            let w = data[offset + 3];
1310            Ok(Vector4::new(x, y, z, w))
1311        } else {
1312            Err(VertexFetchError::NoSuchAttribute(usage))
1313        }
1314    }
1315}
1316
1317impl VertexReadTrait for VertexViewRef<'_> {
1318    fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]) {
1319        (self.vertex_data, self.sparse_layout)
1320    }
1321}
1322
1323/// A trait for read/write vertex data accessor.
1324pub trait VertexWriteTrait: VertexReadTrait {
1325    #[doc(hidden)]
1326    fn data_layout_mut(&mut self) -> (&mut [u8], &[Option<VertexAttribute>]);
1327
1328    /// Tries to find an attribute of the given type and returns a mutable reference of the specified
1329    /// type. Type casting will fail if the size of the destination type `T` does not match the
1330    /// actual attribute size.
1331    #[inline(always)]
1332    fn cast_attribute<T: Copy>(
1333        &mut self,
1334        usage: VertexAttributeUsage,
1335    ) -> Result<&mut T, VertexFetchError> {
1336        let (data, layout) = self.data_layout_mut();
1337        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1338            let expected_size = (attribute.size * attribute.data_type.size()) as usize;
1339            let actual_size = std::mem::size_of::<T>();
1340            if expected_size == std::mem::size_of::<T>() {
1341                Ok(unsafe { &mut *(data.as_mut_ptr().add(attribute.offset as usize) as *mut T) })
1342            } else {
1343                Err(VertexFetchError::SizeMismatch {
1344                    expected: expected_size as u8,
1345                    actual: actual_size as u8,
1346                })
1347            }
1348        } else {
1349            Err(VertexFetchError::NoSuchAttribute(usage))
1350        }
1351    }
1352
1353    /// Tries to write an attribute with given usage as a pair of two f32.
1354    fn write_2_f32(
1355        &mut self,
1356        usage: VertexAttributeUsage,
1357        value: Vector2<f32>,
1358    ) -> Result<(), VertexFetchError>;
1359
1360    /// Tries to write an attribute with given usage as a pair of three f32.
1361    fn write_3_f32(
1362        &mut self,
1363        usage: VertexAttributeUsage,
1364        value: Vector3<f32>,
1365    ) -> Result<(), VertexFetchError>;
1366
1367    /// Tries to write an attribute with given usage as a pair of four f32.
1368    fn write_4_f32(
1369        &mut self,
1370        usage: VertexAttributeUsage,
1371        value: Vector4<f32>,
1372    ) -> Result<(), VertexFetchError>;
1373
1374    /// Tries to write an attribute with given usage as a pair of four u8.
1375    fn write_4_u8(
1376        &mut self,
1377        usage: VertexAttributeUsage,
1378        value: Vector4<u8>,
1379    ) -> Result<(), VertexFetchError>;
1380}
1381
1382impl VertexReadTrait for VertexViewMut<'_> {
1383    fn data_layout_ref(&self) -> (&[u8], &[Option<VertexAttribute>]) {
1384        (self.vertex_data, self.sparse_layout)
1385    }
1386}
1387
1388impl VertexWriteTrait for VertexViewMut<'_> {
1389    #[inline(always)]
1390    fn data_layout_mut(&mut self) -> (&mut [u8], &[Option<VertexAttribute>]) {
1391        (self.vertex_data, self.sparse_layout)
1392    }
1393
1394    #[inline(always)]
1395    fn write_2_f32(
1396        &mut self,
1397        usage: VertexAttributeUsage,
1398        value: Vector2<f32>,
1399    ) -> Result<(), VertexFetchError> {
1400        let (data, layout) = self.data_layout_mut();
1401        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1402            LittleEndian::write_f32(&mut data[(attribute.offset as usize)..], value.x);
1403            LittleEndian::write_f32(&mut data[(attribute.offset as usize + 4)..], value.y);
1404            Ok(())
1405        } else {
1406            Err(VertexFetchError::NoSuchAttribute(usage))
1407        }
1408    }
1409
1410    #[inline(always)]
1411    fn write_3_f32(
1412        &mut self,
1413        usage: VertexAttributeUsage,
1414        value: Vector3<f32>,
1415    ) -> Result<(), VertexFetchError> {
1416        let (data, layout) = self.data_layout_mut();
1417        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1418            LittleEndian::write_f32(&mut data[(attribute.offset as usize)..], value.x);
1419            LittleEndian::write_f32(&mut data[(attribute.offset as usize + 4)..], value.y);
1420            LittleEndian::write_f32(&mut data[(attribute.offset as usize + 8)..], value.z);
1421            Ok(())
1422        } else {
1423            Err(VertexFetchError::NoSuchAttribute(usage))
1424        }
1425    }
1426
1427    #[inline(always)]
1428    fn write_4_f32(
1429        &mut self,
1430        usage: VertexAttributeUsage,
1431        value: Vector4<f32>,
1432    ) -> Result<(), VertexFetchError> {
1433        let (data, layout) = self.data_layout_mut();
1434        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1435            LittleEndian::write_f32(&mut data[(attribute.offset as usize)..], value.x);
1436            LittleEndian::write_f32(&mut data[(attribute.offset as usize + 4)..], value.y);
1437            LittleEndian::write_f32(&mut data[(attribute.offset as usize + 8)..], value.z);
1438            LittleEndian::write_f32(&mut data[(attribute.offset as usize + 12)..], value.w);
1439            Ok(())
1440        } else {
1441            Err(VertexFetchError::NoSuchAttribute(usage))
1442        }
1443    }
1444
1445    #[inline(always)]
1446    fn write_4_u8(
1447        &mut self,
1448        usage: VertexAttributeUsage,
1449        value: Vector4<u8>,
1450    ) -> Result<(), VertexFetchError> {
1451        let (data, layout) = self.data_layout_mut();
1452        if let Some(attribute) = layout.get(usage as usize).unwrap() {
1453            data[attribute.offset as usize] = value.x;
1454            data[(attribute.offset + 1) as usize] = value.y;
1455            data[(attribute.offset + 2) as usize] = value.z;
1456            data[(attribute.offset + 3) as usize] = value.w;
1457            Ok(())
1458        } else {
1459            Err(VertexFetchError::NoSuchAttribute(usage))
1460        }
1461    }
1462}
1463
1464/// A buffer for data that defines connections between vertices.
1465#[derive(Reflect, Visit, Default, Clone, Debug)]
1466pub struct TriangleBuffer {
1467    triangles: Vec<TriangleDefinition>,
1468    modifications_counter: u64,
1469}
1470
1471fn calculate_triangle_buffer_hash(triangles: &[TriangleDefinition]) -> u64 {
1472    let mut hasher = FxHasher::default();
1473    triangles.hash(&mut hasher);
1474    hasher.finish()
1475}
1476
1477impl TriangleBuffer {
1478    /// Creates new triangle buffer with given set of triangles.
1479    pub fn new(triangles: Vec<TriangleDefinition>) -> Self {
1480        Self {
1481            triangles,
1482            modifications_counter: 0,
1483        }
1484    }
1485
1486    /// Creates new ref iterator.
1487    pub fn iter(&self) -> impl Iterator<Item = &TriangleDefinition> {
1488        self.triangles.iter()
1489    }
1490
1491    /// Returns a ref to inner data with triangles.
1492    pub fn triangles_ref(&self) -> &[TriangleDefinition] {
1493        &self.triangles
1494    }
1495
1496    /// Sets a new set of triangles.
1497    pub fn set_triangles(&mut self, triangles: Vec<TriangleDefinition>) {
1498        self.triangles = triangles;
1499        self.modifications_counter += 1;
1500    }
1501
1502    /// Returns amount of triangles in the buffer.
1503    pub fn len(&self) -> usize {
1504        self.triangles.len()
1505    }
1506
1507    /// Returns true if the buffer is empty, false - otherwise.
1508    pub fn is_empty(&self) -> bool {
1509        self.triangles.is_empty()
1510    }
1511
1512    /// Returns the total amount of times the buffer was modified.
1513    pub fn modifications_count(&self) -> u64 {
1514        self.modifications_counter
1515    }
1516
1517    /// Calculates inner data hash.
1518    pub fn content_hash(&self) -> u64 {
1519        calculate_triangle_buffer_hash(&self.triangles)
1520    }
1521
1522    /// See VertexBuffer::modify for more info.
1523    pub fn modify(&mut self) -> TriangleBufferRefMut<'_> {
1524        TriangleBufferRefMut {
1525            triangle_buffer: self,
1526        }
1527    }
1528}
1529
1530impl Index<usize> for TriangleBuffer {
1531    type Output = TriangleDefinition;
1532
1533    fn index(&self, index: usize) -> &Self::Output {
1534        &self.triangles[index]
1535    }
1536}
1537
1538/// See VertexBuffer::modify for more info.
1539pub struct TriangleBufferRefMut<'a> {
1540    triangle_buffer: &'a mut TriangleBuffer,
1541}
1542
1543impl Deref for TriangleBufferRefMut<'_> {
1544    type Target = TriangleBuffer;
1545
1546    fn deref(&self) -> &Self::Target {
1547        self.triangle_buffer
1548    }
1549}
1550
1551impl DerefMut for TriangleBufferRefMut<'_> {
1552    fn deref_mut(&mut self) -> &mut Self::Target {
1553        self.triangle_buffer
1554    }
1555}
1556
1557impl Drop for TriangleBufferRefMut<'_> {
1558    fn drop(&mut self) {
1559        self.triangle_buffer.modifications_counter += 1;
1560    }
1561}
1562
1563impl TriangleBufferRefMut<'_> {
1564    /// Returns mutable iterator.
1565    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TriangleDefinition> {
1566        self.triangles.iter_mut()
1567    }
1568
1569    /// Adds new triangle in the buffer.
1570    pub fn push(&mut self, triangle: TriangleDefinition) {
1571        self.triangles.push(triangle)
1572    }
1573
1574    /// Adds triangles from the given iterator to the current buffer. Offsets each triangle by the
1575    /// given `offset` value.
1576    pub fn push_triangles_iter_with_offset(
1577        &mut self,
1578        offset: u32,
1579        triangles: impl Iterator<Item = TriangleDefinition>,
1580    ) {
1581        self.triangles.extend(triangles.map(|t| t.add(offset)))
1582    }
1583
1584    /// Adds triangles from the given slice to the current buffer.
1585    pub fn push_triangles(&mut self, triangles: &[TriangleDefinition]) {
1586        self.triangles.extend_from_slice(triangles)
1587    }
1588
1589    /// Adds triangles from the given iterator to the current buffer.
1590    pub fn push_triangles_iter(&mut self, triangles: impl Iterator<Item = TriangleDefinition>) {
1591        self.triangles.extend(triangles)
1592    }
1593
1594    /// Adds triangles from the given slice to the current buffer. Offsets each triangle by the
1595    /// given `offset` value.
1596    pub fn push_triangles_with_offset(&mut self, offset: u32, triangles: &[TriangleDefinition]) {
1597        self.triangles
1598            .extend(triangles.iter().map(|t| t.add(offset)))
1599    }
1600
1601    /// Clears the buffer.
1602    pub fn clear(&mut self) {
1603        self.triangles.clear();
1604    }
1605}
1606
1607impl Index<usize> for TriangleBufferRefMut<'_> {
1608    type Output = TriangleDefinition;
1609
1610    fn index(&self, index: usize) -> &Self::Output {
1611        &self.triangle_buffer.triangles[index]
1612    }
1613}
1614
1615impl IndexMut<usize> for TriangleBufferRefMut<'_> {
1616    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1617        &mut self.triangle_buffer.triangles[index]
1618    }
1619}
1620
1621/// A typed attribute view for a specific vertex attribute in a vertex buffer.
1622pub struct AttributeViewRef<'a, T> {
1623    ptr: *const u8,
1624    stride: usize,
1625    count: usize,
1626    phantom: PhantomData<&'a T>,
1627}
1628
1629impl<'a, T> AttributeViewRef<'a, T> {
1630    /// Tries to fetch attribute data at the given index.
1631    pub fn get(&'a self, i: usize) -> Option<&'a T> {
1632        if i < self.count {
1633            Some(unsafe { &*((self.ptr.add(i * self.stride)) as *const T) })
1634        } else {
1635            None
1636        }
1637    }
1638}
1639
1640/// A typed attribute view for a specific vertex attribute in a vertex buffer.
1641pub struct AttributeViewRefMut<'a, T> {
1642    ptr: *mut u8,
1643    stride: usize,
1644    count: usize,
1645    phantom: PhantomData<&'a T>,
1646}
1647
1648impl<'a, T> AttributeViewRefMut<'a, T> {
1649    /// Tries to fetch attribute data at the given index.
1650    pub fn get(&'a mut self, i: usize) -> Option<&'a mut T> {
1651        if i < self.count {
1652            Some(unsafe { &mut *((self.ptr.add(i * self.stride)) as *mut T) })
1653        } else {
1654            None
1655        }
1656    }
1657}
1658
1659#[cfg(test)]
1660mod test {
1661    use crate::scene::mesh::buffer::VertexTrait;
1662    use crate::{
1663        core::algebra::{Vector2, Vector3, Vector4},
1664        scene::mesh::buffer::{
1665            VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexBuffer,
1666            VertexReadTrait,
1667        },
1668    };
1669
1670    #[derive(Clone, Copy, PartialEq, Debug)]
1671    #[repr(C)]
1672    struct Vertex {
1673        position: Vector3<f32>,
1674        tex_coord: Vector2<f32>,
1675        second_tex_coord: Vector2<f32>,
1676        normal: Vector3<f32>,
1677        tangent: Vector4<f32>,
1678        bone_weights: Vector4<f32>,
1679        bone_indices: Vector4<u8>,
1680    }
1681
1682    impl VertexTrait for Vertex {
1683        fn layout() -> &'static [VertexAttributeDescriptor] {
1684            static LAYOUT: [VertexAttributeDescriptor; 7] = [
1685                VertexAttributeDescriptor {
1686                    usage: VertexAttributeUsage::Position,
1687                    data_type: VertexAttributeDataType::F32,
1688                    size: 3,
1689                    divisor: 0,
1690                    shader_location: 0,
1691                    normalized: false,
1692                },
1693                VertexAttributeDescriptor {
1694                    usage: VertexAttributeUsage::TexCoord0,
1695                    data_type: VertexAttributeDataType::F32,
1696                    size: 2,
1697                    divisor: 0,
1698                    shader_location: 1,
1699                    normalized: false,
1700                },
1701                VertexAttributeDescriptor {
1702                    usage: VertexAttributeUsage::TexCoord1,
1703                    data_type: VertexAttributeDataType::F32,
1704                    size: 2,
1705                    divisor: 0,
1706                    shader_location: 2,
1707                    normalized: false,
1708                },
1709                VertexAttributeDescriptor {
1710                    usage: VertexAttributeUsage::Normal,
1711                    data_type: VertexAttributeDataType::F32,
1712                    size: 3,
1713                    divisor: 0,
1714                    shader_location: 3,
1715                    normalized: false,
1716                },
1717                VertexAttributeDescriptor {
1718                    usage: VertexAttributeUsage::Tangent,
1719                    data_type: VertexAttributeDataType::F32,
1720                    size: 4,
1721                    divisor: 0,
1722                    shader_location: 4,
1723                    normalized: false,
1724                },
1725                VertexAttributeDescriptor {
1726                    usage: VertexAttributeUsage::BoneWeight,
1727                    data_type: VertexAttributeDataType::F32,
1728                    size: 4,
1729                    divisor: 0,
1730                    shader_location: 5,
1731                    normalized: false,
1732                },
1733                VertexAttributeDescriptor {
1734                    usage: VertexAttributeUsage::BoneIndices,
1735                    data_type: VertexAttributeDataType::U8,
1736                    size: 4,
1737                    divisor: 0,
1738                    shader_location: 6,
1739                    normalized: false,
1740                },
1741            ];
1742
1743            &LAYOUT
1744        }
1745    }
1746
1747    const VERTICES: [Vertex; 3] = [
1748        Vertex {
1749            position: Vector3::new(1.0, 2.0, 3.0),
1750            tex_coord: Vector2::new(0.0, 1.0),
1751            second_tex_coord: Vector2::new(1.0, 0.0),
1752            normal: Vector3::new(0.0, 1.0, 0.0),
1753            tangent: Vector4::new(1.0, 0.0, 0.0, 1.0),
1754            bone_weights: Vector4::new(0.25, 0.25, 0.25, 0.25),
1755            bone_indices: Vector4::new(1, 2, 3, 4),
1756        },
1757        Vertex {
1758            position: Vector3::new(3.0, 2.0, 1.0),
1759            tex_coord: Vector2::new(1.0, 0.0),
1760            second_tex_coord: Vector2::new(1.0, 0.0),
1761            normal: Vector3::new(0.0, 1.0, 0.0),
1762            tangent: Vector4::new(1.0, 0.0, 0.0, 1.0),
1763            bone_weights: Vector4::new(0.25, 0.25, 0.25, 0.25),
1764            bone_indices: Vector4::new(1, 2, 3, 4),
1765        },
1766        Vertex {
1767            position: Vector3::new(1.0, 1.0, 1.0),
1768            tex_coord: Vector2::new(1.0, 1.0),
1769            second_tex_coord: Vector2::new(1.0, 0.0),
1770            normal: Vector3::new(0.0, 1.0, 0.0),
1771            tangent: Vector4::new(1.0, 0.0, 0.0, 1.0),
1772            bone_weights: Vector4::new(0.25, 0.25, 0.25, 0.25),
1773            bone_indices: Vector4::new(1, 2, 3, 4),
1774        },
1775    ];
1776
1777    fn test_view_original_equal<T: VertexReadTrait>(view: T, original: &Vertex) {
1778        assert_eq!(
1779            view.read_3_f32(VertexAttributeUsage::Position).unwrap(),
1780            original.position
1781        );
1782        assert_eq!(
1783            view.read_2_f32(VertexAttributeUsage::TexCoord0).unwrap(),
1784            original.tex_coord
1785        );
1786        assert_eq!(
1787            view.read_2_f32(VertexAttributeUsage::TexCoord1).unwrap(),
1788            original.second_tex_coord
1789        );
1790        assert_eq!(
1791            view.read_3_f32(VertexAttributeUsage::Normal).unwrap(),
1792            original.normal
1793        );
1794        assert_eq!(
1795            view.read_4_f32(VertexAttributeUsage::Tangent).unwrap(),
1796            original.tangent
1797        );
1798        assert_eq!(
1799            view.read_4_f32(VertexAttributeUsage::BoneWeight).unwrap(),
1800            original.bone_weights
1801        );
1802        assert_eq!(
1803            view.read_4_u8(VertexAttributeUsage::BoneIndices).unwrap(),
1804            original.bone_indices
1805        );
1806    }
1807
1808    fn create_test_buffer() -> VertexBuffer {
1809        VertexBuffer::new(VERTICES.len(), VERTICES.to_vec()).unwrap()
1810    }
1811
1812    #[test]
1813    fn test_empty() {
1814        VertexBuffer::new::<Vertex>(0, vec![]).unwrap();
1815    }
1816
1817    #[test]
1818    fn test_iter() {
1819        let buffer = create_test_buffer();
1820
1821        for (view, original) in buffer.iter().zip(VERTICES.iter()) {
1822            test_view_original_equal(view, original);
1823        }
1824    }
1825
1826    #[test]
1827    fn test_iter_mut() {
1828        let mut buffer = create_test_buffer();
1829
1830        for (view, original) in buffer.modify().iter_mut().zip(VERTICES.iter()) {
1831            test_view_original_equal(view, original);
1832        }
1833    }
1834
1835    #[test]
1836    fn test_vertex_duplication() {
1837        let mut buffer = create_test_buffer();
1838
1839        buffer.modify().duplicate(0);
1840
1841        assert_eq!(buffer.vertex_count(), 4);
1842        assert_eq!(buffer.get(0).unwrap(), buffer.get(3).unwrap())
1843    }
1844
1845    #[test]
1846    fn test_pop_vertex() {
1847        let mut buffer = create_test_buffer();
1848
1849        let vertex = buffer.modify().pop_vertex::<Vertex>().unwrap();
1850
1851        assert_eq!(buffer.vertex_count(), 2);
1852        assert_eq!(vertex, VERTICES[2]);
1853    }
1854
1855    #[test]
1856    fn test_remove_last_vertex() {
1857        let mut buffer = create_test_buffer();
1858
1859        buffer.modify().remove_last_vertex();
1860
1861        assert_eq!(buffer.vertex_count(), 2);
1862    }
1863
1864    #[test]
1865    fn test_attribute_view() {
1866        let buffer = create_test_buffer();
1867
1868        let position_view = buffer
1869            .attribute_view::<Vector3<f32>>(VertexAttributeUsage::Position)
1870            .unwrap();
1871
1872        assert_eq!(position_view.get(0), Some(&Vector3::new(1.0, 2.0, 3.0)));
1873        assert_eq!(position_view.get(1), Some(&Vector3::new(3.0, 2.0, 1.0)));
1874        assert_eq!(position_view.get(2), Some(&Vector3::new(1.0, 1.0, 1.0)));
1875
1876        let uv_view = buffer
1877            .attribute_view::<Vector2<f32>>(VertexAttributeUsage::TexCoord0)
1878            .unwrap();
1879
1880        assert_eq!(uv_view.get(0), Some(&Vector2::new(0.0, 1.0)));
1881        assert_eq!(uv_view.get(1), Some(&Vector2::new(1.0, 0.0)));
1882        assert_eq!(uv_view.get(2), Some(&Vector2::new(1.0, 1.0)));
1883    }
1884
1885    #[test]
1886    fn test_add_attribute() {
1887        let mut buffer = create_test_buffer();
1888
1889        let fill = Vector2::new(0.25, 0.75);
1890        let test_index = 1;
1891
1892        buffer
1893            .modify()
1894            .add_attribute(
1895                VertexAttributeDescriptor {
1896                    usage: VertexAttributeUsage::TexCoord2,
1897                    data_type: VertexAttributeDataType::F32,
1898                    size: 2,
1899                    divisor: 0,
1900                    shader_location: 7,
1901                    normalized: false,
1902                },
1903                fill,
1904            )
1905            .unwrap();
1906
1907        #[derive(Clone, Copy, PartialEq, Debug)]
1908        #[repr(C)]
1909        struct ExtendedVertex {
1910            position: Vector3<f32>,
1911            tex_coord: Vector2<f32>,
1912            second_tex_coord: Vector2<f32>,
1913            normal: Vector3<f32>,
1914            tangent: Vector4<f32>,
1915            bone_weights: Vector4<f32>,
1916            bone_indices: Vector4<u8>,
1917            third_tex_coord: Vector2<f32>, // NEW
1918        }
1919
1920        let new_1 = ExtendedVertex {
1921            position: VERTICES[test_index].position,
1922            tex_coord: VERTICES[test_index].tex_coord,
1923            second_tex_coord: VERTICES[test_index].second_tex_coord,
1924            normal: VERTICES[test_index].normal,
1925            tangent: VERTICES[test_index].tangent,
1926            bone_weights: VERTICES[test_index].bone_weights,
1927            bone_indices: VERTICES[test_index].bone_indices,
1928            third_tex_coord: fill,
1929        };
1930
1931        assert_eq!(
1932            buffer.vertex_size,
1933            std::mem::size_of::<ExtendedVertex>() as u8
1934        );
1935        let view = buffer.get(test_index).unwrap();
1936        assert_eq!(
1937            view.read_3_f32(VertexAttributeUsage::Position).unwrap(),
1938            new_1.position
1939        );
1940        assert_eq!(
1941            view.read_2_f32(VertexAttributeUsage::TexCoord0).unwrap(),
1942            new_1.tex_coord
1943        );
1944        assert_eq!(
1945            view.read_2_f32(VertexAttributeUsage::TexCoord1).unwrap(),
1946            new_1.second_tex_coord
1947        );
1948        assert_eq!(
1949            view.read_2_f32(VertexAttributeUsage::TexCoord2).unwrap(),
1950            new_1.third_tex_coord
1951        );
1952        assert_eq!(
1953            view.read_3_f32(VertexAttributeUsage::Normal).unwrap(),
1954            new_1.normal
1955        );
1956        assert_eq!(
1957            view.read_4_f32(VertexAttributeUsage::Tangent).unwrap(),
1958            new_1.tangent
1959        );
1960        assert_eq!(
1961            view.read_4_f32(VertexAttributeUsage::BoneWeight).unwrap(),
1962            new_1.bone_weights
1963        );
1964        assert_eq!(
1965            view.read_4_u8(VertexAttributeUsage::BoneIndices).unwrap(),
1966            new_1.bone_indices
1967        );
1968    }
1969}