gltf-reader 0.1.0

A simple glTF 2.0 reader using `serde` and `serde_json`
Documentation
use alloc::borrow::Cow;
use alloc::vec::Vec;
use ownable::IntoOwned;
use serde::Deserialize;
use serde_json::Number;

use crate::buffer::BufferView;
use crate::{Extensions, Extras, Idx};

/// glTF known data types of an accessor's components.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComponentTypeEnum {
    I8,
    U8,
    I16,
    U16,
    U32,
    F32,
}

/// Data type of an accessor's components.
#[derive(Clone, Copy, PartialEq, Eq, Deserialize, IntoOwned)]
#[serde(transparent)]
pub struct ComponentType(pub u64);

impl core::fmt::Debug for ComponentType {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        if let Some(e) = self.to_enum() {
            e.fmt(f)
        } else {
            self.0.fmt(f)
        }
    }
}

impl ComponentType {
    pub const I8: Self = Self(5120);
    pub const U8: Self = Self(5121);
    pub const I16: Self = Self(5122);
    pub const U16: Self = Self(5123);
    pub const U32: Self = Self(5125);
    pub const F32: Self = Self(5126);

    pub fn to_enum(self) -> Option<ComponentTypeEnum> {
        Some(match self {
            Self::I8 => ComponentTypeEnum::I8,
            Self::U8 => ComponentTypeEnum::U8,
            Self::I16 => ComponentTypeEnum::I16,
            Self::U16 => ComponentTypeEnum::U16,
            Self::U32 => ComponentTypeEnum::U32,
            Self::F32 => ComponentTypeEnum::F32,
            _ => return None,
        })
    }
}

/// glTF known data types of an accessor's elements.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ElementTypeEnum {
    Scalar,
    Vec2,
    Vec3,
    Vec4,
    Mat2,
    Mat3,
    Mat4,
}

/// Data type of an accessor's elements.
#[derive(Clone, PartialEq, Eq, Deserialize, IntoOwned)]
#[serde(transparent)]
pub struct ElementType<'a>(#[serde(borrow)] pub Cow<'a, str>);

impl core::fmt::Debug for ElementType<'_> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        if let Some(e) = self.to_enum() {
            e.fmt(f)
        } else {
            self.0.fmt(f)
        }
    }
}

impl ElementType<'_> {
    pub const SCALAR: Self = Self(Cow::Borrowed("SCALAR"));
    pub const VEC2: Self = Self(Cow::Borrowed("VEC2"));
    pub const VEC3: Self = Self(Cow::Borrowed("VEC3"));
    pub const VEC4: Self = Self(Cow::Borrowed("VEC4"));
    pub const MAT2: Self = Self(Cow::Borrowed("MAT2"));
    pub const MAT3: Self = Self(Cow::Borrowed("MAT3"));
    pub const MAT4: Self = Self(Cow::Borrowed("MAT4"));

    pub fn to_enum(&self) -> Option<ElementTypeEnum> {
        if *self == Self::SCALAR {
            return Some(ElementTypeEnum::Scalar);
        } else if *self == Self::VEC2 {
            return Some(ElementTypeEnum::Vec2);
        } else if *self == Self::VEC3 {
            return Some(ElementTypeEnum::Vec3);
        } else if *self == Self::VEC4 {
            return Some(ElementTypeEnum::Vec4);
        } else if *self == Self::MAT2 {
            return Some(ElementTypeEnum::Mat2);
        } else if *self == Self::MAT3 {
            return Some(ElementTypeEnum::Mat3);
        } else if *self == Self::MAT4 {
            return Some(ElementTypeEnum::Mat4);
        }

        None
    }
}

/// Sparse storage of accessor values that deviate from their initialization value.
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct SparseIndices<'a> {
    /// The index of the buffer view with sparse indices.
    #[serde(rename = "bufferView")]
    pub buffer_view: Idx<BufferView<'static>>,
    /// The offset relative to the start of the buffer view in bytes.
    #[serde(rename = "byteOffset")]
    #[serde(default)]
    pub byte_offset: u64,
    /// The indices data type.
    #[serde(rename = "componentType")]
    pub component_type: ComponentType,

    #[serde(borrow)]
    pub extensions: Option<Extensions<'a>>,
    #[serde(borrow)]
    pub extras: Option<Extras<'a>>,
}

/// An object pointing to a buffer view containing the deviating accessor values.
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct SparseValues<'a> {
    /// The index of the buffer view with sparse indices.
    #[serde(rename = "bufferView")]
    pub buffer_view: Idx<BufferView<'static>>,
    /// The offset relative to the start of the buffer view in bytes.
    #[serde(rename = "byteOffset")]
    #[serde(default)]
    pub byte_offset: u64,

    #[serde(borrow)]
    pub extensions: Option<Extensions<'a>>,
    #[serde(borrow)]
    pub extras: Option<Extras<'a>>,
}

/// Sparse storage of accessor values that deviate from their initialization value.
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct Sparse<'a> {
    /// Number of deviating accessor values stored in the sparse array.
    pub count: u64,
    /// An object pointing to a buffer view containing the indices of deviating accessor values.
    pub indices: SparseIndices<'a>,
    /// An object pointing to a buffer view containing the deviating accessor values.
    pub values: SparseValues<'a>,

    #[serde(borrow)]
    pub extensions: Option<Extensions<'a>>,
    #[serde(borrow)]
    pub extras: Option<Extras<'a>>,
}

/// A typed view into a buffer view that contains raw binary data.
#[derive(Debug, Clone, Deserialize, IntoOwned)]
pub struct Accessor<'a> {
    /// The user-defined name of this object.
    #[serde(borrow)]
    pub name: Option<Cow<'a, str>>,

    /// The index of the buffer view.
    #[serde(rename = "bufferView")]
    pub buffer_view: Idx<BufferView<'static>>,
    /// The offset relative to the start of the buffer view in bytes.
    #[serde(rename = "byteOffset")]
    #[serde(default)]
    pub byte_offset: u64,

    /// Specifies if the accessor's elements are scalars, vectors, or matrices.
    #[serde(rename = "type")]
    #[serde(borrow)]
    pub ty: ElementType<'a>,
    /// The data type of the accessor's components.
    #[serde(rename = "componentType")]
    pub component_type: ComponentType,
    /// Specifies whether integer data values are normalized to [0, 1] (for unsigned types) or to
    /// [-1, 1] (for signed types) when they are accessed.
    #[serde(default)]
    pub normalized: bool,
    /// The number of elements referenced by this accessor.
    pub count: u64,
    /// Maximum value of each component in this accessor.
    #[ownable(clone)]
    pub max: Option<Vec<Number>>,
    /// Minimum value of each component in this accessor.
    #[ownable(clone)]
    pub min: Option<Vec<Number>>,

    /// Sparse storage of elements that deviate from their initialization value.
    #[serde(borrow)]
    pub sparse: Option<Sparse<'a>>,

    #[serde(borrow)]
    pub extensions: Option<Extensions<'a>>,
    #[serde(borrow)]
    pub extras: Option<Extras<'a>>,
}