implement valve mesh loading

This commit is contained in:
Quaternions 2024-02-14 23:19:15 -08:00
parent b25bcc627d
commit df8189b874
8 changed files with 79 additions and 50 deletions

13
Cargo.lock generated
View File

@ -1658,7 +1658,7 @@ dependencies = [
[[package]]
name = "strafesnet_bsp_loader"
version = "0.1.0"
source = "git+https://git.itzana.me/StrafesNET/bsp_loader?rev=00df8288849f8da4a61ff96a9d3f7fc8e6162c2a#00df8288849f8da4a61ff96a9d3f7fc8e6162c2a"
source = "git+https://git.itzana.me/StrafesNET/bsp_loader?rev=45b2af405bd171f4c7227668eac7eb1a1a0d4ea9#45b2af405bd171f4c7227668eac7eb1a1a0d4ea9"
dependencies = [
"glam",
"strafesnet_common",
@ -1669,7 +1669,7 @@ dependencies = [
[[package]]
name = "strafesnet_common"
version = "0.1.0"
source = "git+https://git.itzana.me/StrafesNET/common?rev=47cdea0c8a5d10a2440ca6270a975d560aa3642d#47cdea0c8a5d10a2440ca6270a975d560aa3642d"
source = "git+https://git.itzana.me/StrafesNET/common?rev=093a54c527134ef7020a22a0f5778df8cba60228#093a54c527134ef7020a22a0f5778df8cba60228"
dependencies = [
"glam",
"id",
@ -1677,17 +1677,18 @@ dependencies = [
[[package]]
name = "strafesnet_deferred_loader"
version = "0.2.0"
source = "git+https://git.itzana.me/StrafesNET/deferred_loader?rev=b941bdb6fd103073239d64488e4de99cd792a55c#b941bdb6fd103073239d64488e4de99cd792a55c"
version = "0.3.0"
source = "git+https://git.itzana.me/StrafesNET/deferred_loader?rev=c03cd0e905daf70b03b60b3e12509f96ee94a658#c03cd0e905daf70b03b60b3e12509f96ee94a658"
dependencies = [
"lazy-regex",
"strafesnet_common",
"vbsp",
]
[[package]]
name = "strafesnet_rbx_loader"
version = "0.1.0"
source = "git+https://git.itzana.me/StrafesNET/rbx_loader?rev=0b630576d4b2402277d55f0a53e9d048a31af9aa#0b630576d4b2402277d55f0a53e9d048a31af9aa"
version = "0.2.0"
source = "git+https://git.itzana.me/StrafesNET/rbx_loader?rev=34017ea72ce9b65fedcd6e376b4230fdb1cf6b5d#34017ea72ce9b65fedcd6e376b4230fdb1cf6b5d"
dependencies = [
"glam",
"lazy-regex",

View File

@ -13,10 +13,10 @@ glam = "0.25.0"
id = { git = "https://git.itzana.me/Quaternions/id", rev = "1f710976cc786c8853dab73d6e1cee53158deeb0" }
parking_lot = "0.12.1"
pollster = "0.3.0"
strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "47cdea0c8a5d10a2440ca6270a975d560aa3642d" }
strafesnet_bsp_loader = { git = "https://git.itzana.me/StrafesNET/bsp_loader", rev = "00df8288849f8da4a61ff96a9d3f7fc8e6162c2a" }
strafesnet_rbx_loader = { git = "https://git.itzana.me/StrafesNET/rbx_loader", rev = "0b630576d4b2402277d55f0a53e9d048a31af9aa" }
strafesnet_deferred_loader = { git = "https://git.itzana.me/StrafesNET/deferred_loader", rev = "b941bdb6fd103073239d64488e4de99cd792a55c", features = ["legacy"] }
strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "093a54c527134ef7020a22a0f5778df8cba60228" }
strafesnet_bsp_loader = { git = "https://git.itzana.me/StrafesNET/bsp_loader", rev = "45b2af405bd171f4c7227668eac7eb1a1a0d4ea9" }
strafesnet_rbx_loader = { git = "https://git.itzana.me/StrafesNET/rbx_loader", rev = "34017ea72ce9b65fedcd6e376b4230fdb1cf6b5d" }
strafesnet_deferred_loader = { git = "https://git.itzana.me/StrafesNET/deferred_loader", rev = "c03cd0e905daf70b03b60b3e12509f96ee94a658", features = ["legacy"] }
wgpu = "0.19.0"
winit = "0.29.2"

View File

@ -42,43 +42,70 @@ impl std::fmt::Display for LoadError{
}
impl std::error::Error for LoadError{}
pub fn load<P:AsRef<std::path::Path>>(path:P)->Result<(strafesnet_common::map::CompleteMap,strafesnet_deferred_loader::texture::Textures),LoadError>{
pub fn load<P:AsRef<std::path::Path>>(path:P)->Result<strafesnet_common::map::CompleteMap,LoadError>{
//blocking because it's simpler...
let file=std::fs::File::open(path).map_err(LoadError::File)?;
match read(file).map_err(LoadError::ReadError)?{
DataStructure::Roblox(something)=>{
let mut legacy_loader=strafesnet_deferred_loader::roblox_legacy();
DataStructure::Roblox(dom)=>{
let mut loader=strafesnet_deferred_loader::roblox_legacy();
let map=strafesnet_rbx_loader::convert(&something,|name|{
match legacy_loader.acquire_texture_id(name){
Ok(texture_id)=>Some(texture_id),
Err(e)=>{
println!("legacy_loader error: {e}");
None
let map_step1=strafesnet_rbx_loader::convert(
&dom,
|name|loader.acquire_render_config_id(name)
);
let (textures,render_configs)=loader.into_render_configs().map_err(LoadError::Io)?.consume();
let map=map_step1.add_render_configs_and_textures(
render_configs.into_iter(),
textures.into_iter().map(|(texture_id,texture)|
(texture_id,match texture{
strafesnet_deferred_loader::texture::Texture::ImageDDS(data)=>data,
})
)
);
Ok(map)
},
}
});
DataStructure::Source(bsp)=>{
let mut loader=strafesnet_deferred_loader::source_legacy();
let textures=legacy_loader.load_textures().map_err(LoadError::Io)?;
let (texture_loader,mesh_loader)=loader.get_inner_mut();
Ok((map,textures))
},
DataStructure::Source(something)=>{
let mut legacy_loader=strafesnet_deferred_loader::source_legacy();
let (texture_loader,mesh_loader)=legacy_loader.get_inner_mut();
let map=strafesnet_bsp_loader::convert(
&something,
//acquire_texture_id
|name|texture_loader.acquire_texture_id(name),
let map_step1=strafesnet_bsp_loader::convert(
&bsp,
//acquire_render_config_id
&mut |name|texture_loader.acquire_render_config_id(name),
//acquire_mesh_id
|name|mesh_loader.acquire_mesh_id(name),
);
let textures=legacy_loader.load_textures().map_err(LoadError::Io)?;
let prop_meshes=mesh_loader.load_meshes(&bsp.as_ref());
Ok((map,textures))
let map_step2=map_step1.add_prop_meshes(
//the type conflagulator 9000
prop_meshes.into_iter().map(|(mesh_id,loader_model)|
(mesh_id,strafesnet_bsp_loader::data::ModelData{
mdl:strafesnet_bsp_loader::data::MdlData::new(loader_model.mdl.get()),
vtx:strafesnet_bsp_loader::data::VtxData::new(loader_model.vtx.get()),
vvd:strafesnet_bsp_loader::data::VvdData::new(loader_model.vvd.get()),
})
),
&mut |name|texture_loader.acquire_render_config_id(name),
);
let (textures,render_configs)=loader.into_render_configs().map_err(LoadError::Io)?.consume();
let map=map_step2.add_render_configs_and_textures(
render_configs.into_iter(),
textures.into_iter().map(|(texture_id,texture)|
(texture_id,match texture{
strafesnet_deferred_loader::texture::Texture::ImageDDS(data)=>data,
})
),
);
Ok(map)
},
}
}

View File

@ -147,9 +147,10 @@ impl GraphicsState{
pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){
self.camera.fov=user_settings.calculate_fov(1.0,&self.camera.screen_size).as_vec2();
}
pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::CompleteMap,textures:strafesnet_deferred_loader::texture::Textures){
pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::CompleteMap){
//generate texture view per texture
let texture_views:HashMap<strafesnet_common::model::TextureId,wgpu::TextureView>=textures.into_iter().filter_map(|(texture_id,texture_data)|{
let texture_views:HashMap<strafesnet_common::model::TextureId,wgpu::TextureView>=map.textures.iter().enumerate().filter_map(|(texture_id,texture_data)|{
let texture_id=model::TextureId::new(texture_id as u32);
let image=ddsfile::Dds::read(std::io::Cursor::new(texture_data)).ok()?;
let (mut width,mut height)=(image.get_width(),image.get_height());

View File

@ -4,7 +4,7 @@ pub enum Instruction{
Render(crate::physics::PhysicsOutputState,integer::Time,glam::IVec2),
//UpdateModel(crate::graphics::GraphicsModelUpdate),
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
GenerateModels(strafesnet_common::map::CompleteMap,strafesnet_deferred_loader::texture::Textures),
GenerateModels(strafesnet_common::map::CompleteMap),
ClearModels,
}
@ -27,8 +27,8 @@ pub fn new<'a>(
let mut resize=None;
crate::compat_worker::INWorker::new(move |ins:Instruction|{
match ins{
Instruction::GenerateModels(map,textures)=>{
graphics.generate_models(&device,&queue,&map,textures);
Instruction::GenerateModels(map)=>{
graphics.generate_models(&device,&queue,&map);
},
Instruction::ClearModels=>{
graphics.clear();

View File

@ -176,8 +176,8 @@ impl PhysicsModels{
&model.transform
)
}
fn model(&self,model_id:PhysicsModelId)->&PhysicsModel{
&self.models[&model_id]
fn model(&self,model_id:PhysicsModelId)->Option<&PhysicsModel>{
self.models.get(&model_id)
}
fn attr(&self,model_id:PhysicsModelId)->&PhysicsCollisionAttributes{
&self.attributes[&self.models[&model_id].attr_id]
@ -1198,7 +1198,7 @@ fn teleport(body:&mut Body,touching:&mut TouchingState,models:&PhysicsModels,sty
MoveState::Air
}
fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,mode:&gameplay_modes::Mode,models:&PhysicsModels,stage_id:gameplay_modes::StageId)->Option<MoveState>{
let model=models.model(mode.get_spawn_model_id(stage_id)?.into());
let model=models.model(mode.get_spawn_model_id(stage_id)?.into()).unwrap();
let point=model.transform.vertex.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(style.hitbox.halfsize.y()+Planar64::ONE/16);
Some(teleport(body,touching,models,style,hitbox_mesh,point))
}
@ -1254,8 +1254,8 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
}
match wormhole{
&Some(gameplay_attributes::Wormhole{destination_model})=>{
let origin_model=models.model(convex_mesh_id.model_id);
let destination_model=models.model(destination_model.into());
let origin_model=models.model(convex_mesh_id.model_id).unwrap();
let destination_model=models.model(destination_model.into()).unwrap();
//ignore the transform for now
Some(teleport(body,touching,models,style,hitbox_mesh,body.position-origin_model.transform.vertex.translation+destination_model.transform.vertex.translation))
}
@ -1461,7 +1461,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,models
state.mode_state.set_stage_id(gameplay_modes::StageId::FIRST);
let spawn_point=data.modes.get_mode(state.mode_state.get_mode_id()).and_then(|mode|
//TODO: spawn at the bottom of the start zone plus the hitbox size
Some(data.models.model(mode.get_start().into()).transform.vertex.translation)
data.models.model(mode.get_start().into()).map(|model|model.transform.vertex.translation)
).unwrap_or(Planar64Vec3::ZERO);
set_position(&mut state.body,&mut state.touching,spawn_point);
set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,Planar64Vec3::ZERO);

View File

@ -18,7 +18,7 @@ pub enum Instruction{
Input(InputInstruction),
Render,
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
GenerateModels(strafesnet_common::map::CompleteMap,strafesnet_deferred_loader::texture::Textures),
GenerateModels(strafesnet_common::map::CompleteMap),
ClearModels,
//Graphics(crate::graphics_worker::Instruction),
}
@ -63,7 +63,7 @@ pub enum Instruction{
&InputInstruction::Zoom(s)=>Some(PhysicsInputInstruction::SetZoom(s)),
InputInstruction::Reset=>Some(PhysicsInputInstruction::Reset),
},
Instruction::GenerateModels(_,_)=>Some(PhysicsInputInstruction::Idle),
Instruction::GenerateModels(_)=>Some(PhysicsInputInstruction::Idle),
Instruction::ClearModels=>Some(PhysicsInputInstruction::Idle),
Instruction::Resize(_,_)=>Some(PhysicsInputInstruction::Idle),
Instruction::Render=>Some(PhysicsInputInstruction::Idle),
@ -118,10 +118,10 @@ pub enum Instruction{
Instruction::Resize(size,user_settings)=>{
graphics_worker.send(crate::graphics_worker::Instruction::Resize(size,user_settings)).unwrap();
},
Instruction::GenerateModels(map,textures)=>{
Instruction::GenerateModels(map)=>{
physics.generate_models(&map);
physics.spawn();
graphics_worker.send(crate::graphics_worker::Instruction::GenerateModels(map,textures)).unwrap();
graphics_worker.send(crate::graphics_worker::Instruction::GenerateModels(map)).unwrap();
},
Instruction::ClearModels=>{
physics.state.clear();

View File

@ -28,9 +28,9 @@ impl WindowContext<'_>{
match event {
winit::event::WindowEvent::DroppedFile(path)=>{
match crate::file::load(path.as_path()){
Ok((map,textures))=>{
Ok(map)=>{
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::ClearModels}).unwrap();
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::GenerateModels(map,textures)}).unwrap();
self.physics_thread.send(TimedInstruction{time,instruction:crate::physics_worker::Instruction::GenerateModels(map)}).unwrap();
},
Err(e)=>println!("Failed to load map: {e}"),
}