native/src/variational_asset/mod.rs (45 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved // use std::path::Path; extern crate wasm_bindgen; use wasm_bindgen::prelude::*; use serde_derive::{Deserialize, Serialize}; use crate::{Error, Tag, WorkAsset}; /// The Metadata struct & accessor methods pub mod metadata; pub use metadata::Metadata; /// Compatibility methods for the WebAssembly build pub mod wasm; /// The primary API data structure. /// /// The key property is a glTF asset in binary form (which will always implement /// the `KHR_materials_variants` extension), along with various useful metadata for /// the benefit of clients. /// /// The key method melds one variational asset into another: /// ``` /// extern crate assets; /// use std::path::Path; /// use gltf_variant_meld::{Tag, VariationalAsset}; /// /// let (matte_tag, shiny_tag) = (Tag::from("matte"), Tag::from("shiny")); /// let pinecone_matte = VariationalAsset::from_file( /// &Path::new(assets::ASSET_PINECONE_MATTE()), /// Some(&matte_tag), /// ).expect("Eek! Couldn't create matte pinecone VariationalAsset."); /// /// let pinecone_shiny = VariationalAsset::from_file( /// &Path::new(assets::ASSET_PINECONE_SHINY()), /// Some(&shiny_tag), /// ).expect("Eek! Couldn't create shiny pinecone VariationalAsset."); /// /// let result = VariationalAsset::meld( /// &pinecone_matte, /// &pinecone_shiny /// ).expect("Erk. Failed to meld two pinecones."); /// /// assert!(result.metadata().tags().contains(&matte_tag)); /// assert!(result.metadata().tags().contains(&shiny_tag)); /// assert_eq!(result.metadata().tags().len(), 2); ///``` #[wasm_bindgen] #[derive(Debug, Clone)] pub struct VariationalAsset { /// The generated glTF for this asset. Will always implement `KHR_materials_variants` /// and is always in binary (GLB) form. pub(crate) glb: Vec<u8>, /// The tag that stands in for any default material references in the asset glTF. pub(crate) default_tag: Tag, /// All the metadata generated for this asset. pub(crate) metadata: Metadata, } /// A summary of a mesh primitive's byte size requirements; currently textures only. #[wasm_bindgen] #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct AssetSizes { /// Byte count for texture image data, in its raw encoded form. pub texture_bytes: usize, } // methods that wasm_bindgen can't cope with in their preferred form impl VariationalAsset { /// Generates a new `VariationalAsset` from a glTF file. /// /// If the provided asset implements `KHR_materials_variants`, then `default_tag` must /// either be empty or match the default tag within the asset. /// /// If the asset doesn't implement `KHR_materials_variants`, then the argument /// `default_tag` must be non-empty. If it does, then `default_tag` must either match /// what's in the asset, or else be empty. pub fn from_file(file: &Path, default_tag: Option<&Tag>) -> Result<VariationalAsset, Error> { let loaded = WorkAsset::from_file(file, default_tag)?; loaded.export() } /// Generates a new `VariationalAsset` from a byte slice of glTF. /// /// If the provided asset implements `KHR_materials_variants`, then `default_tag` must /// either be empty or match the default tag within the asset. /// /// If the asset doesn't implement `KHR_materials_variants`, then the argument /// `default_tag` must be non-empty. If it does, then `default_tag` must either match /// what's in the asset, or else be empty. pub fn from_slice( gltf: &[u8], default_tag: Option<&Tag>, base_dir: Option<&Path>, ) -> Result<VariationalAsset, Error> { let loaded = WorkAsset::from_slice(gltf, default_tag, base_dir)?; loaded.export() } /// The generated glTF for this asset. Will always implement `KHR_materials_variants` /// and is always in binary (GLB) form. pub fn glb(&self) -> &[u8] { self.glb.as_slice() } /// The tag that stands in for any default material references in the asset glTF. pub fn default_tag(&self) -> &Tag { &self.default_tag } /// All the metadata generated for this asset. pub fn metadata(&self) -> &Metadata { &self.metadata } /// Melds one variational asset into another, combining material-switching tags /// on a per-mesh, per-primitive basis. /// /// Note that logically identical glTF objects may be bitwise quite different, e.g. /// because glTF array order is undefined, floating-point values are only equal to /// within some epsilon, the final global position of a vector can be the end /// result of very different transformations, and so on. /// /// Further, the whole point of this tool is to identify shared pieces of data /// between the two assets, keep only one, and redirect all references to it. /// pub fn meld<'a>( base: &'a VariationalAsset, other: &'a VariationalAsset, ) -> Result<VariationalAsset, Error> { let base = &WorkAsset::from_slice(base.glb(), Some(base.default_tag()), None)?; let other = &WorkAsset::from_slice(other.glb(), Some(other.default_tag()), None)?; let meld = WorkAsset::meld(base, other)?; meld.export() } } impl AssetSizes { /// Instantiate a new `AssetSizes` with the given texture byte count. pub fn new(texture_bytes: usize) -> AssetSizes { AssetSizes { texture_bytes } } /// Byte count for texture image data, in its raw encoded form. pub fn texture_bytes(&self) -> usize { self.texture_bytes } }