implement map file format
This commit is contained in:
parent
1883c06f12
commit
4f90956e16
@ -84,6 +84,9 @@ impl<R:BinReaderExt> File<R>{
|
||||
data:input,
|
||||
})
|
||||
}
|
||||
pub(crate) fn as_mut(&mut self)->&mut R{
|
||||
&mut self.data
|
||||
}
|
||||
pub(crate) fn block_reader(&mut self,block_id:BlockId)->Result<binrw::io::TakeSeek<&mut R>,Error>{
|
||||
if self.header.block_location.len() as u32<=block_id.get(){
|
||||
return Err(Error::InvalidBlockId(block_id))
|
||||
|
142
src/map.rs
142
src/map.rs
@ -1,10 +1,14 @@
|
||||
//use strafesnet_common::model;
|
||||
//use strafesnet_common::gameplay_modes;
|
||||
use binrw::{BinReaderExt, binrw};
|
||||
use crate::newtypes;
|
||||
use crate::file::BlockId;
|
||||
use binrw::{binrw,BinReaderExt};
|
||||
use strafesnet_common::model;
|
||||
use strafesnet_common::aabb::Aabb;
|
||||
use strafesnet_common::bvh::BvhNode;
|
||||
use strafesnet_common::gameplay_modes;
|
||||
|
||||
pub enum Error{
|
||||
InvalidHeader,
|
||||
InvalidBvhNodeId(BvhNodeId),
|
||||
InvalidHeader(binrw::Error),
|
||||
InvalidBlockId(BlockId),
|
||||
InvalidRegion(binrw::Error),
|
||||
File(crate::file::Error),
|
||||
}
|
||||
@ -14,10 +18,13 @@ pub enum Error{
|
||||
BLOCK_MAP_HEADER:
|
||||
DefaultStyleInfo style_info
|
||||
//bvh goes here
|
||||
u64 num_nodes
|
||||
u32 num_nodes
|
||||
u32 num_spacial_blocks
|
||||
u32 num_resource_blocks
|
||||
u32 num_resources_external
|
||||
//node 0 parent node is implied to be None
|
||||
for node_id in 1..num_nodes{
|
||||
u64 parent_node
|
||||
u32 parent_node
|
||||
}
|
||||
|
||||
//NOTE: alternate realities are not necessary.
|
||||
@ -26,17 +33,20 @@ for node_id in 1..num_nodes{
|
||||
|
||||
//ideally spacial blocks are sorted from distance to start zone
|
||||
//texture blocks are inserted before the first spacial block they are used in
|
||||
u64 num_spacial_blocks
|
||||
for spacial_block_id in 0..num_spacial_blocks{
|
||||
u64 node_id
|
||||
u64 block_id //data block
|
||||
Aabb block_extents
|
||||
u32 node_id
|
||||
u32 block_id //data block
|
||||
Aabb extents
|
||||
}
|
||||
//if the map file references external resources, num_resources = 0
|
||||
u64 num_resources
|
||||
for resource_id in 0..num_resources{
|
||||
u64 block_id
|
||||
u128 resource_id
|
||||
//the order of these lists uniquely generates the incremental Ids
|
||||
//MeshId, TextureId etc. based on resource type
|
||||
//the first 8 bits of resource_uuid describe the type (mesh, texture, etc)
|
||||
//if the map file references only external resources, num_resource_blocks = 0
|
||||
for resource_idx in 0..num_resource_blocks{
|
||||
u32 block_id
|
||||
}
|
||||
for resource_idx in 0..num_resources_external{
|
||||
u128 resource_uuid
|
||||
}
|
||||
|
||||
BLOCK_MAP_RESOURCE:
|
||||
@ -52,71 +62,105 @@ Resource resource_type
|
||||
BLOCK_MAP_REGION:
|
||||
u64 num_models
|
||||
for model_id in 0..num_models{
|
||||
u128 model_resource_uuid
|
||||
ModelInstance mode_instance
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//error hiding mock code
|
||||
mod gameplay_modes{
|
||||
pub struct Modes{}
|
||||
//if you hash the resource itself and set the first 8 bits to this, that's the resource uuid
|
||||
#[binrw]
|
||||
#[brw(little,repr=u8)]
|
||||
enum Resource{
|
||||
Mesh,
|
||||
Image,
|
||||
Shader,
|
||||
Sound,
|
||||
Video,
|
||||
Animation,
|
||||
}
|
||||
mod model{
|
||||
pub struct Mesh{}
|
||||
#[super::binrw]
|
||||
#[brw(little)]
|
||||
pub struct Model{}
|
||||
}
|
||||
mod image{
|
||||
pub struct Image{}
|
||||
}
|
||||
|
||||
//serious code
|
||||
|
||||
struct ModelUuid(u128);
|
||||
struct ImageUuid(u128);
|
||||
|
||||
#[binrw]
|
||||
#[brw(little)]
|
||||
#[derive(Clone,Copy,id::Id)]
|
||||
pub struct BvhNodeId(u32);
|
||||
struct BvhNode{
|
||||
//aabb
|
||||
//child
|
||||
struct SpacialBlockHeader{
|
||||
id:BlockId,
|
||||
extents:newtypes::aabb::Aabb,
|
||||
}
|
||||
#[binrw]
|
||||
#[brw(little)]
|
||||
struct ResourceBlockHeader{
|
||||
resource:Resource,
|
||||
id:BlockId,
|
||||
}
|
||||
#[binrw]
|
||||
#[brw(little)]
|
||||
struct ResourceExternalHeader{
|
||||
resource_uuid:u128,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[brw(little)]
|
||||
struct MapHeader{
|
||||
num_nodes:u32,
|
||||
num_spacial_blocks:u32,
|
||||
num_resource_blocks:u32,
|
||||
num_resources_external:u32,
|
||||
num_modes:u32,
|
||||
#[br(count=num_nodes)]
|
||||
nodes:Vec<u32>,
|
||||
#[br(count=num_spacial_blocks)]
|
||||
spacial_blocks:Vec<SpacialBlockHeader>,
|
||||
#[br(count=num_resource_blocks)]
|
||||
resource_blocks:Vec<ResourceBlockHeader>,
|
||||
#[br(count=num_resources_external)]
|
||||
external_resources:Vec<ResourceExternalHeader>,
|
||||
#[br(count=num_modes)]
|
||||
modes:Vec<newtypes::gameplay_modes::Mode>,
|
||||
}
|
||||
|
||||
#[binrw]
|
||||
#[brw(little)]
|
||||
struct Region{
|
||||
//consider including a bvh in the region instead of needing to rebalance the physics bvh on the fly
|
||||
model_count:u32,
|
||||
#[br(count=model_count)]
|
||||
models:Vec<model::Model>,
|
||||
models:Vec<newtypes::model::Model>,
|
||||
}
|
||||
|
||||
pub struct StreamableMap<R:BinReaderExt>{
|
||||
file:crate::file::File<R>,
|
||||
//this includes every platform... move the unconstrained datas to their appropriate data block?
|
||||
modes:gameplay_modes::Modes,
|
||||
bvh:BvhNode,
|
||||
node_id_to_block_id:Vec<crate::file::BlockId>,
|
||||
bvh:BvhNode<BlockId>,
|
||||
}
|
||||
impl<R:BinReaderExt> StreamableMap<R>{
|
||||
pub(crate) fn new(file:crate::file::File<R>)->Result<Self,Error>{
|
||||
Err(Error::InvalidHeader)
|
||||
pub(crate) fn new(mut file:crate::file::File<R>)->Result<Self,Error>{
|
||||
//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 modes=header.modes.into_iter().map(Into::into).collect();
|
||||
let bvh=header.spacial_blocks.into_iter().map(|spacial_block|
|
||||
(spacial_block.id,spacial_block.extents.into())
|
||||
).collect();
|
||||
Ok(Self{
|
||||
file,
|
||||
modes:strafesnet_common::gameplay_modes::Modes::new(modes),
|
||||
bvh:strafesnet_common::bvh::generate_bvh(bvh),
|
||||
})
|
||||
}
|
||||
pub fn load_node(&mut self,node_id:BvhNodeId)->Result<Vec<model::Model>,Error>{
|
||||
pub fn get_intersecting_region_block_ids(&self,aabb:&Aabb)->Vec<BlockId>{
|
||||
let mut block_ids=Vec::new();
|
||||
self.bvh.the_tester(aabb,&mut |block_id|block_ids.push(block_id));
|
||||
block_ids
|
||||
}
|
||||
pub fn load_region(&mut self,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 block_id=*self.node_id_to_block_id.get(node_id.get() as usize).ok_or(Error::InvalidBvhNodeId(node_id))?;
|
||||
let mut block=self.file.block_reader(block_id).map_err(Error::File)?;
|
||||
let region:Region=block.read_le().map_err(Error::InvalidRegion)?;
|
||||
Ok(region.models)
|
||||
Ok(region.models.into_iter().map(Into::into).collect())
|
||||
}
|
||||
// pub fn load_resource(&mut self,resource_id:ResourceId)->Resource{
|
||||
// //
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user