use std::collections::{BTreeMap, HashMap};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AssetFormat {
GLTF,
USDZ,
FBX,
OBJ,
GLB,
VRM,
}
impl Default for AssetFormat {
fn default() -> Self {
Self::GLTF
}
}
#[derive(Debug, Clone)]
pub struct Asset {
pub id: String,
pub format: AssetFormat,
pub data: Vec<u8>,
}
#[derive(Debug, Clone)]
pub struct AssetTransform {
pub position: [f32; 3],
pub rotation: [f32; 4],
pub scale: [f32; 3],
}
impl Default for AssetTransform {
fn default() -> Self {
Self {
position: [0.0, 0.0, 0.0],
rotation: [0.0, 0.0, 0.0, 1.0],
scale: [1.0, 1.0, 1.0],
}
}
}
pub struct AssetInterop {
supported_formats: Vec<AssetFormat>,
}
impl AssetInterop {
pub fn new() -> Self {
Self {
supported_formats: vec![
AssetFormat::GLTF,
AssetFormat::USDZ,
AssetFormat::FBX,
AssetFormat::OBJ,
AssetFormat::GLB,
AssetFormat::VRM,
],
}
}
pub fn supports_format(&self, format: AssetFormat) -> bool {
self.supported_formats.contains(&format)
}
pub fn convert(&self, asset: &Asset, target_format: AssetFormat) -> Result<Asset, AssetError> {
if !self.supports_format(asset.format) {
return Err(AssetError::UnsupportedFormat(format!("{:?}", asset.format)));
}
if !self.supports_format(target_format) {
return Err(AssetError::UnsupportedFormat(format!("{:?}", target_format)));
}
Ok(Asset {
id: asset.id.clone(),
format: target_format,
data: asset.data.clone(),
})
}
pub fn validate(&self, asset: &Asset) -> Result<(), AssetError> {
if asset.data.is_empty() {
return Err(AssetError::InvalidAsset("Empty data".to_string()));
}
Ok(())
}
pub fn get_metadata(&self, asset: &Asset) -> AssetMetadata {
AssetMetadata {
format: asset.format,
size_bytes: asset.data.len(),
id: asset.id.clone(),
}
}
}
impl Default for AssetInterop {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone)]
pub struct AssetMetadata {
pub format: AssetFormat,
pub size_bytes: usize,
pub id: String,
}
#[derive(Debug, Clone)]
pub enum AssetError {
UnsupportedFormat(String),
ConversionFailed(String),
InvalidAsset(String),
LoadFailed(String),
}
impl std::fmt::Display for AssetError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::UnsupportedFormat(fmt) => write!(f, "不支持的格式: {}", fmt),
Self::ConversionFailed(msg) => write!(f, "转换失败: {}", msg),
Self::InvalidAsset(msg) => write!(f, "无效资产: {}", msg),
Self::LoadFailed(msg) => write!(f, "加载失败: {}", msg),
}
}
}
impl std::error::Error for AssetError {}