Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

200
vendor/gltf/src/accessor/mod.rs vendored Normal file
View File

@@ -0,0 +1,200 @@
//! # Basic usage
//!
//! Visiting the accessors of a glTF asset.
//!
//! ```
//! # fn run() -> Result<(), Box<dyn std::error::Error>> {
//! # let gltf = gltf::Gltf::open("examples/Box.gltf")?;
//! for accessor in gltf.accessors() {
//! println!("Accessor #{}", accessor.index());
//! println!("offset: {:?}", accessor.offset());
//! println!("count: {}", accessor.count());
//! println!("data_type: {:?}", accessor.data_type());
//! println!("dimensions: {:?}", accessor.dimensions());
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! # let _ = run().expect("runtime error");
//! # }
//! ```
//!
//! # Utility functions
//!
//! Reading the values from the `vec3` accessors of a glTF asset.
//!
//! ## Note
//!
//! The [`Iter`] utility is a low-level iterator intended for use in special
//! cases. The average user is expected to use reader abstractions such as
//! [`mesh::Reader`].
//!
//! [`Iter`]: struct.Iter.html
//! [`mesh::Reader`]: ../mesh/struct.Reader.html
//!
//! ```
//! # fn run() -> Result<(), Box<dyn std::error::Error>> {
//! # use gltf::accessor::{DataType, Dimensions, Iter};
//! let (gltf, buffers, _) = gltf::import("examples/Box.gltf")?;
//! let get_buffer_data = |buffer: gltf::Buffer| buffers.get(buffer.index()).map(|x| &*x.0);
//! for accessor in gltf.accessors() {
//! match (accessor.data_type(), accessor.dimensions()) {
//! (DataType::F32, Dimensions::Vec3) => {
//! if let Some(iter) = Iter::<[f32; 3]>::new(accessor, get_buffer_data) {
//! for item in iter {
//! println!("{:?}", item);
//! }
//! }
//! }
//! _ => {},
//! }
//! }
//! # Ok(())
//! # }
//! # fn main() {
//! # let _ = run().expect("runtime error");
//! # }
//! ```
use crate::{buffer, Document};
pub use json::accessor::ComponentType as DataType;
pub use json::accessor::Type as Dimensions;
#[cfg(feature = "extensions")]
use serde_json::{Map, Value};
/// Utility functions.
#[cfg(feature = "utils")]
#[cfg_attr(docsrs, doc(cfg(feature = "utils")))]
pub mod util;
/// Contains data structures for sparse storage.
pub mod sparse;
#[cfg(feature = "utils")]
#[doc(inline)]
pub use self::util::{Item, Iter};
/// A typed view into a buffer view.
#[derive(Clone, Debug)]
pub struct Accessor<'a> {
/// The parent `Document` struct.
document: &'a Document,
/// The corresponding JSON index.
index: usize,
/// The corresponding JSON struct.
json: &'a json::accessor::Accessor,
}
impl<'a> Accessor<'a> {
/// Constructs an `Accessor`.
pub(crate) fn new(
document: &'a Document,
index: usize,
json: &'a json::accessor::Accessor,
) -> Self {
Self {
document,
index,
json,
}
}
/// Returns the internal JSON index.
pub fn index(&self) -> usize {
self.index
}
/// Returns the size of each component that this accessor describes.
pub fn size(&self) -> usize {
self.data_type().size() * self.dimensions().multiplicity()
}
/// Returns the buffer view this accessor reads from.
///
/// This may be `None` if the corresponding accessor is sparse.
pub fn view(&self) -> Option<buffer::View<'a>> {
self.json
.buffer_view
.map(|view| self.document.views().nth(view.value()).unwrap())
}
/// Returns the offset relative to the start of the parent buffer view in bytes.
///
/// This will be 0 if the corresponding accessor is sparse.
pub fn offset(&self) -> usize {
// TODO: Change this function to return Option<usize> in the next
// version and return None for sparse accessors.
self.json.byte_offset.unwrap_or_default().0 as usize
}
/// Returns the number of components within the buffer view - not to be confused
/// with the number of bytes in the buffer view.
pub fn count(&self) -> usize {
self.json.count.0 as usize
}
/// Returns the data type of components in the attribute.
pub fn data_type(&self) -> DataType {
self.json.component_type.unwrap().0
}
/// Returns extension data unknown to this crate version.
#[cfg(feature = "extensions")]
#[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
pub fn extensions(&self) -> Option<&Map<String, Value>> {
let ext = self.json.extensions.as_ref()?;
Some(&ext.others)
}
/// Queries extension data unknown to this crate version.
#[cfg(feature = "extensions")]
#[cfg_attr(docsrs, doc(cfg(feature = "extensions")))]
pub fn extension_value(&self, ext_name: &str) -> Option<&Value> {
let ext = self.json.extensions.as_ref()?;
ext.others.get(ext_name)
}
/// Optional application specific data.
pub fn extras(&self) -> &'a json::Extras {
&self.json.extras
}
/// Specifies if the attribute is a scalar, vector, or matrix.
pub fn dimensions(&self) -> Dimensions {
self.json.type_.unwrap()
}
/// Returns the minimum value of each component in this attribute.
pub fn min(&self) -> Option<json::Value> {
self.json.min.clone()
}
/// Returns the maximum value of each component in this attribute.
pub fn max(&self) -> Option<json::Value> {
self.json.max.clone()
}
/// Optional user-defined name for this object.
#[cfg(feature = "names")]
#[cfg_attr(docsrs, doc(cfg(feature = "names")))]
pub fn name(&self) -> Option<&'a str> {
self.json.name.as_deref()
}
/// Specifies whether integer data values should be normalized.
pub fn normalized(&self) -> bool {
self.json.normalized
}
/// Returns sparse storage of attributes that deviate from their initialization
/// value.
pub fn sparse(&self) -> Option<sparse::Sparse<'a>> {
self.json
.sparse
.as_ref()
.map(|json| sparse::Sparse::new(self.document, json))
}
}

143
vendor/gltf/src/accessor/sparse.rs vendored Normal file
View File

@@ -0,0 +1,143 @@
use crate::{buffer, Document};
/// The index data type.
#[derive(Clone, Debug)]
pub enum IndexType {
/// Corresponds to `GL_UNSIGNED_BYTE`.
U8 = 5121,
/// Corresponds to `GL_UNSIGNED_SHORT`.
U16 = 5123,
/// Corresponds to `GL_UNSIGNED_INT`.
U32 = 5125,
}
/// Indices of those attributes that deviate from their initialization value.
pub struct Indices<'a> {
/// The parent `Document` struct.
document: &'a Document,
/// The corresponding JSON struct.
json: &'a json::accessor::sparse::Indices,
}
impl<'a> Indices<'a> {
/// Constructs `sparse::Indices`.
pub(crate) fn new(document: &'a Document, json: &'a json::accessor::sparse::Indices) -> Self {
Self { document, json }
}
/// Returns the buffer view containing the sparse indices.
pub fn view(&self) -> buffer::View<'a> {
self.document
.views()
.nth(self.json.buffer_view.value())
.unwrap()
}
/// The offset relative to the start of the parent buffer view in bytes.
pub fn offset(&self) -> usize {
self.json.byte_offset.0 as usize
}
/// The data type of each index.
pub fn index_type(&self) -> IndexType {
match self.json.component_type.unwrap().0 {
json::accessor::ComponentType::U8 => IndexType::U8,
json::accessor::ComponentType::U16 => IndexType::U16,
json::accessor::ComponentType::U32 => IndexType::U32,
_ => unreachable!(),
}
}
/// Optional application specific data.
pub fn extras(&self) -> &'a json::Extras {
&self.json.extras
}
}
/// Sparse storage of attributes that deviate from their initialization value.
pub struct Sparse<'a> {
/// The parent `Document` struct.
document: &'a Document,
/// The corresponding JSON struct.
json: &'a json::accessor::sparse::Sparse,
}
impl<'a> Sparse<'a> {
/// Constructs `Sparse`.
pub(crate) fn new(document: &'a Document, json: &'a json::accessor::sparse::Sparse) -> Self {
Self { document, json }
}
/// Returns the number of attributes encoded in this sparse accessor.
pub fn count(&self) -> usize {
self.json.count.0 as usize
}
/// Returns an index array of size `count` that points to those accessor
/// attributes that deviate from their initialization value.
pub fn indices(&self) -> Indices<'a> {
Indices::new(self.document, &self.json.indices)
}
/// Returns an array of size `count * number_of_components`, storing the
/// displaced accessor attributes pointed by `indices`.
pub fn values(&self) -> Values<'a> {
Values::new(self.document, &self.json.values)
}
/// Optional application specific data.
pub fn extras(&self) -> &'a json::Extras {
&self.json.extras
}
}
/// Array of size `count * number_of_components` storing the displaced accessor
/// attributes pointed by `accessor::sparse::Indices`.
pub struct Values<'a> {
/// The parent `Document` struct.
document: &'a Document,
/// The corresponding JSON struct.
json: &'a json::accessor::sparse::Values,
}
impl<'a> Values<'a> {
/// Constructs `sparse::Values`.
pub(crate) fn new(document: &'a Document, json: &'a json::accessor::sparse::Values) -> Self {
Self { document, json }
}
/// Returns the buffer view containing the sparse values.
pub fn view(&self) -> buffer::View<'a> {
self.document
.views()
.nth(self.json.buffer_view.value())
.unwrap()
}
/// The offset relative to the start of the parent buffer view in bytes.
pub fn offset(&self) -> usize {
self.json.byte_offset.0 as usize
}
/// Optional application specific data.
pub fn extras(&self) -> &'a json::Extras {
&self.json.extras
}
}
impl IndexType {
/// Returns the number of bytes this value represents.
pub fn size(&self) -> usize {
use self::IndexType::*;
match *self {
U8 => 1,
U16 => 2,
U32 => 4,
}
}
}

454
vendor/gltf/src/accessor/util.rs vendored Normal file
View File

@@ -0,0 +1,454 @@
use byteorder::{ByteOrder, LE};
use std::marker::PhantomData;
use std::{iter, mem};
use crate::{accessor, buffer};
fn buffer_view_slice<'a, 's>(
view: buffer::View<'a>,
get_buffer_data: &dyn Fn(buffer::Buffer<'a>) -> Option<&'s [u8]>,
) -> Option<&'s [u8]> {
let start = view.offset();
let end = start + view.length();
get_buffer_data(view.buffer()).and_then(|slice| slice.get(start..end))
}
/// General iterator for an accessor.
#[derive(Clone, Debug)]
pub enum Iter<'a, T: Item> {
/// Standard accessor iterator.
Standard(ItemIter<'a, T>),
/// Iterator for accessor with sparse values.
Sparse(SparseIter<'a, T>),
}
impl<'a, T: Item> Iterator for Iter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match self {
Iter::Standard(ref mut iter) => iter.next(),
Iter::Sparse(ref mut iter) => iter.next(),
}
}
fn nth(&mut self, nth: usize) -> Option<Self::Item> {
match self {
Iter::Standard(ref mut iter) => iter.nth(nth),
Iter::Sparse(ref mut iter) => iter.nth(nth),
}
}
fn last(self) -> Option<Self::Item> {
match self {
Iter::Standard(iter) => iter.last(),
Iter::Sparse(iter) => iter.last(),
}
}
fn count(self) -> usize {
match self {
Iter::Standard(iter) => iter.count(),
Iter::Sparse(iter) => iter.count(),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
Iter::Standard(ref iter) => iter.size_hint(),
Iter::Sparse(ref iter) => iter.size_hint(),
}
}
}
impl<'a, T: Item> ExactSizeIterator for Iter<'a, T> {}
/// Iterator over indices of sparse accessor.
#[derive(Clone, Debug)]
pub enum SparseIndicesIter<'a> {
/// 8-bit indices.
U8(ItemIter<'a, u8>),
/// 16-bit indices.
U16(ItemIter<'a, u16>),
/// 32-bit indices.
U32(ItemIter<'a, u32>),
}
impl<'a> Iterator for SparseIndicesIter<'a> {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
match *self {
SparseIndicesIter::U8(ref mut iter) => iter.next().map(|x| x as u32),
SparseIndicesIter::U16(ref mut iter) => iter.next().map(|x| x as u32),
SparseIndicesIter::U32(ref mut iter) => iter.next(),
}
}
}
/// Iterates over a sparse accessor.
#[derive(Clone, Debug)]
pub struct SparseIter<'a, T: Item> {
/// Base value iterator.
///
/// This can be `None` if the base buffer view is not set. In this case the base values are all zero.
base: Option<ItemIter<'a, T>>,
/// Number of values in the base accessor
///
/// Valid even when `base` is not set.
base_count: usize,
/// Sparse indices iterator.
indices: iter::Peekable<SparseIndicesIter<'a>>,
/// Sparse values iterator.
values: ItemIter<'a, T>,
/// Iterator counter.
counter: u32,
}
impl<'a, T: Item> SparseIter<'a, T> {
/// Constructor.
///
/// Here `base` is allowed to be `None` when the base buffer view is not explicitly specified.
pub fn new(
base: Option<ItemIter<'a, T>>,
indices: SparseIndicesIter<'a>,
values: ItemIter<'a, T>,
) -> Self {
Self::with_base_count(base, 0, indices, values)
}
/// Supplemental constructor.
pub fn with_base_count(
base: Option<ItemIter<'a, T>>,
base_count: usize,
indices: SparseIndicesIter<'a>,
values: ItemIter<'a, T>,
) -> Self {
Self {
base,
base_count,
indices: indices.peekable(),
values,
counter: 0,
}
}
}
impl<'a, T: Item> Iterator for SparseIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let mut next_value = if let Some(base) = self.base.as_mut() {
// If accessor.bufferView is set we let base decide when we have reached the end
// of the iteration sequence.
base.next()?
} else if (self.counter as usize) < self.base_count {
// Else, we continue iterating until we have generated the number of items
// specified by accessor.count
T::zero()
} else {
return None;
};
let next_sparse_index = self.indices.peek();
if let Some(index) = next_sparse_index {
if *index == self.counter {
self.indices.next(); // advance
next_value = self.values.next().unwrap();
}
}
self.counter += 1;
Some(next_value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let hint = self.base_count - (self.counter as usize).min(self.base_count);
(hint, Some(hint))
}
}
impl<'a, T: Item> ExactSizeIterator for SparseIter<'a, T> {}
/// Represents items that can be read by an [`Accessor`].
///
/// [`Accessor`]: struct.Accessor.html
pub trait Item {
/// Create an object of this type from a byte slice.
fn from_slice(slice: &[u8]) -> Self;
/// Create an object of this type that represents a zero value.
fn zero() -> Self;
}
/// Visits the items in an [`Accessor`].
///
/// [`Accessor`]: struct.Accessor.html
#[derive(Copy, Clone, Debug)]
pub struct ItemIter<'a, T: Item> {
stride: usize,
data: &'a [u8],
_phantom: PhantomData<T>,
}
impl Item for i8 {
fn from_slice(slice: &[u8]) -> Self {
slice[0] as i8
}
fn zero() -> Self {
0
}
}
impl Item for i16 {
fn from_slice(slice: &[u8]) -> Self {
LE::read_i16(slice)
}
fn zero() -> Self {
0
}
}
impl Item for u8 {
fn from_slice(slice: &[u8]) -> Self {
slice[0]
}
fn zero() -> Self {
0
}
}
impl Item for u16 {
fn from_slice(slice: &[u8]) -> Self {
LE::read_u16(slice)
}
fn zero() -> Self {
0
}
}
impl Item for u32 {
fn from_slice(slice: &[u8]) -> Self {
LE::read_u32(slice)
}
fn zero() -> Self {
0
}
}
impl Item for f32 {
fn from_slice(slice: &[u8]) -> Self {
LE::read_f32(slice)
}
fn zero() -> Self {
0.0
}
}
impl<T: Item + Copy> Item for [T; 2] {
fn from_slice(slice: &[u8]) -> Self {
assert!(slice.len() >= 2 * mem::size_of::<T>());
[
T::from_slice(slice),
T::from_slice(&slice[mem::size_of::<T>()..]),
]
}
fn zero() -> Self {
[T::zero(); 2]
}
}
impl<T: Item + Copy> Item for [T; 3] {
fn from_slice(slice: &[u8]) -> Self {
assert!(slice.len() >= 3 * mem::size_of::<T>());
[
T::from_slice(slice),
T::from_slice(&slice[mem::size_of::<T>()..]),
T::from_slice(&slice[2 * mem::size_of::<T>()..]),
]
}
fn zero() -> Self {
[T::zero(); 3]
}
}
impl<T: Item + Copy> Item for [T; 4] {
fn from_slice(slice: &[u8]) -> Self {
assert!(slice.len() >= 4 * mem::size_of::<T>());
[
T::from_slice(slice),
T::from_slice(&slice[mem::size_of::<T>()..]),
T::from_slice(&slice[2 * mem::size_of::<T>()..]),
T::from_slice(&slice[3 * mem::size_of::<T>()..]),
]
}
fn zero() -> Self {
[T::zero(); 4]
}
}
impl<'a, T: Item> ItemIter<'a, T> {
/// Constructor.
pub fn new(slice: &'a [u8], stride: usize) -> Self {
ItemIter {
data: slice,
stride,
_phantom: PhantomData,
}
}
}
impl<'a, 's, T: Item> Iter<'s, T> {
/// Constructor.
pub fn new<F>(accessor: super::Accessor<'a>, get_buffer_data: F) -> Option<Iter<'s, T>>
where
F: Clone + Fn(buffer::Buffer<'a>) -> Option<&'s [u8]>,
{
match accessor.sparse() {
Some(sparse) => {
// Using `if let` here instead of map to preserve the early return behavior.
let base_iter = if let Some(view) = accessor.view() {
let stride = view.stride().unwrap_or(mem::size_of::<T>());
let start = accessor.offset();
let end = start + stride * (accessor.count() - 1) + mem::size_of::<T>();
let subslice = buffer_view_slice(view, &get_buffer_data)
.and_then(|slice| slice.get(start..end))?;
Some(ItemIter::new(subslice, stride))
} else {
None
};
let base_count = accessor.count();
let indices = sparse.indices();
let values = sparse.values();
let sparse_count = sparse.count();
let index_iter = {
let view = indices.view();
let index_size = indices.index_type().size();
let stride = view.stride().unwrap_or(index_size);
let start = indices.offset();
let end = start + stride * (sparse_count - 1) + index_size;
let subslice = buffer_view_slice(view, &get_buffer_data)
.and_then(|slice| slice.get(start..end))?;
match indices.index_type() {
accessor::sparse::IndexType::U8 => {
SparseIndicesIter::U8(ItemIter::new(subslice, stride))
}
accessor::sparse::IndexType::U16 => {
SparseIndicesIter::U16(ItemIter::new(subslice, stride))
}
accessor::sparse::IndexType::U32 => {
SparseIndicesIter::U32(ItemIter::new(subslice, stride))
}
}
};
let value_iter = {
let view = values.view();
let stride = view.stride().unwrap_or(mem::size_of::<T>());
let start = values.offset();
let end = start + stride * (sparse_count - 1) + mem::size_of::<T>();
let subslice = buffer_view_slice(view, &get_buffer_data)
.and_then(|slice| slice.get(start..end))?;
ItemIter::new(subslice, stride)
};
Some(Iter::Sparse(SparseIter::with_base_count(
base_iter, base_count, index_iter, value_iter,
)))
}
None => {
debug_assert_eq!(mem::size_of::<T>(), accessor.size());
debug_assert!(mem::size_of::<T>() > 0);
accessor.view().and_then(|view| {
let stride = view.stride().unwrap_or(mem::size_of::<T>());
debug_assert!(
stride >= mem::size_of::<T>(),
"Mismatch in stride, expected at least {} stride but found {}",
mem::size_of::<T>(),
stride
);
let start = accessor.offset();
let end = start + stride * (accessor.count() - 1) + mem::size_of::<T>();
let subslice = buffer_view_slice(view, &get_buffer_data)
.and_then(|slice| slice.get(start..end))?;
Some(Iter::Standard(ItemIter {
stride,
data: subslice,
_phantom: PhantomData,
}))
})
}
}
}
}
impl<'a, T: Item> ExactSizeIterator for ItemIter<'a, T> {}
impl<'a, T: Item> Iterator for ItemIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let stride = if self.data.len() >= self.stride {
Some(self.stride)
} else if self.data.len() >= mem::size_of::<T>() {
Some(mem::size_of::<T>())
} else {
None
};
if let Some(stride) = stride {
let (val, data) = self.data.split_at(stride);
let val = T::from_slice(val);
self.data = data;
Some(val)
} else {
None
}
}
fn nth(&mut self, nth: usize) -> Option<Self::Item> {
if let Some(val_data) = self.data.get(nth * self.stride..) {
if val_data.len() >= mem::size_of::<T>() {
let val = T::from_slice(val_data);
self.data = &val_data[self.stride.min(val_data.len())..];
Some(val)
} else {
None
}
} else {
None
}
}
fn last(self) -> Option<Self::Item> {
if self.data.len() >= mem::size_of::<T>() {
self.data
.get((self.data.len() - 1) / self.stride * self.stride..)
.map(T::from_slice)
} else {
None
}
}
fn count(self) -> usize {
self.size_hint().0
}
fn size_hint(&self) -> (usize, Option<usize>) {
let hint = self.data.len() / self.stride
+ (self.data.len() % self.stride >= mem::size_of::<T>()) as usize;
(hint, Some(hint))
}
}