use std::io::Read; use std::collections::HashMap; use crate::roblox_mesh; use crate::texture::{RenderConfigs,Texture}; use strafesnet_common::model::{MeshId,RenderConfig,RenderConfigId,TextureId}; use crate::rbxassetid::RobloxAssetId; #[derive(Default)] pub struct RenderConfigLoader{ texture_count:u32, render_configs:Vec, render_config_id_from_asset_id:HashMap,RenderConfigId>, } impl RenderConfigLoader{ pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{ let render_id=RenderConfigId::new(self.render_config_id_from_asset_id.len() as u32); let index=name.and_then(|name|{ match name.parse::(){ Ok(asset_id)=>Some(asset_id), Err(e)=>{ println!("Failed to parse AssetId: {e}"); None }, } }); *self.render_config_id_from_asset_id.entry(index).or_insert_with(||{ //create the render config. let render_config=if name.is_some(){ let render_config=RenderConfig::texture(TextureId::new(self.texture_count)); self.texture_count+=1; render_config }else{ RenderConfig::default() }; self.render_configs.push(render_config); render_id }) } } #[derive(Default)] pub struct MeshLoader{ mesh_id_from_asset_id:HashMap,MeshId>, } impl MeshLoader{ pub fn acquire_mesh_id(&mut self,name:&str)->MeshId{ let mesh_id=MeshId::new(self.mesh_id_from_asset_id.len() as u32); let index=match name.parse::(){ Ok(asset_id)=>Some(asset_id), Err(e)=>{ println!("Failed to parse AssetId: {e}"); None }, }; *self.mesh_id_from_asset_id.entry(index).or_insert(mesh_id) } pub fn load_meshes(&mut self)->Result{ let mut mesh_data=vec![None;self.mesh_id_from_asset_id.len()]; for (asset_id_option,mesh_id) in &self.mesh_id_from_asset_id{ if let Some(asset_id)=asset_id_option{ if let Ok(mut file)=std::fs::File::open(format!("meshes/{}",asset_id.0)){ //TODO: parallel let mut data=Vec::::new(); file.read_to_end(&mut data)?; mesh_data[mesh_id.get() as usize]=Some(roblox_mesh::RobloxMeshData::new(data)); }else{ println!("[roblox_legacy] no mesh name={}",asset_id.0); } } } Ok(roblox_mesh::Meshes::new(mesh_data)) } } pub struct Loader{ render_config_loader:RenderConfigLoader, mesh_loader:MeshLoader, } impl Loader{ pub fn new()->Self{ Self{ render_config_loader:RenderConfigLoader::default(), mesh_loader:MeshLoader::default(), } } pub fn get_inner_mut(&mut self)->(&mut RenderConfigLoader,&mut MeshLoader){ (&mut self.render_config_loader,&mut self.mesh_loader) } pub fn into_render_configs(mut self)->Result{ let mut sorted_textures=vec![None;self.render_config_loader.texture_count as usize]; for (asset_id_option,render_config_id) in self.render_config_loader.render_config_id_from_asset_id{ let render_config=self.render_config_loader.render_configs.get_mut(render_config_id.get() as usize).unwrap(); if let (Some(asset_id),Some(texture_id))=(asset_id_option,render_config.texture){ if let Ok(mut file)=std::fs::File::open(format!("textures/{}.dds",asset_id.0)){ //TODO: parallel let mut data=Vec::::new(); file.read_to_end(&mut data)?; sorted_textures[texture_id.get() as usize]=Some(Texture::ImageDDS(data)); }else{ //texture failed to load render_config.texture=None; } } } Ok(RenderConfigs::new( sorted_textures, self.render_config_loader.render_configs, )) } }