generate resource ids + implement load_mesh

This commit is contained in:
Quaternions 2024-07-24 11:59:37 -07:00
parent 5e644c7eed
commit 2eef7843a2

View File

@ -11,7 +11,9 @@ use strafesnet_common::gameplay_modes;
pub enum Error{ pub enum Error{
InvalidHeader(binrw::Error), InvalidHeader(binrw::Error),
InvalidBlockId(BlockId), InvalidBlockId(BlockId),
InvalidRegion(binrw::Error), InvalidMeshId(model::MeshId),
InvalidTextureId(model::TextureId),
InvalidData(binrw::Error),
File(crate::file::Error), File(crate::file::Error),
} }
@ -73,17 +75,29 @@ for model_id in 0..num_models{
//if you hash the resource itself and set the first 8 bits to this, that's the resource uuid //if you hash the resource itself and set the first 8 bits to this, that's the resource uuid
#[binrw] #[binrw]
#[brw(little,repr=u8)] #[brw(little,repr=u8)]
enum Resource{ enum ResourceType{
Mesh, Mesh,
Texture, Texture,
Shader, //Shader,
Sound, //Sound,
Video, //Video,
Animation, //Animation,
} }
const RESOURCE_TYPE_VARIANT_COUNT:u8=2;
#[binrw] #[binrw]
#[brw(little)] #[brw(little)]
struct ResourceId(u128); struct ResourceId(u128);
impl ResourceId{
fn resource_type(&self)->Option<ResourceType>{
let discriminant=self.0 as u8;
//TODO: use this when it is stabilized https://github.com/rust-lang/rust/issues/73662
//if (discriminant as usize)<std::mem::variant_count::<ResourceType>(){
match discriminant<RESOURCE_TYPE_VARIANT_COUNT{
true=>Some(unsafe{std::mem::transmute::<u8,ResourceType>(discriminant)}),
false=>None,
}
}
}
struct ResourceMap<T>{ struct ResourceMap<T>{
meshes:HashMap<strafesnet_common::model::MeshId,T>, meshes:HashMap<strafesnet_common::model::MeshId,T>,
@ -107,7 +121,7 @@ struct SpacialBlockHeader{
#[binrw] #[binrw]
#[brw(little)] #[brw(little)]
struct ResourceBlockHeader{ struct ResourceBlockHeader{
resource:Resource, resource:ResourceType,
id:BlockId, id:BlockId,
} }
#[binrw] #[binrw]
@ -152,7 +166,7 @@ pub struct StreamableMap<R:BinReaderExt>{
bvh:BvhNode<BlockId>, bvh:BvhNode<BlockId>,
//something something resources hashmaps //something something resources hashmaps
resource_blocks:ResourceMap<BlockId>, resource_blocks:ResourceMap<BlockId>,
resource_external:ResourceMap<ResourceId>, //resource_external:ResourceMap<ResourceId>,
} }
impl<R:BinReaderExt> StreamableMap<R>{ impl<R:BinReaderExt> StreamableMap<R>{
pub(crate) fn new(mut file:crate::file::File<R>)->Result<Self,Error>{ pub(crate) fn new(mut file:crate::file::File<R>)->Result<Self,Error>{
@ -162,13 +176,31 @@ impl<R:BinReaderExt> StreamableMap<R>{
let bvh=header.spacial_blocks.into_iter().map(|spacial_block| let bvh=header.spacial_blocks.into_iter().map(|spacial_block|
(spacial_block.id,spacial_block.extents.into()) (spacial_block.id,spacial_block.extents.into())
).collect(); ).collect();
//TODO: generate mesh ids and texture ids from resource list order //generate mesh ids and texture ids from resource list order
let mut resource_blocks=ResourceMap::default();
for resource_block_header in header.resource_blocks{
match resource_block_header.resource{
ResourceType::Mesh=>{
resource_blocks.meshes.insert(
//generate the id from the current length
model::MeshId::new(resource_blocks.meshes.len() as u32),
resource_block_header.id
);
},
ResourceType::Texture=>{
resource_blocks.textures.insert(
model::TextureId::new(resource_blocks.textures.len() as u32),
resource_block_header.id
);
},
}
}
Ok(Self{ Ok(Self{
file, file,
modes:strafesnet_common::gameplay_modes::Modes::new(modes), modes:strafesnet_common::gameplay_modes::Modes::new(modes),
bvh:strafesnet_common::bvh::generate_bvh(bvh), bvh:strafesnet_common::bvh::generate_bvh(bvh),
resource_blocks:Default::default(), resource_blocks,
resource_external:Default::default(), //resource_external:Default::default(),
}) })
} }
pub fn get_intersecting_region_block_ids(&self,aabb:&Aabb)->Vec<BlockId>{ pub fn get_intersecting_region_block_ids(&self,aabb:&Aabb)->Vec<BlockId>{
@ -182,15 +214,13 @@ impl<R:BinReaderExt> StreamableMap<R>{
//load resources into self.resources //load resources into self.resources
//return Region //return Region
let mut block=self.file.block_reader(block_id).map_err(Error::File)?; let mut block=self.file.block_reader(block_id).map_err(Error::File)?;
let region:Region=block.read_le().map_err(Error::InvalidRegion)?; let region:Region=block.read_le().map_err(Error::InvalidData)?;
Ok(region.models.into_iter().map(Into::into).collect()) Ok(region.models.into_iter().map(Into::into).collect())
} }
/*
pub fn load_mesh(&mut self,mesh_id:model::MeshId)->Result<model::Mesh,Error>{ pub fn load_mesh(&mut self,mesh_id:model::MeshId)->Result<model::Mesh,Error>{
let block_id=self.resource_blocks.meshes.get(mesh_id).ok_or_err(Error::NotFound)?; let block_id=*self.resource_blocks.meshes.get(&mesh_id).ok_or(Error::InvalidMeshId(mesh_id))?;
let mut block=self.file.block_reader(block_id).map_err(Error::File)?; let mut block=self.file.block_reader(block_id).map_err(Error::File)?;
let mesh:newtypes::model::Mesh=block.read_le().map_err(Error::InvalidRegion)?; let mesh:newtypes::model::Mesh=block.read_le().map_err(Error::InvalidData)?;
Ok(mesh.into()) Ok(mesh.into())
} }
*/
} }