use crate::validation::{Checked, Error, USize64};
use crate::{buffer, extensions, Extras, Index, Path, Root};
use gltf_derive::Validate;
use serde::{de, ser};
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
use std::fmt;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)]
pub enum ComponentType {
I8 = 1,
U8,
I16,
U16,
U32,
F32,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)]
pub enum Type {
Scalar = 1,
Vec2,
Vec3,
Vec4,
Mat2,
Mat3,
Mat4,
}
pub const BYTE: u32 = 5120;
pub const UNSIGNED_BYTE: u32 = 5121;
pub const SHORT: u32 = 5122;
pub const UNSIGNED_SHORT: u32 = 5123;
pub const UNSIGNED_INT: u32 = 5125;
pub const FLOAT: u32 = 5126;
pub const VALID_COMPONENT_TYPES: &[u32] = &[
BYTE,
UNSIGNED_BYTE,
SHORT,
UNSIGNED_SHORT,
UNSIGNED_INT,
FLOAT,
];
pub const VALID_INDEX_TYPES: &[u32] = &[UNSIGNED_BYTE, UNSIGNED_SHORT, UNSIGNED_INT];
pub const VALID_ACCESSOR_TYPES: &[&str] =
&["SCALAR", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4"];
pub mod sparse {
use super::*;
use crate::extensions;
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct Indices {
#[serde(rename = "bufferView")]
pub buffer_view: Index<buffer::View>,
#[serde(default, rename = "byteOffset")]
pub byte_offset: USize64,
#[serde(rename = "componentType")]
pub component_type: Checked<IndexComponentType>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::accessor::sparse::Indices>,
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct Sparse {
pub count: USize64,
pub indices: Indices,
pub values: Values,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::accessor::sparse::Sparse>,
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
pub struct Values {
#[serde(rename = "bufferView")]
pub buffer_view: Index<buffer::View>,
#[serde(default, rename = "byteOffset")]
pub byte_offset: USize64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::accessor::sparse::Values>,
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
}
}
#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
#[gltf(validate_hook = "accessor_validate_hook")]
pub struct Accessor {
#[serde(rename = "bufferView")]
#[serde(skip_serializing_if = "Option::is_none")]
pub buffer_view: Option<Index<buffer::View>>,
#[serde(default, rename = "byteOffset")]
#[serde(skip_serializing_if = "Option::is_none")]
pub byte_offset: Option<USize64>,
pub count: USize64,
#[serde(rename = "componentType")]
pub component_type: Checked<GenericComponentType>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extensions: Option<extensions::accessor::Accessor>,
#[serde(default)]
#[cfg_attr(feature = "extras", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(not(feature = "extras"), serde(skip_serializing))]
pub extras: Extras,
#[serde(rename = "type")]
pub type_: Checked<Type>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max: Option<Value>,
#[cfg(feature = "names")]
#[cfg_attr(feature = "names", serde(skip_serializing_if = "Option::is_none"))]
pub name: Option<String>,
#[serde(default, skip_serializing_if = "is_normalized_default")]
pub normalized: bool,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub sparse: Option<sparse::Sparse>,
}
fn accessor_validate_hook<P, R>(accessor: &Accessor, _root: &Root, path: P, report: &mut R)
where
P: Fn() -> Path,
R: FnMut(&dyn Fn() -> Path, Error),
{
if accessor.sparse.is_none() && accessor.buffer_view.is_none() {
report(&|| path().field("bufferView"), Error::Missing);
}
}
fn is_normalized_default(b: &bool) -> bool {
!*b
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct IndexComponentType(pub ComponentType);
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct GenericComponentType(pub ComponentType);
impl<'de> de::Deserialize<'de> for Checked<GenericComponentType> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<GenericComponentType>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_COMPONENT_TYPES)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
use self::ComponentType::*;
use crate::validation::Checked::*;
Ok(match value as u32 {
BYTE => Valid(GenericComponentType(I8)),
UNSIGNED_BYTE => Valid(GenericComponentType(U8)),
SHORT => Valid(GenericComponentType(I16)),
UNSIGNED_SHORT => Valid(GenericComponentType(U16)),
UNSIGNED_INT => Valid(GenericComponentType(U32)),
FLOAT => Valid(GenericComponentType(F32)),
_ => Invalid,
})
}
}
deserializer.deserialize_u64(Visitor)
}
}
impl<'de> de::Deserialize<'de> for Checked<IndexComponentType> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<IndexComponentType>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_INDEX_TYPES)
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
use self::ComponentType::*;
use crate::validation::Checked::*;
Ok(match value as u32 {
UNSIGNED_BYTE => Valid(IndexComponentType(U8)),
UNSIGNED_SHORT => Valid(IndexComponentType(U16)),
UNSIGNED_INT => Valid(IndexComponentType(U32)),
_ => Invalid,
})
}
}
deserializer.deserialize_u64(Visitor)
}
}
impl<'de> de::Deserialize<'de> for Checked<Type> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Checked<Type>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "any of: {:?}", VALID_ACCESSOR_TYPES)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
use self::Type::*;
use crate::validation::Checked::*;
Ok(match value {
"SCALAR" => Valid(Scalar),
"VEC2" => Valid(Vec2),
"VEC3" => Valid(Vec3),
"VEC4" => Valid(Vec4),
"MAT2" => Valid(Mat2),
"MAT3" => Valid(Mat3),
"MAT4" => Valid(Mat4),
_ => Invalid,
})
}
}
deserializer.deserialize_str(Visitor)
}
}
impl ser::Serialize for Type {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
serializer.serialize_str(match *self {
Type::Scalar => "SCALAR",
Type::Vec2 => "VEC2",
Type::Vec3 => "VEC3",
Type::Vec4 => "VEC4",
Type::Mat2 => "MAT2",
Type::Mat3 => "MAT3",
Type::Mat4 => "MAT4",
})
}
}
impl ComponentType {
pub fn size(&self) -> usize {
use self::ComponentType::*;
match *self {
I8 | U8 => 1,
I16 | U16 => 2,
F32 | U32 => 4,
}
}
pub fn as_gl_enum(self) -> u32 {
match self {
ComponentType::I8 => BYTE,
ComponentType::U8 => UNSIGNED_BYTE,
ComponentType::I16 => SHORT,
ComponentType::U16 => UNSIGNED_SHORT,
ComponentType::U32 => UNSIGNED_INT,
ComponentType::F32 => FLOAT,
}
}
}
impl ser::Serialize for ComponentType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
serializer.serialize_u32(self.as_gl_enum())
}
}
impl Type {
pub fn multiplicity(&self) -> usize {
use self::Type::*;
match *self {
Scalar => 1,
Vec2 => 2,
Vec3 => 3,
Vec4 | Mat2 => 4,
Mat3 => 9,
Mat4 => 16,
}
}
}