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)]
60pub enum VertexAttributeDataType {
61    /// 32-bit floating-point.
62    F32,
63    /// 32-bit unsigned integer.
64    U32,
65    /// 16-bit unsigned integer.
66    U16,
67    /// 8-bit unsigned integer.
68    U8,
69}
70
71impl Default for VertexAttributeDataType {
72    fn default() -> Self {
73        Self::F32
74    }
75}
76
77impl VertexAttributeDataType {
78    /// Returns size of data in bytes.
79    pub fn size(self) -> u8 {
80        match self {
81            VertexAttributeDataType::F32 | VertexAttributeDataType::U32 => 4,
82            VertexAttributeDataType::U16 => 2,
83            VertexAttributeDataType::U8 => 1,
84        }
85    }
86}
87
88/// An usage for vertex attribute. It is a fixed set, but there are plenty
89/// room for any custom data - it may be fit into `TexCoordN` attributes.
90#[derive(Reflect, Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Visit, Debug)]
91#[repr(u32)]
92pub enum VertexAttributeUsage {
93    /// Vertex position. Usually `Vector2<f32>` or `Vector3<f32>`.
94    Position = 0,
95    /// Vertex normal. Usually `Vector3<f32>`, more rare `Vector3<u16>` (F16).
96    Normal = 1,
97    /// Vertex tangent. Usually `Vector3<f32>`.
98    Tangent = 2,
99    /// First texture coordinates. Usually `Vector2<f32>`.
100    /// It may be used for everything else, not only for texture coordinates.
101    TexCoord0 = 3,
102    /// Second texture coordinates.
103    TexCoord1 = 4,
104    /// Third texture coordinates.
105    TexCoord2 = 5,
106    /// Fourth texture coordinates.
107    TexCoord3 = 6,
108    /// Fifth texture coordinates.
109    TexCoord4 = 7,
110    /// Sixth texture coordinates.
111    TexCoord5 = 8,
112    /// Seventh texture coordinates.
113    TexCoord6 = 9,
114    /// Eighth texture coordinates.
115    TexCoord7 = 10,
116    /// Bone weights. Usually `Vector4<f32>`.
117    BoneWeight = 11,
118    /// Bone indices. Usually `Vector4<u8>`.
119    BoneIndices = 12,
120    /// Color. Usually `Vector4<u8>`.
121    Color = 13,
122    /// First custom attribute with arbitrary, context-dependent meaning.
123    Custom0 = 14,
124    /// Second custom attribute with arbitrary, context-dependent meaning.
125    Custom1 = 15,
126    /// Third custom attribute with arbitrary, context-dependent meaning.
127    Custom2 = 16,
128    /// Fourth custom attribute with arbitrary, context-dependent meaning.
129    Custom3 = 17,
130    /// Fifth custom attribute with arbitrary, context-dependent meaning.
131    Custom4 = 18,
132    /// Sixth custom attribute with arbitrary, context-dependent meaning.
133    Custom5 = 19,
134    /// Seventh custom attribute with arbitrary, context-dependent meaning.
135    Custom6 = 20,
136    /// Eigth custom attribute with arbitrary, context-dependent meaning.
137    Custom7 = 21,
138    /// Maximum amount of attribute kinds.
139    Count,
140}
141
142impl Default for VertexAttributeUsage {
143    fn default() -> Self {
144        Self::Position
145    }
146}
147
148/// Input vertex attribute descriptor used to construct layouts and feed vertex buffer.
149#[derive(Debug, Hash)]
150pub struct VertexAttributeDescriptor {
151    /// Claimed usage of the attribute. It could be Position, Normal, etc.
152    pub usage: VertexAttributeUsage,
153    /// Data type of every component of the attribute. It could be F32, U32, U16, etc.
154    pub data_type: VertexAttributeDataType,
155    /// Size of attribute expressed in components. For example, for `Position` it could
156    /// be 3 - which means there are 3 components in attribute of `data_type`.
157    pub size: u8,
158    /// Sets a "fetch rate" for vertex shader at which it will read vertex attribute:
159    ///  0 - per vertex (default)
160    ///  1 - per instance
161    ///  2 - per 2 instances and so on.
162    pub divisor: u8,
163    /// Defines location of the attribute in a shader (`layout(location = x) attrib;`)
164    pub shader_location: u8,
165    /// Whether the attribute values should be normalized into `0.0..1.0` range or not.
166    /// If this field is set to `false`, then the numbers will appear "as-is" when fetching
167    /// them in a shader. On the other hand, if it is `true`, then any numeric value will be
168    /// normalized by applying `normalized = num / T::max()` equation. This way all numbers will
169    /// always stay in `0.0..1.0` range.
170    ///
171    /// For example, normalization could be useful for RGB colors that expressed as three bytes (u8).
172    /// In this case normalization will turn the color into `0.0..1.0` range.  
173    pub normalized: bool,
174}
175
176/// Vertex attribute is a simple "bridge" between raw data and its interpretation. In
177/// other words it defines how to treat raw data in vertex shader.
178#[derive(Reflect, Visit, Copy, Clone, Default, Debug, Hash)]
179pub struct VertexAttribute {
180    /// Claimed usage of the attribute. It could be Position, Normal, etc.
181    pub usage: VertexAttributeUsage,
182    /// Data type of every component of the attribute. It could be F32, U32, U16, etc.
183    pub data_type: VertexAttributeDataType,
184    /// Size of attribute expressed in components. For example, for `Position` it could
185    /// be 3 - which means there are 3 components in attribute of `data_type`.
186    pub size: u8,
187    /// Sets a "fetch rate" for vertex shader at which it will read vertex attribute:
188    ///  0 - per vertex (default)
189    ///  1 - per instance
190    ///  2 - per 2 instances and so on.
191    pub divisor: u8,
192    /// Offset in bytes from beginning of the vertex.
193    pub offset: u8,
194    /// Defines location of the attribute in a shader (`layout(location = x) attrib;`)
195    pub shader_location: u8,
196    /// Whether the attribute values should be normalized into `0.0..1.0` range or not.
197    /// If this field is set to `false`, then the numbers will appear "as-is" when fetching
198    /// them in a shader. On the other hand, if it is `true`, then any numeric value will be
199    /// normalized by applying `normalized = num / T::max()` equation. This way all numbers will
200    /// always stay in `0.0..1.0` range.
201    ///
202    /// For example, normalization could be useful for RGB colors that expressed as three bytes (u8).
203    /// In this case normalization will turn the color into `0.0..1.0` range.  
204    #[visit(optional)]
205    pub normalized: bool,
206}
207
208/// Bytes storage of a vertex buffer.
209#[derive(Reflect, Clone, Debug)]
210pub struct BytesStorage {
211    bytes: Vec<u8>,
212    #[reflect(hidden)]
213    layout: Layout,
214}
215
216impl Visit for BytesStorage {
217    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
218        let mut bytes_adapter = PodVecView::from_pod_vec(&mut self.bytes);
219        if bytes_adapter.visit(name, visitor).is_err() {
220            let mut bytes = Vec::<u8>::new();
221            bytes.visit(name, visitor)?;
222            self.bytes = bytes;
223        }
224
225        if visitor.is_reading() {
226            self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
227        }
228        Ok(())
229    }
230}
231
232impl Default for BytesStorage {
233    fn default() -> Self {
234        Self {
235            bytes: Default::default(),
236            layout: Layout::array::<u8>(0).unwrap(),
237        }
238    }
239}
240
241impl BytesStorage {
242    /// Creates new empty bytes storage with the given capacity.
243    pub fn with_capacity(capacity: usize) -> Self {
244        Self {
245            bytes: Vec::with_capacity(capacity),
246            layout: Layout::array::<u8>(capacity).unwrap(),
247        }
248    }
249
250    /// Creates new bytes storage from the given data buffer.
251    pub fn new<T>(data: Vec<T>) -> Self {
252        // Prevent destructor to be called on `data`, this is needed because we're taking its
253        // data storage and treat it as a simple bytes block.
254        let mut data = std::mem::ManuallyDrop::new(data);
255        let bytes_length = data.len() * std::mem::size_of::<T>();
256        let bytes_capacity = data.capacity() * std::mem::size_of::<T>();
257        Self {
258            bytes: unsafe {
259                Vec::<u8>::from_raw_parts(
260                    data.as_mut_ptr() as *mut u8,
261                    bytes_length,
262                    bytes_capacity,
263                )
264            },
265            // Preserve initial memory layout, to ensure that the memory block will be deallocated
266            // with initial memory layout.
267            layout: Layout::array::<T>(data.capacity()).unwrap(),
268        }
269    }
270
271    fn extend_from_slice(&mut self, slice: &[u8]) {
272        if self.layout.align() != 1 {
273            // Realloc backing storage manually if the alignment is anything else than 1.
274            let new_storage = Vec::with_capacity(self.bytes.len());
275            let old_storage = std::mem::replace(&mut self.bytes, new_storage);
276            self.bytes.extend_from_slice(old_storage.as_slice());
277            self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
278        }
279        self.bytes.extend_from_slice(slice);
280        self.layout = Layout::array::<u8>(self.bytes.capacity()).unwrap();
281    }
282
283    fn drain<R>(&mut self, range: R) -> Drain<'_, u8>
284    where
285        R: RangeBounds<usize>,
286    {
287        self.bytes.drain(range)
288    }
289
290    fn as_mut_ptr(&mut self) -> *mut u8 {
291        self.bytes.as_mut_ptr()
292    }
293
294    fn as_slice_mut(&mut self) -> &mut [u8] {
295        self.bytes.as_mut_slice()
296    }
297
298    fn clear(&mut self) {
299        self.bytes.clear()
300    }
301}
302
303impl Drop for BytesStorage {
304    fn drop(&mut self) {
305        let mut bytes = std::mem::ManuallyDrop::new(std::mem::take(&mut self.bytes));
306        // Dealloc manually with initial memory layout.
307        if bytes.capacity() != 0 {
308            unsafe { std::alloc::dealloc(bytes.as_mut_ptr(), self.layout) }
309        }
310    }
311}
312
313impl Deref for BytesStorage {
314    type Target = Vec<u8>;
315
316    fn deref(&self) -> &Self::Target {
317        &self.bytes
318    }
319}
320
321/// Vertex buffer with dynamic layout. It is used to store multiple vertices of a single type, that implements [`VertexTrait`].
322/// Different vertex types used to for efficient memory usage. For example, you could have a simple vertex with only position
323/// expressed as Vector3 and it will be enough for simple cases, when only position is required. However, if you want to draw
324/// a mesh with skeletal animation, that also supports texturing, lighting, you need to provide a lot more data (bone indices,
325/// bone weights, normals, tangents, texture coordinates).
326///
327/// ## Examples
328///
329/// ```rust
330/// # use fyrox_impl::{
331/// #     core::algebra::Vector3,
332/// #     scene::mesh::buffer::{
333/// #         VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexBuffer,
334/// #         VertexTrait,
335/// #     },
336/// # };
337/// #
338/// #[derive(Copy, Clone)]
339/// #[repr(C)]
340/// struct MyVertex {
341///     position: Vector3<f32>,
342/// }
343///
344/// impl VertexTrait for MyVertex {
345///     fn layout() -> &'static [VertexAttributeDescriptor] {
346///         &[VertexAttributeDescriptor {
347///             usage: VertexAttributeUsage::Position,
348///             data_type: VertexAttributeDataType::F32,
349///             size: 3,
350///             divisor: 0,
351///             shader_location: 0,
352///             normalized: false
353///         }]
354///     }
355/// }
356///
357/// fn create_triangle_vertex_buffer() -> VertexBuffer {
358///     VertexBuffer::new(
359///         3,
360///         vec![
361///             MyVertex {
362///                 position: Vector3::new(0.0, 0.0, 0.0),
363///             },
364///             MyVertex {
365///                 position: Vector3::new(0.0, 1.0, 0.0),
366///             },
367///             MyVertex {
368///                 position: Vector3::new(1.0, 1.0, 0.0),
369///             },
370///         ],
371///     )
372///     .unwrap()
373/// }  
374/// ```
375///
376/// This example creates a simple vertex buffer that contains a single triangle with custom vertex format. The most important
377/// part here is [`VertexTrait::layout`] implementation - it describes each "attribute" of your vertex, if your layout does not
378/// match the actual content of the vertex (in terms of size in bytes), then vertex buffer cannot be created and [`VertexBuffer::new`]
379/// will return [`None`].
380///
381/// The second, but not least important is `#[repr(C)]` attribute - it is mandatory for every vertex type, it forbids fields
382/// reordering of you vertex structure and guarantees that they will have the same layout in memory as their declaration order.
383///
384/// ## Limitations
385///
386/// Vertex size cannot be more than 256 bytes, this limitation shouldn't be a problem because almost every GPU supports up to
387/// 16 vertex attributes with 16 bytes of size each, which gives exactly 256 bytes.
388#[derive(Reflect, Clone, Visit, Default, Debug)]
389pub struct VertexBuffer {
390    dense_layout: Vec<VertexAttribute>,
391    sparse_layout: [Option<VertexAttribute>; VertexAttributeUsage::Count as usize],
392    vertex_size: u8,
393    vertex_count: u32,
394    data: BytesStorage,
395    #[visit(optional)]
396    layout_hash: u64,
397    #[visit(optional)]
398    modifications_counter: u64,
399}
400
401fn calculate_layout_hash(layout: &[VertexAttribute]) -> u64 {
402    let mut hasher = FxHasher::default();
403    layout.hash(&mut hasher);
404    hasher.finish()
405}
406
407fn calculate_data_hash(data: &[u8]) -> u64 {
408    let mut hasher = FxHasher::default();
409    data.hash(&mut hasher);
410    hasher.finish()
411}
412
413/// See VertexBuffer::modify for more info.
414pub struct VertexBufferRefMut<'a> {
415    vertex_buffer: &'a mut VertexBuffer,
416}
417
418impl Drop for VertexBufferRefMut<'_> {
419    fn drop(&mut self) {
420        self.vertex_buffer.modifications_counter += 1;
421    }
422}
423
424impl Deref for VertexBufferRefMut<'_> {
425    type Target = VertexBuffer;
426
427    fn deref(&self) -> &Self::Target {
428        self.vertex_buffer
429    }
430}
431
432impl DerefMut for VertexBufferRefMut<'_> {
433    fn deref_mut(&mut self) -> &mut Self::Target {
434        self.vertex_buffer
435    }
436}
437
438impl VertexBufferRefMut<'_> {
439    /// Tries to append a vertex to the buffer.
440    ///
441    /// # Safety and validation
442    ///
443    /// This method accepts any type that has appropriate size, the size must be equal
444    /// with the size defined by layout. The Copy trait bound is required to ensure that
445    /// the type does not have any custom destructors.
446    pub fn push_vertex<T>(&mut self, vertex: &T) -> Result<(), ValidationError>
447    where
448        T: VertexTrait + bytemuck::Pod,
449    {
450        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
451            self.vertex_buffer
452                .data
453                .extend_from_slice(value_as_u8_slice(vertex));
454            self.vertex_buffer.vertex_count += 1;
455            Ok(())
456        } else {
457            Err(ValidationError::InvalidVertexSize {
458                expected: self.vertex_buffer.vertex_size,
459                actual: std::mem::size_of::<T>() as u8,
460            })
461        }
462    }
463
464    /// Tries to append a slice of vertices to the buffer.
465    ///
466    /// # Safety and validation
467    ///
468    /// This method accepts any type that has appropriate size, the size must be equal
469    /// with the size defined by layout. The Copy trait bound is required to ensure that
470    /// the type does not have any custom destructors.
471    pub fn push_vertices<T>(&mut self, vertices: &[T]) -> Result<(), ValidationError>
472    where
473        T: VertexTrait + Pod,
474    {
475        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
476            self.vertex_buffer
477                .data
478                .extend_from_slice(array_as_u8_slice(vertices));
479            self.vertex_buffer.vertex_count += vertices.len() as u32;
480            Ok(())
481        } else {
482            Err(ValidationError::InvalidVertexSize {
483                expected: self.vertex_buffer.vertex_size,
484                actual: std::mem::size_of::<T>() as u8,
485            })
486        }
487    }
488
489    /// Tries to append a raw vertex data to the vertex buffer. This method will fail if the `data`
490    /// size does not match the vertex size of the buffer.
491    pub fn push_vertex_raw(&mut self, data: &[u8]) -> Result<(), ValidationError> {
492        if data.len() == self.vertex_buffer.vertex_size as usize {
493            self.vertex_buffer.data.extend_from_slice(data);
494            self.vertex_buffer.vertex_count += 1;
495            Ok(())
496        } else {
497            Err(ValidationError::InvalidVertexSize {
498                expected: self.vertex_buffer.vertex_size,
499                actual: data.len() as u8,
500            })
501        }
502    }
503
504    /// Tries to append the vertices that the given iterator produces.
505    ///
506    /// # Safety and validation
507    ///
508    /// This method accepts any type that has appropriate size, the size must be equal
509    /// with the size defined by layout. The Copy trait bound is required to ensure that
510    /// the type does not have any custom destructors.
511    pub fn push_vertices_iter<T>(
512        &mut self,
513        vertices: impl Iterator<Item = T>,
514    ) -> Result<(), ValidationError>
515    where
516        T: VertexTrait + Pod,
517    {
518        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
519            for vertex in vertices {
520                self.vertex_buffer
521                    .data
522                    .extend_from_slice(value_as_u8_slice(&vertex));
523                self.vertex_buffer.vertex_count += 1;
524            }
525            Ok(())
526        } else {
527            Err(ValidationError::InvalidVertexSize {
528                expected: self.vertex_buffer.vertex_size,
529                actual: std::mem::size_of::<T>() as u8,
530            })
531        }
532    }
533
534    /// Tries to append a slice of vertices to the buffer. Each vertex will be transformed using
535    /// `transformer` callback.
536    ///
537    /// # Safety and validation
538    ///
539    /// This method accepts any type that has appropriate size, the size must be equal
540    /// with the size defined by layout. The Copy trait bound is required to ensure that
541    /// the type does not have any custom destructors.
542    pub fn push_vertices_transform<T, F>(
543        &mut self,
544        vertices: &[T],
545        mut transformer: F,
546    ) -> Result<(), ValidationError>
547    where
548        T: VertexTrait + Pod,
549        F: FnMut(&T) -> T,
550    {
551        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
552            for vertex in vertices {
553                let transformed = transformer(vertex);
554
555                self.vertex_buffer
556                    .data
557                    .extend_from_slice(value_as_u8_slice(&transformed));
558            }
559            self.vertex_buffer.vertex_count += vertices.len() as u32;
560            Ok(())
561        } else {
562            Err(ValidationError::InvalidVertexSize {
563                expected: self.vertex_buffer.vertex_size,
564                actual: std::mem::size_of::<T>() as u8,
565            })
566        }
567    }
568
569    /// Removes last vertex from the buffer.
570    pub fn remove_last_vertex(&mut self) {
571        let range = (self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize)..;
572        self.vertex_buffer.data.drain(range);
573        self.vertex_buffer.vertex_count -= 1;
574    }
575
576    /// Copies data of last vertex from the buffer to an instance of variable of a type.
577    ///
578    /// # Safety and validation
579    ///
580    /// This method accepts any type that has appropriate size, the size must be equal
581    /// with the size defined by layout. The Copy trait bound is required to ensure that
582    /// the type does not have any custom destructors.
583    pub fn pop_vertex<T>(&mut self) -> Result<T, ValidationError>
584    where
585        T: VertexTrait,
586    {
587        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize
588            && self.vertex_buffer.data.len() >= self.vertex_buffer.vertex_size as usize
589        {
590            unsafe {
591                let mut v = MaybeUninit::<T>::uninit();
592                std::ptr::copy_nonoverlapping(
593                    self.vertex_buffer.data.as_ptr().add(
594                        self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize,
595                    ),
596                    v.as_mut_ptr() as *mut u8,
597                    self.vertex_buffer.vertex_size as usize,
598                );
599                let range =
600                    (self.vertex_buffer.data.len() - self.vertex_buffer.vertex_size as usize)..;
601                self.vertex_buffer.data.drain(range);
602                self.vertex_buffer.vertex_count -= 1;
603                Ok(v.assume_init())
604            }
605        } else {
606            Err(ValidationError::InvalidVertexSize {
607                expected: self.vertex_buffer.vertex_size,
608                actual: std::mem::size_of::<T>() as u8,
609            })
610        }
611    }
612
613    /// Tries to cast internal data buffer to a slice of given type. It may fail if
614    /// size of type is not equal with claimed size (which is set by the layout).
615    pub fn cast_data_mut<T>(&mut self) -> Result<&mut [T], ValidationError>
616    where
617        T: VertexTrait,
618    {
619        if std::mem::size_of::<T>() == self.vertex_buffer.vertex_size as usize {
620            Ok(unsafe {
621                std::slice::from_raw_parts_mut(
622                    self.vertex_buffer.data.as_mut_ptr() as *const T as *mut T,
623                    self.vertex_buffer.data.len() / std::mem::size_of::<T>(),
624                )
625            })
626        } else {
627            Err(ValidationError::InvalidVertexSize {
628                expected: self.vertex_buffer.vertex_size,
629                actual: std::mem::size_of::<T>() as u8,
630            })
631        }
632    }
633
634    /// Creates iterator that emits read/write accessors for vertices.
635    pub fn iter_mut(&mut self) -> impl Iterator<Item = VertexViewMut<'_>> + '_ {
636        unsafe {
637            VertexViewMutIterator {
638                ptr: self.vertex_buffer.data.as_mut_ptr(),
639                end: self.data.as_mut_ptr().add(
640                    self.vertex_buffer.vertex_size as usize
641                        * self.vertex_buffer.vertex_count as usize,
642                ),
643                vertex_size: self.vertex_buffer.vertex_size,
644                sparse_layout: &self.vertex_buffer.sparse_layout,
645                marker: PhantomData,
646            }
647        }
648    }
649
650    /// Returns a read/write accessor of n-th vertex.
651    pub fn get_mut(&mut self, n: usize) -> Option<VertexViewMut<'_>> {
652        let offset = n * self.vertex_buffer.vertex_size as usize;
653        if offset < self.vertex_buffer.data.len() {
654            Some(VertexViewMut {
655                vertex_data: &mut self.vertex_buffer.data.as_slice_mut()
656                    [offset..(offset + self.vertex_buffer.vertex_size as usize)],
657                sparse_layout: &self.vertex_buffer.sparse_layout,
658            })
659        } else {
660            None
661        }
662    }
663
664    /// Duplicates n-th vertex and puts it at the back of the buffer.
665    pub fn duplicate(&mut self, n: usize) {
666        // Vertex cannot be larger than 256 bytes, so having temporary array of
667        // such size is ok.
668        let mut temp = ArrayVec::<u8, 256>::new();
669        temp.try_extend_from_slice(
670            &self.vertex_buffer.data[(n * self.vertex_buffer.vertex_size as usize)
671                ..((n + 1) * self.vertex_buffer.vertex_size as usize)],
672        )
673        .unwrap();
674        self.vertex_buffer.data.extend_from_slice(temp.as_slice());
675        self.vertex_buffer.vertex_count += 1;
676    }
677
678    /// Adds new attribute at the end of layout, reorganizes internal data storage to be
679    /// able to contain new attribute. Default value of the new attribute in the buffer
680    /// becomes `fill_value`. Graphically this could be represented like so:
681    ///
682    /// Add secondary texture coordinates:
683    ///  Before: P1_N1_TC1_P2_N2_TC2...
684    ///  After: P1_N1_TC1_TC2(fill_value)_P2_N2_TC2_TC2(fill_value)...
685    pub fn add_attribute<T>(
686        &mut self,
687        descriptor: VertexAttributeDescriptor,
688        fill_value: T,
689    ) -> Result<(), ValidationError>
690    where
691        T: Copy + Pod,
692    {
693        if self.vertex_buffer.sparse_layout[descriptor.usage as usize].is_some() {
694            Err(ValidationError::DuplicatedAttributeDescriptor)
695        } else {
696            let vertex_attribute = VertexAttribute {
697                usage: descriptor.usage,
698                data_type: descriptor.data_type,
699                size: descriptor.size,
700                divisor: descriptor.divisor,
701                offset: self.vertex_buffer.vertex_size,
702                shader_location: descriptor.shader_location,
703                normalized: descriptor.normalized,
704            };
705            self.vertex_buffer.sparse_layout[descriptor.usage as usize] = Some(vertex_attribute);
706            self.vertex_buffer.dense_layout.push(vertex_attribute);
707
708            self.layout_hash = calculate_layout_hash(&self.vertex_buffer.dense_layout);
709
710            let mut new_data = Vec::new();
711
712            for chunk in self
713                .vertex_buffer
714                .data
715                .chunks_exact(self.vertex_buffer.vertex_size as usize)
716            {
717                let mut temp = ArrayVec::<u8, 256>::new();
718                temp.try_extend_from_slice(chunk).unwrap();
719                temp.try_extend_from_slice(value_as_u8_slice(&fill_value))
720                    .unwrap();
721                new_data.extend_from_slice(&temp);
722            }
723
724            self.vertex_buffer.data = BytesStorage::new(new_data);
725
726            self.vertex_buffer.vertex_size += std::mem::size_of::<T>() as u8;
727
728            Ok(())
729        }
730    }
731
732    /// Clears the buffer making it empty.
733    pub fn clear(&mut self) {
734        self.data.clear();
735        self.vertex_count = 0;
736    }
737}
738
739/// An error that may occur during input data and layout validation.
740#[derive(Debug)]
741pub enum ValidationError {
742    /// Attribute size must be either 1, 2, 3 or 4.
743    InvalidAttributeSize(usize),
744
745    /// Data size is not correct.
746    InvalidDataSize {
747        /// Expected data size in bytes.
748        expected: usize,
749        /// Actual data size in bytes.
750        actual: usize,
751    },
752
753    /// Trying to add vertex of incorrect size.
754    InvalidVertexSize {
755        /// Expected vertex size.
756        expected: u8,
757        /// Actual vertex size.
758        actual: u8,
759    },
760
761    /// A duplicate of a descriptor was found.
762    DuplicatedAttributeDescriptor,
763
764    /// Duplicate shader locations were found.
765    ConflictingShaderLocations(usize),
766}
767
768impl Display for ValidationError {
769    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
770        match self {
771            ValidationError::InvalidAttributeSize(v) => {
772                write!(f, "Invalid attribute size {v}. Must be either 1, 2, 3 or 4")
773            }
774            ValidationError::InvalidDataSize { expected, actual } => {
775                write!(f, "Invalid data size. Expected {expected}, got {actual}.")
776            }
777            ValidationError::InvalidVertexSize { expected, actual } => {
778                write!(f, "Invalid vertex size. Expected {expected}, got {actual}.",)
779            }
780            ValidationError::DuplicatedAttributeDescriptor => {
781                write!(f, "A duplicate of a descriptor was found.")
782            }
783            ValidationError::ConflictingShaderLocations(v) => {
784                write!(f, "Duplicate shader locations were found {v}.")
785            }
786        }
787    }
788}
789
790impl VertexBuffer {
791    /// Creates new vertex buffer from provided data and with the given layout of the vertex type `T`.
792    pub fn new<T>(vertex_count: usize, data: Vec<T>) -> Result<Self, ValidationError>
793    where
794        T: VertexTrait,
795    {
796        Self::new_with_layout(T::layout(), vertex_count, BytesStorage::new(data))
797    }
798
799    /// Creates new vertex buffer from the given layout, vertex count and bytes storage.
800    pub fn new_with_layout(
801        layout: &[VertexAttributeDescriptor],
802        vertex_count: usize,
803        bytes: BytesStorage,
804    ) -> Result<Self, ValidationError> {
805        // Validate for duplicates and invalid layout.
806        for descriptor in layout {
807            for other_descriptor in layout {
808                if !std::ptr::eq(descriptor, other_descriptor) {
809                    if descriptor.usage == other_descriptor.usage {
810                        return Err(ValidationError::DuplicatedAttributeDescriptor);
811                    } else if descriptor.shader_location == other_descriptor.shader_location {
812                        return Err(ValidationError::ConflictingShaderLocations(
813                            descriptor.shader_location as usize,
814                        ));
815                    }
816                }
817            }
818        }
819
820        let mut dense_layout = Vec::new();
821
822        // Validate everything as much as possible and calculate vertex size.
823        let mut sparse_layout = [None; VertexAttributeUsage::Count as usize];
824        let mut vertex_size_bytes = 0u8;
825        for attribute in layout.iter() {
826            if attribute.size < 1 || attribute.size > 4 {
827                return Err(ValidationError::InvalidAttributeSize(
828                    attribute.size as usize,
829                ));
830            }
831
832            let vertex_attribute = VertexAttribute {
833                usage: attribute.usage,
834                data_type: attribute.data_type,
835                size: attribute.size,
836                divisor: attribute.divisor,
837                offset: vertex_size_bytes,
838                shader_location: attribute.shader_location,
839                normalized: attribute.normalized,
840            };
841
842            dense_layout.push(vertex_attribute);
843
844            // Map dense to sparse layout to increase performance.
845            sparse_layout[attribute.usage as usize] = Some(vertex_attribute);
846
847            vertex_size_bytes += attribute.size * attribute.data_type.size();
848        }
849
850        let expected_data_size = vertex_count * vertex_size_bytes as usize;
851        if expected_data_size != bytes.len() {
852            return Err(ValidationError::InvalidDataSize {
853                expected: expected_data_size,
854                actual: bytes.len(),
855            });
856        }
857
858        Ok(Self {
859            vertex_size: vertex_size_bytes,
860            vertex_count: vertex_count as u32,
861            modifications_counter: 0,
862            data: bytes,
863            layout_hash: calculate_layout_hash(&dense_layout),
864            sparse_layout,
865            dense_layout,
866        })
867    }
868
869    /// Creates a new empty vertex buffer with the same layout and vertex size, but with an empty
870    /// inner buffer of the specified capacity.  
871    pub fn clone_empty(&self, capacity: usize) -> Self {
872        Self {
873            dense_layout: self.dense_layout.clone(),
874            sparse_layout: self.sparse_layout,
875            vertex_size: self.vertex_size,
876            vertex_count: 0,
877            data: BytesStorage::with_capacity(capacity),
878            layout_hash: self.layout_hash,
879            modifications_counter: 0,
880        }
881    }
882
883    /// Returns a reference to underlying data buffer slice.
884    pub fn raw_data(&self) -> &[u8] {
885        &self.data
886    }
887
888    /// Returns true if buffer does not contain any vertex, false - otherwise.
889    pub fn is_empty(&self) -> bool {
890        self.vertex_count == 0
891    }
892
893    /// Returns the total amount of times the buffer was modified.
894    pub fn modifications_count(&self) -> u64 {
895        self.modifications_counter
896    }
897
898    /// Calculates inner data hash.
899    pub fn content_hash(&self) -> u64 {
900        calculate_data_hash(&self.data.bytes)
901    }
902
903    /// Returns hash of vertex buffer layout. Cached value is guaranteed to be in actual state.
904    /// The hash could be used to check if the layout has changed.
905    pub fn layout_hash(&self) -> u64 {
906        self.layout_hash
907    }
908
909    /// Provides mutable access to content of the buffer.
910    ///
911    /// # Performance
912    ///
913    /// This method returns a special structure which has custom destructor that increases use
914    /// counter of the data once modification is over. You **must** hold this structure as long as
915    /// possible while modifying the contents of the buffer. 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 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 to notify the GPU that the content has
952    /// changed and must be re-uploaded to the GPU.
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 mut 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}