implement legacy roblox mesh loader
This commit is contained in:
parent
e37d8540c2
commit
790c72a1b8
@ -8,7 +8,10 @@ mod roblox;
|
|||||||
mod source;
|
mod source;
|
||||||
|
|
||||||
pub mod texture;
|
pub mod texture;
|
||||||
|
#[cfg(any(feature="source",feature="legacy"))]
|
||||||
pub mod valve_mesh;
|
pub mod valve_mesh;
|
||||||
|
#[cfg(any(feature="roblox",feature="legacy"))]
|
||||||
|
pub mod roblox_mesh;
|
||||||
|
|
||||||
#[cfg(feature="legacy")]
|
#[cfg(feature="legacy")]
|
||||||
pub fn roblox_legacy()->roblox_legacy::Loader{
|
pub fn roblox_legacy()->roblox_legacy::Loader{
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::texture::{Texture,RenderConfigs};
|
use crate::roblox_mesh;
|
||||||
use strafesnet_common::model::{TextureId,RenderConfigId,RenderConfig};
|
use crate::texture::{RenderConfigs,Texture};
|
||||||
|
use strafesnet_common::model::{MeshId,RenderConfig,RenderConfigId,TextureId};
|
||||||
|
|
||||||
#[derive(Hash,Eq,PartialEq)]
|
#[derive(Hash,Eq,PartialEq)]
|
||||||
struct RobloxAssetId(u64);
|
struct RobloxAssetId(u64);
|
||||||
@ -28,22 +29,14 @@ impl std::fmt::Display for RobloxAssetIdParseErr{
|
|||||||
}
|
}
|
||||||
impl std::error::Error for RobloxAssetIdParseErr{}
|
impl std::error::Error for RobloxAssetIdParseErr{}
|
||||||
|
|
||||||
pub struct Loader{
|
#[derive(Default)]
|
||||||
|
pub struct RenderConfigLoader{
|
||||||
texture_count:u32,
|
texture_count:u32,
|
||||||
render_configs:Vec<RenderConfig>,
|
render_configs:Vec<RenderConfig>,
|
||||||
render_config_id_from_asset_id:HashMap<Option<RobloxAssetId>,RenderConfigId>,
|
render_config_id_from_asset_id:HashMap<Option<RobloxAssetId>,RenderConfigId>,
|
||||||
}
|
}
|
||||||
impl Loader{
|
|
||||||
pub fn new()->Self{
|
|
||||||
Self{
|
|
||||||
texture_count:0,
|
|
||||||
render_configs:Vec::new(),
|
|
||||||
render_config_id_from_asset_id:HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Loader{
|
impl RenderConfigLoader{
|
||||||
pub fn acquire_render_config_id(&mut self,name:Option<&str>)->RenderConfigId{
|
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 render_id=RenderConfigId::new(self.render_config_id_from_asset_id.len() as u32);
|
||||||
let index=name.and_then(|name|{
|
let index=name.and_then(|name|{
|
||||||
@ -68,11 +61,62 @@ impl Loader{
|
|||||||
render_id
|
render_id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct MeshLoader{
|
||||||
|
mesh_id_from_asset_id:HashMap<Option<RobloxAssetId>,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::<RobloxAssetId>(){
|
||||||
|
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<roblox_mesh::Meshes,std::io::Error>{
|
||||||
|
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::<u8>::new();
|
||||||
|
file.read_to_end(&mut data)?;
|
||||||
|
mesh_data[mesh_id.get() as usize]=Some(roblox_mesh::RobloxMeshData::new(data));
|
||||||
|
}else{
|
||||||
|
println!("no model 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<RenderConfigs,std::io::Error>{
|
pub fn into_render_configs(mut self)->Result<RenderConfigs,std::io::Error>{
|
||||||
let mut sorted_textures=vec![None;self.texture_count as usize];
|
let mut sorted_textures=vec![None;self.render_config_loader.texture_count as usize];
|
||||||
for (asset_id,render_config_id) in self.render_config_id_from_asset_id{
|
for (asset_id_option,render_config_id) in self.render_config_loader.render_config_id_from_asset_id{
|
||||||
let render_config=self.render_configs.get_mut(render_config_id.get() as usize).unwrap();
|
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,render_config.texture){
|
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)){
|
if let Ok(mut file)=std::fs::File::open(format!("textures/{}.dds",asset_id.0)){
|
||||||
//TODO: parallel
|
//TODO: parallel
|
||||||
let mut data=Vec::<u8>::new();
|
let mut data=Vec::<u8>::new();
|
||||||
@ -86,7 +130,7 @@ impl Loader{
|
|||||||
}
|
}
|
||||||
Ok(RenderConfigs::new(
|
Ok(RenderConfigs::new(
|
||||||
sorted_textures,
|
sorted_textures,
|
||||||
self.render_configs,
|
self.render_config_loader.render_configs,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
30
src/roblox_mesh.rs
Normal file
30
src/roblox_mesh.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use strafesnet_common::model::MeshId;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RobloxMeshData(Vec<u8>);
|
||||||
|
impl RobloxMeshData{
|
||||||
|
pub(crate) fn new(data:Vec<u8>)->Self{
|
||||||
|
Self(data)
|
||||||
|
}
|
||||||
|
pub fn get(self)->Vec<u8>{
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub struct Meshes{
|
||||||
|
meshes:Vec<Option<RobloxMeshData>>,
|
||||||
|
}
|
||||||
|
impl Meshes{
|
||||||
|
pub(crate) const fn new(meshes:Vec<Option<RobloxMeshData>>)->Self{
|
||||||
|
Self{
|
||||||
|
meshes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn get_texture(&self,texture_id:MeshId)->Option<&RobloxMeshData>{
|
||||||
|
self.meshes.get(texture_id.get() as usize)?.as_ref()
|
||||||
|
}
|
||||||
|
pub fn into_iter(self)->impl Iterator<Item=(MeshId,RobloxMeshData)>{
|
||||||
|
self.meshes.into_iter().enumerate().filter_map(|(mesh_id,maybe_mesh)|
|
||||||
|
maybe_mesh.map(|mesh|(MeshId::new(mesh_id as u32),mesh))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user