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