load good

This commit is contained in:
Quaternions 2025-01-29 13:44:57 -08:00
parent 82d68311fd
commit 7e3eeed23f

@ -60,7 +60,9 @@ pub enum MeshError{
RobloxAssetIdParse(RobloxAssetIdParseErr),
Mesh(crate::mesh::Error),
Union(crate::union::Error),
DecodeBinary(rbx_binary::DecodeError),
OneChildPolicy,
MissingInstance,
}
impl std::fmt::Display for MeshError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
@ -88,6 +90,11 @@ impl From<crate::union::Error> for MeshError{
Self::Union(value)
}
}
impl From<rbx_binary::DecodeError> for MeshError{
fn from(value:rbx_binary::DecodeError)->Self{
Self::DecodeBinary(value)
}
}
#[derive(Hash,Eq,PartialEq)]
pub enum MeshType<'a>{
@ -132,14 +139,41 @@ impl<'a> Loader for MeshLoader<'a>{
type Index=MeshIndex<'a>;
type Resource=Mesh;
fn load(&mut self,index:Self::Index)->Result<Self::Resource,Self::Error>{
let RobloxAssetId(asset_id)=index.content.parse()?;
let file_name=format!("meshes/{}",asset_id);
// reading the entire file is way faster than
// round tripping to disk every read from the parser
let data=read_entire_file(file_name)?;
let mesh=match index.mesh_type{
MeshType::FileMesh=>crate::mesh::convert(RobloxMeshBytes::new(data))?,
MeshType::Union{physics_data,mesh_data}=>crate::union::convert(physics_data,mesh_data)?,
MeshType::FileMesh=>{
let RobloxAssetId(asset_id)=index.content.parse()?;
let file_name=format!("meshes/{}",asset_id);
let data=read_entire_file(file_name)?;
crate::mesh::convert(RobloxMeshBytes::new(data))?
},
MeshType::Union{mut physics_data,mut mesh_data}=>{
// decode asset
if !index.content.is_empty()&&(physics_data.is_empty()||mesh_data.is_empty()){
let RobloxAssetId(asset_id)=index.content.parse()?;
let file_name=format!("unions/{}",asset_id);
let data=read_entire_file(file_name)?;
let dom=rbx_binary::from_reader(std::io::Cursor::new(data))?;
let &[referent]=dom.root().children()else{
return Err(MeshError::OneChildPolicy);
};
let Some(instance)=dom.get_by_ref(referent)else{
return Err(MeshError::MissingInstance);
};
if physics_data.is_empty(){
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get("PhysicsData"){
physics_data=data.as_ref();
}
}
if mesh_data.is_empty(){
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=instance.properties.get("MeshData"){
mesh_data=data.as_ref();
}
}
crate::union::convert(physics_data,mesh_data)?
}else{
crate::union::convert(physics_data,mesh_data)?
}
},
};
Ok(mesh)
}