fn check_load_accessors(&mut self) -> Result<(), ModelError> {
        // check each accessor to see if it is sparse
        for accessor in &self.gltf.accessors {
            let sparse = match &accessor.sparse {
                Some(s) => s,
                _ => continue,
            };

            // there isn't always a buffer view, if not present a buffer of
            // zeros should be created to apply the sparse accessor to, so create
            // a new buffer view and buffer to store this new data
            let buffer_view = match accessor.buffer_view {
                Some(idx) => idx,
                None => {
                    let size = accessor.component_type.size()
                        * accessor.r#type.component_count()
                        * accessor.count;
                    self.buffers.push(Buffer {
                        data: vec![0; size],
                    });

                    let view = gltf::BufferView {
                        buffer: self.buffers.len() - 1,
                        byte_length: size,
                        byte_stride: None,
                        byte_offset: 0,
                        extensions: HashMap::default(),
                        extras: serde_json::Value::Null,
                        name: None,
                        target: None,
                    };

                    self.gltf.buffer_views.push(view);

                    self.gltf.buffer_views.len() - 1
                }
            };

            let value_size = accessor.component_type.size() * accessor.r#type.component_count();

            // get the indicies buffer view, then offset it with the infomation
            // from the sparse accessor offsetting the data
            let indicies = self.buffer_data(sparse.indices.buffer_view)?;
            let indicies = indicies
                .get(
                    sparse.indices.byte_offset
                        ..(sparse.indices.byte_offset
                            + sparse.count * sparse.indices.component_type.size()),
                )
                .ok_or(ModelError::BadIndex {
                    array: "Sparse indicies",
                    got: sparse.indices.byte_offset + sparse.count,
                    max: indicies.len(),
                })?
                .to_owned();

            // get the valaues buffer view, then offset it with the infomation
            // from the sparse accessor offsetting the data
            let values = self.buffer_data(sparse.values.buffer_view)?.to_owned();
            let values = values
                .get(
                    sparse.values.byte_offset
                        ..(sparse.values.byte_offset + sparse.count * value_size),
                )
                .ok_or(ModelError::BadIndex {
                    array: "Sparse values",
                    got: sparse.values.byte_offset + sparse.count,
                    max: indicies.len(),
                })?
                .to_owned();

            // get the mutable data to be edited from the model
            let data =
                Self::buffer_data_mut(&self.gltf.buffer_views, &mut self.buffers, buffer_view)?;
            let data_len = data.len();

            // get the relevant portion of the data buffer
            let data = data
                .get_mut(accessor.byte_offset..(accessor.byte_offset + accessor.count * value_size))
                .ok_or(ModelError::BadIndex {
                    array: "Sparse accessor data",
                    got: accessor.byte_offset + accessor.count,
                    max: data_len,
                })?;

            // get the stride, if it is not present, assume the stride is the same
            // as the value size.  If the code has run to this point, it
            // is gauranteed that the relavant buffer view exists so don't
            // need to check the access.
            let stride = if let Some(v) = self.gltf.buffer_views[buffer_view].byte_stride {
                v as usize
            } else {
                value_size
            };

            // macro to simplify generating the acessor processor for each possible
            // index type
            macro_rules! process {
                ($convert:ty) => {
                    process_accessor(
                        // unwrap here is safe as process accessor will only call
                        // this function with a slice that is the correct length
                        |a| <$convert>::from_le_bytes(a.try_into().unwrap()) as usize,
                        std::mem::size_of::<$convert>(),
                        value_size,
                        data,
                        &indicies,
                        &values,
                        stride,
                    )?
                };
            }

            // dispatch the correct accessor process
            match sparse.indices.component_type {
                gltf::ComponentType::Byte => process!(i8),
                gltf::ComponentType::UnsignedByte => process!(u8),
                gltf::ComponentType::Short => process!(i16),
                gltf::ComponentType::UnsignedShort => process!(u16),
                gltf::ComponentType::UnsignedInt => process!(u32),
                gltf::ComponentType::Float => return Err(ModelError::SparseFloat),
            }
        }

        Ok(())
    }
/// Try to apply all the sparse accessors to the model data, so the graphics
/// backend doesn't have to handle them
Try to apply all the sparse accessors to the model data, so the graphics
backend doesn't have to handle them
Try to apply all the sparse accessors to the model data so the graphics backend doesn ' t have to handle them
fn check_load_accessors(&mut self) -> Result<(), ModelError> {
        // check each accessor to see if it is sparse
        for accessor in &self.gltf.accessors {
            let sparse = match &accessor.sparse {
                Some(s) => s,
                _ => continue,
            };
            // there isn't always a buffer view, if not present a buffer of
            // zeros should be created to apply the sparse accessor to, so create
            // a new buffer view and buffer to store this new data
            let buffer_view = match accessor.buffer_view {
                Some(idx) => idx,
                None => {
                    let size = accessor.component_type.size()
                        * accessor.r#type.component_count()
                        * accessor.count;
                    self.buffers.push(Buffer {
                        data: vec![0; size],
                    });
                    let view = gltf::BufferView {
                        buffer: self.buffers.len() - 1,
                        byte_length: size,
                        byte_stride: None,
                        byte_offset: 0,
                        extensions: HashMap::default(),
                        extras: serde_json::Value::Null,
                        name: None,
                        target: None,
                    };
                    self.gltf.buffer_views.push(view);
                    self.gltf.buffer_views.len() - 1
                }
            };
            let value_size = accessor.component_type.size() * accessor.r#type.component_count();
            // get the indicies buffer view, then offset it with the infomation
            // from the sparse accessor offsetting the data
            let indicies = self.buffer_data(sparse.indices.buffer_view)?;
            let indicies = indicies
                .get(
                    sparse.indices.byte_offset
                        ..(sparse.indices.byte_offset
                            + sparse.count * sparse.indices.component_type.size()),
                )
                .ok_or(ModelError::BadIndex {
                    array: "Sparse indicies",
                    got: sparse.indices.byte_offset + sparse.count,
                    max: indicies.len(),
                })?
                .to_owned();
            // get the valaues buffer view, then offset it with the infomation
            // from the sparse accessor offsetting the data
            let values = self.buffer_data(sparse.values.buffer_view)?.to_owned();
            let values = values
                .get(
                    sparse.values.byte_offset
                        ..(sparse.values.byte_offset + sparse.count * value_size),
                )
                .ok_or(ModelError::BadIndex {
                    array: "Sparse values",
                    got: sparse.values.byte_offset + sparse.count,
                    max: indicies.len(),
                })?
                .to_owned();
            // get the mutable data to be edited from the model
            let data =
                Self::buffer_data_mut(&self.gltf.buffer_views, &mut self.buffers, buffer_view)?;
            let data_len = data.len();
            // get the relevant portion of the data buffer
            let data = data
                .get_mut(accessor.byte_offset..(accessor.byte_offset + accessor.count * value_size))
                .ok_or(ModelError::BadIndex {
                    array: "Sparse accessor data",
                    got: accessor.byte_offset + accessor.count,
                    max: data_len,
                })?;
            // get the stride, if it is not present, assume the stride is the same
            // as the value size.  If the code has run to this point, it
            // is gauranteed that the relavant buffer view exists so don't
            // need to check the access.
            let stride = if let Some(v) = self.gltf.buffer_views[buffer_view].byte_stride {
                v as usize
            } else {
                value_size
            };
            // macro to simplify generating the acessor processor for each possible
            // index type
            macro_rules! process {
                ($convert:ty) => {
                    process_accessor(
                        // unwrap here is safe as process accessor will only call
                        // this function with a slice that is the correct length
                        |a| <$convert>::from_le_bytes(a.try_into().unwrap()) as usize,
                        std::mem::size_of::<$convert>(),
                        value_size,
                        data,
                        &indicies,
                        &values,
                        stride,
                    )?
                };
            }
            // dispatch the correct accessor process
            match sparse.indices.component_type {
                gltf::ComponentType::Byte => process!(i8),
                gltf::ComponentType::UnsignedByte => process!(u8),
                gltf::ComponentType::Short => process!(i16),
                gltf::ComponentType::UnsignedShort => process!(u16),
                gltf::ComponentType::UnsignedInt => process!(u32),
                gltf::ComponentType::Float => return Err(ModelError::SparseFloat),
            }
        }
        Ok(())
    }
fn check_load_accessors ( & mut self ) -> Result < ( ) , ModelError > { // check each accessor to see if it is sparse for accessor in & self . gltf . accessors { let sparse = match & accessor . sparse { Some ( s ) => s , _ => continue , } ; // there isn't always a buffer view, if not present a buffer of // zeros should be created to apply the sparse accessor to, so create // a new buffer view and buffer to store this new data let buffer_view = match accessor . buffer_view { Some ( idx ) => idx , None => { let size = accessor . component_type . size ( ) * accessor . r#type . component_count ( ) * accessor . count ; self . buffers . push ( Buffer { data : vec ! [ 0 size ] , } ) ; let view = gltf :: BufferView { buffer : self . buffers . len ( ) - 1 , byte_length : size , byte_stride : None , byte_offset : 0 , extensions : HashMap :: default ( ) , extras : serde_json :: Value :: Null , name : None , target : None , } ; self . gltf . buffer_views . push ( view ) ; self . gltf . buffer_views . len ( ) - 1 } } ; let value_size = accessor . component_type . size ( ) * accessor . r#type . component_count ( ) ; // get the indicies buffer view, then offset it with the infomation // from the sparse accessor offsetting the data let indicies = self . buffer_data ( sparse . indices . buffer_view ) ? ; let indicies = indicies . get ( sparse . indices . byte_offset .. ( sparse . indices . byte_offset + sparse . count * sparse . indices . component_type . size ( ) ) , ) . ok_or ( ModelError :: BadIndex { array : " " , got : sparse . indices . byte_offset + sparse . count , max : indicies . len ( ) , } ) ? . to_owned ( ) ; // get the valaues buffer view, then offset it with the infomation // from the sparse accessor offsetting the data let values = self . buffer_data ( sparse . values . buffer_view ) ? . to_owned ( ) ; let values = values . get ( sparse . values . byte_offset .. ( sparse . values . byte_offset + sparse . count * value_size ) , ) . ok_or ( ModelError :: BadIndex { array : " " , got : sparse . values . byte_offset + sparse . count , max : indicies . len ( ) , } ) ? . to_owned ( ) ; // get the mutable data to be edited from the model let data = Self :: buffer_data_mut ( & self . gltf . buffer_views , & mut self . buffers , buffer_view ) ? ; let data_len = data . len ( ) ; // get the relevant portion of the data buffer let data = data . get_mut ( accessor . byte_offset .. ( accessor . byte_offset + accessor . count * value_size ) ) . ok_or ( ModelError :: BadIndex { array : " " , got : accessor . byte_offset + accessor . count , max : data_len , } ) ? ; // get the stride, if it is not present, assume the stride is the same // as the value size.  If the code has run to this point, it // is gauranteed that the relavant buffer view exists so don't // need to check the access. let stride = if let Some ( v ) = self . gltf . buffer_views [ buffer_view ] . byte_stride { v as usize } else { value_size } ; // macro to simplify generating the acessor processor for each possible // index type macro_rules! process { ( $convert : ty ) => { process_accessor ( // unwrap here is safe as process accessor will only call // this function with a slice that is the correct length a $convert from_le_bytes ( a try_into ( ) unwrap ( ) ) as usize std mem size_of $convert ( ) value_size data indicies values stride ) } ; } // dispatch the correct accessor process match sparse . indices . component_type { gltf :: ComponentType :: Byte => process ! ( i8 ) , gltf :: ComponentType :: UnsignedByte => process ! ( u8 ) , gltf :: ComponentType :: Short => process ! ( i16 ) , gltf :: ComponentType :: UnsignedShort => process ! ( u16 ) , gltf :: ComponentType :: UnsignedInt => process ! ( u32 ) , gltf :: ComponentType :: Float => return Err ( ModelError :: SparseFloat ) , } } Ok ( ( ) ) }
Try to apply all the sparse accessors to the model data, so the graphics
backend doesn't have to handle them
Try to apply all the sparse accessors to the model data so the graphics backend doesn ' t have to handle them
&mut self
&mut self