complete map loader
This commit is contained in:
parent
d60486acc3
commit
5d9c124e76
83
src/map.rs
83
src/map.rs
@ -1,3 +1,4 @@
|
|||||||
|
use std::io::Read;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::newtypes;
|
use crate::newtypes;
|
||||||
@ -14,6 +15,7 @@ pub enum Error{
|
|||||||
InvalidMeshId(model::MeshId),
|
InvalidMeshId(model::MeshId),
|
||||||
InvalidTextureId(model::TextureId),
|
InvalidTextureId(model::TextureId),
|
||||||
InvalidData(binrw::Error),
|
InvalidData(binrw::Error),
|
||||||
|
IO(std::io::Error),
|
||||||
File(crate::file::Error),
|
File(crate::file::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +140,8 @@ struct MapHeader{
|
|||||||
num_resource_blocks:u32,
|
num_resource_blocks:u32,
|
||||||
num_resources_external:u32,
|
num_resources_external:u32,
|
||||||
num_modes:u32,
|
num_modes:u32,
|
||||||
|
num_attributes:u32,
|
||||||
|
num_render_configs:u32,
|
||||||
#[br(count=num_nodes)]
|
#[br(count=num_nodes)]
|
||||||
nodes:Vec<u32>,
|
nodes:Vec<u32>,
|
||||||
#[br(count=num_spacial_blocks)]
|
#[br(count=num_spacial_blocks)]
|
||||||
@ -148,6 +152,10 @@ struct MapHeader{
|
|||||||
external_resources:Vec<ResourceExternalHeader>,
|
external_resources:Vec<ResourceExternalHeader>,
|
||||||
#[br(count=num_modes)]
|
#[br(count=num_modes)]
|
||||||
modes:Vec<newtypes::gameplay_modes::Mode>,
|
modes:Vec<newtypes::gameplay_modes::Mode>,
|
||||||
|
#[br(count=num_attributes)]
|
||||||
|
attributes:Vec<newtypes::gameplay_attributes::CollisionAttributes>,
|
||||||
|
#[br(count=num_render_configs)]
|
||||||
|
render_configs:Vec<newtypes::model::RenderConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
@ -159,10 +167,37 @@ struct Region{
|
|||||||
models:Vec<newtypes::model::Model>,
|
models:Vec<newtypes::model::Model>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//code deduplication reused in into_complete_map
|
||||||
|
fn read_region<R:BinReaderExt>(file:&mut crate::file::File<R>,block_id:BlockId)->Result<Vec<model::Model>,Error>{
|
||||||
|
//load region from disk
|
||||||
|
//parse the models and determine what resources need to be loaded
|
||||||
|
//load resources into self.resources
|
||||||
|
//return Region
|
||||||
|
let mut block=file.block_reader(block_id).map_err(Error::File)?;
|
||||||
|
let region:Region=block.read_le().map_err(Error::InvalidData)?;
|
||||||
|
Ok(region.models.into_iter().map(Into::into).collect())
|
||||||
|
}
|
||||||
|
fn read_mesh<R:BinReaderExt>(file:&mut crate::file::File<R>,block_id:BlockId)->Result<model::Mesh,Error>{
|
||||||
|
let mut block=file.block_reader(block_id).map_err(Error::File)?;
|
||||||
|
let mesh:newtypes::model::Mesh=block.read_le().map_err(Error::InvalidData)?;
|
||||||
|
Ok(mesh.into())
|
||||||
|
}
|
||||||
|
fn read_texture<R:BinReaderExt>(file:&mut crate::file::File<R>,block_id:BlockId)->Result<Vec<u8>,Error>{
|
||||||
|
let mut block=file.block_reader(block_id).map_err(Error::File)?;
|
||||||
|
let mut texture=Vec::new();
|
||||||
|
block.read_to_end(&mut texture).map_err(Error::IO)?;
|
||||||
|
Ok(texture)
|
||||||
|
}
|
||||||
|
|
||||||
pub struct StreamableMap<R:BinReaderExt>{
|
pub struct StreamableMap<R:BinReaderExt>{
|
||||||
file:crate::file::File<R>,
|
file:crate::file::File<R>,
|
||||||
//this includes every platform... move the unconstrained datas to their appropriate data block?
|
//this includes every platform... move the unconstrained datas to their appropriate data block?
|
||||||
modes:gameplay_modes::Modes,
|
modes:gameplay_modes::Modes,
|
||||||
|
//this is every possible attribute... need some sort of streaming system
|
||||||
|
attributes:Vec<strafesnet_common::gameplay_attributes::CollisionAttributes>,
|
||||||
|
//this is every possible render configuration... shaders and such... need streaming
|
||||||
|
render_configs:Vec<strafesnet_common::model::RenderConfig>,
|
||||||
|
//this makes sense to keep in memory for streaming, a map of which blocks occupy what space
|
||||||
bvh:BvhNode<BlockId>,
|
bvh:BvhNode<BlockId>,
|
||||||
//something something resources hashmaps
|
//something something resources hashmaps
|
||||||
resource_blocks:ResourceMap<BlockId>,
|
resource_blocks:ResourceMap<BlockId>,
|
||||||
@ -173,6 +208,8 @@ impl<R:BinReaderExt> StreamableMap<R>{
|
|||||||
//assume the file seek is in the right place to start reading a map header
|
//assume the file seek is in the right place to start reading a map header
|
||||||
let header:MapHeader=file.as_mut().read_le().map_err(Error::InvalidHeader)?;
|
let header:MapHeader=file.as_mut().read_le().map_err(Error::InvalidHeader)?;
|
||||||
let modes=header.modes.into_iter().map(Into::into).collect();
|
let modes=header.modes.into_iter().map(Into::into).collect();
|
||||||
|
let attributes=header.attributes.into_iter().map(Into::into).collect();
|
||||||
|
let render_configs=header.render_configs.into_iter().map(Into::into).collect();
|
||||||
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();
|
||||||
@ -198,6 +235,8 @@ impl<R:BinReaderExt> StreamableMap<R>{
|
|||||||
Ok(Self{
|
Ok(Self{
|
||||||
file,
|
file,
|
||||||
modes:strafesnet_common::gameplay_modes::Modes::new(modes),
|
modes:strafesnet_common::gameplay_modes::Modes::new(modes),
|
||||||
|
attributes,
|
||||||
|
render_configs,
|
||||||
bvh:strafesnet_common::bvh::generate_bvh(bvh),
|
bvh:strafesnet_common::bvh::generate_bvh(bvh),
|
||||||
resource_blocks,
|
resource_blocks,
|
||||||
//resource_external:Default::default(),
|
//resource_external:Default::default(),
|
||||||
@ -209,18 +248,42 @@ impl<R:BinReaderExt> StreamableMap<R>{
|
|||||||
block_ids
|
block_ids
|
||||||
}
|
}
|
||||||
pub fn load_region(&mut self,block_id:BlockId)->Result<Vec<model::Model>,Error>{
|
pub fn load_region(&mut self,block_id:BlockId)->Result<Vec<model::Model>,Error>{
|
||||||
//load region from disk
|
read_region(&mut self.file,block_id)
|
||||||
//parse the models and determine what resources need to be loaded
|
|
||||||
//load resources into self.resources
|
|
||||||
//return Region
|
|
||||||
let mut block=self.file.block_reader(block_id).map_err(Error::File)?;
|
|
||||||
let region:Region=block.read_le().map_err(Error::InvalidData)?;
|
|
||||||
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(Error::InvalidMeshId(mesh_id))?;
|
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)?;
|
read_mesh(&mut self.file,block_id)
|
||||||
let mesh:newtypes::model::Mesh=block.read_le().map_err(Error::InvalidData)?;
|
}
|
||||||
Ok(mesh.into())
|
pub fn load_texture(&mut self,texture_id:model::TextureId)->Result<Vec<u8>,Error>{
|
||||||
|
let block_id=*self.resource_blocks.textures.get(&texture_id).ok_or(Error::InvalidTextureId(texture_id))?;
|
||||||
|
read_texture(&mut self.file,block_id)
|
||||||
|
}
|
||||||
|
pub fn into_complete_map(mut self)->Result<strafesnet_common::map::CompleteMap,Error>{
|
||||||
|
//load all meshes
|
||||||
|
let meshes=self.resource_blocks.meshes.into_values().map(|block_id|
|
||||||
|
read_mesh(&mut self.file,block_id)
|
||||||
|
).collect::<Result<Vec<_>,_>>()?;
|
||||||
|
//load all textures
|
||||||
|
let textures=self.resource_blocks.textures.into_values().map(|block_id|
|
||||||
|
read_texture(&mut self.file,block_id)
|
||||||
|
).collect::<Result<Vec<_>,_>>()?;
|
||||||
|
//load all regions
|
||||||
|
let mut region_results=Vec::new();
|
||||||
|
self.bvh.into_visitor(&mut |block_id|
|
||||||
|
region_results.push(read_region(&mut self.file,block_id))
|
||||||
|
);
|
||||||
|
//allocate twice :'(
|
||||||
|
let mut models=Vec::new();
|
||||||
|
for region_result in region_results{
|
||||||
|
models.append(&mut region_result?);
|
||||||
|
}
|
||||||
|
Ok(strafesnet_common::map::CompleteMap{
|
||||||
|
modes:self.modes,
|
||||||
|
attributes:self.attributes,
|
||||||
|
meshes,
|
||||||
|
models,
|
||||||
|
textures,
|
||||||
|
render_configs:self.render_configs,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user