mod loader;
pub use loader::*;
mod raw_assets;
pub use raw_assets::*;
#[cfg(not(target_arch = "wasm32"))]
mod saver;
#[cfg(not(target_arch = "wasm32"))]
pub use saver::*;
#[cfg(feature = "obj")]
mod obj;
#[cfg(feature = "gltf")]
mod gltf;
#[cfg(feature = "image")]
mod img;
#[cfg(feature = "vol")]
mod vol;
#[cfg(feature = "pcd")]
mod pcd;
#[cfg(not(target_arch = "wasm32"))]
pub fn load_and_deserialize<T: Deserialize>(path: impl AsRef<std::path::Path>) -> crate::Result<T> {
load(&[&path])?.deserialize(path)
}
pub async fn load_and_deserialize_async<T: Deserialize>(
path: impl AsRef<std::path::Path>,
) -> crate::Result<T> {
load_async(&[&path]).await?.deserialize(path)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn serialize_and_save<T: Serialize>(
path: impl AsRef<std::path::Path>,
data: T,
) -> crate::Result<()> {
save(&data.serialize(path)?)
}
pub trait Deserialize: Sized {
fn deserialize(
path: impl AsRef<std::path::Path>,
raw_assets: &mut RawAssets,
) -> crate::Result<Self>;
}
pub trait Serialize: Sized {
fn serialize(&self, path: impl AsRef<std::path::Path>) -> crate::Result<RawAssets>;
}
use crate::{Error, Geometry, Result};
use std::collections::HashSet;
use std::path::{Path, PathBuf};
impl Deserialize for crate::Texture2D {
fn deserialize(path: impl AsRef<std::path::Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let path = raw_assets.match_path(path.as_ref())?;
#[allow(unused_variables)]
let bytes = raw_assets.get(&path)?;
#[cfg(not(feature = "image"))]
return Err(Error::FeatureMissing(
path.extension()
.map(|e| e.to_str().unwrap())
.unwrap_or("image")
.to_string(),
));
#[cfg(feature = "image")]
img::deserialize_img(path, bytes)
}
}
impl Serialize for crate::Texture2D {
fn serialize(&self, path: impl AsRef<Path>) -> Result<RawAssets> {
let path = path.as_ref();
#[cfg(not(feature = "image"))]
return Err(Error::FeatureMissing(
path.extension()
.map(|e| e.to_str().unwrap())
.unwrap_or("image")
.to_string(),
));
#[cfg(feature = "image")]
img::serialize_img(self, path)
}
}
impl Deserialize for crate::Scene {
fn deserialize(path: impl AsRef<Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let path = raw_assets.match_path(path.as_ref())?;
match path.extension().map(|e| e.to_str().unwrap()).unwrap_or("") {
"gltf" | "glb" => {
#[cfg(not(feature = "gltf"))]
return Err(Error::FeatureMissing("gltf".to_string()));
#[cfg(feature = "gltf")]
gltf::deserialize_gltf(raw_assets, &path)
}
"obj" => {
#[cfg(not(feature = "obj"))]
return Err(Error::FeatureMissing("obj".to_string()));
#[cfg(feature = "obj")]
obj::deserialize_obj(raw_assets, &path)
}
"pcd" => {
#[cfg(not(feature = "pcd"))]
return Err(Error::FeatureMissing("pcd".to_string()));
#[cfg(feature = "pcd")]
pcd::deserialize_pcd(raw_assets, &path)
}
_ => Err(Error::FailedDeserialize(path.to_str().unwrap().to_string())),
}
}
}
impl Deserialize for crate::Model {
fn deserialize(path: impl AsRef<Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let scene = crate::Scene::deserialize(path, raw_assets)?;
Ok(scene.into())
}
}
impl Deserialize for crate::VoxelGrid {
fn deserialize(path: impl AsRef<Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let path = raw_assets.match_path(path.as_ref())?;
match path.extension().map(|e| e.to_str().unwrap()).unwrap_or("") {
"vol" => {
#[cfg(not(feature = "vol"))]
return Err(Error::FeatureMissing("vol".to_string()));
#[cfg(feature = "vol")]
vol::deserialize_vol(raw_assets, &path)
}
_ => Err(Error::FailedDeserialize(path.to_str().unwrap().to_string())),
}
}
}
impl Deserialize for crate::Texture3D {
fn deserialize(path: impl AsRef<Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let path = raw_assets.match_path(path.as_ref())?;
let voxel_grid = crate::VoxelGrid::deserialize(path, raw_assets)?;
Ok(voxel_grid.voxels)
}
}
impl Deserialize for crate::TriMesh {
fn deserialize(path: impl AsRef<Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let path = path.as_ref();
let model = crate::Model::deserialize(path, raw_assets)?;
model
.geometries
.into_iter()
.find_map(|p| {
if let Geometry::Triangles(mesh) = p.geometry {
Some(mesh)
} else {
None
}
})
.ok_or_else(|| {
Error::FailedConvertion(
"a triangle mesh".to_owned(),
path.to_str().unwrap().to_owned(),
)
})
}
}
impl Deserialize for crate::PointCloud {
fn deserialize(path: impl AsRef<Path>, raw_assets: &mut RawAssets) -> Result<Self> {
let path = path.as_ref();
let model = crate::Model::deserialize(path, raw_assets)?;
model
.geometries
.into_iter()
.find_map(|p| {
if let Geometry::Points(point_cloud) = p.geometry {
Some(point_cloud)
} else {
None
}
})
.ok_or_else(|| {
Error::FailedConvertion(
"a point cloud".to_owned(),
path.to_str().unwrap().to_owned(),
)
})
}
}
fn get_dependencies(raw_assets: &RawAssets) -> Vec<PathBuf> {
#[allow(unused_mut)]
let mut dependencies = HashSet::new();
for (path, _) in raw_assets.iter() {
match path.extension().map(|e| e.to_str().unwrap()).unwrap_or("") {
"gltf" | "glb" => {
#[cfg(feature = "gltf")]
dependencies.extend(gltf::dependencies(raw_assets, path));
}
"obj" => {
#[cfg(feature = "obj")]
dependencies.extend(obj::dependencies_obj(raw_assets, path));
}
"mtl" => {
#[cfg(feature = "obj")]
dependencies.extend(obj::dependencies_mtl(raw_assets, path));
}
_ => {}
}
}
dependencies
.into_iter()
.filter(|d| !raw_assets.contains_key(d))
.collect()
}