Compare commits

...

6 Commits

Author SHA1 Message Date
c504a4678c parse color from freaky rendercolor 2025-02-18 15:04:19 -08:00
861ce57e63 write a bunch of entities 2025-02-18 11:57:00 -08:00
8daff7bde3 print model that failed to load 2025-02-18 11:54:28 -08:00
75e12c612e update vbsp fork 2025-02-18 09:34:58 -08:00
8547bb9849 recognize InfoPlayerTerrorist spawns 2025-02-14 15:20:00 -08:00
6786706e69 parse css entities only 2025-02-14 15:09:08 -08:00
5 changed files with 73 additions and 35 deletions

4
Cargo.lock generated
View File

@@ -4370,9 +4370,9 @@ dependencies = [
[[package]]
name = "vbsp"
version = "0.7.0-codegen1"
version = "0.7.0-codegen3"
source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/"
checksum = "ff3887880f15dc530860d683aa6cf33f2e03e5a1c2783e3dc8252bffbf889c3c"
checksum = "f93f45d9ed6e8db2e74eda9048eb7566d2d63c65a3f25e546475746db3273895"
dependencies = [
"ahash",
"arrayvec",

View File

@@ -13,6 +13,6 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
glam = "0.29.0"
strafesnet_common = { version = "0.6.0", path = "../common", registry = "strafesnet" }
strafesnet_deferred_loader = { version = "0.5.0", path = "../deferred_loader", registry = "strafesnet" }
vbsp = { version = "0.7.0-codegen1", registry = "strafesnet" }
vbsp = { version = "0.7.0-codegen3", registry = "strafesnet" }
vmdl = "0.2.0"
vpk = "0.2.0"

View File

@@ -32,6 +32,32 @@ fn ingest_vertex(
})
}
fn add_brush<'a>(mesh_deferred_loader:&mut MeshDeferredLoader<&'a str>,world_models:&mut Vec<model::Model>,model:&'a str,origin:vbsp::Vector,rendercolor:vbsp::Color,attributes:gameplay_attributes::CollisionAttributesId){
//The first character of brush.model is '*'
let mesh=match model.split_at(1){
("*",id_str)=>match id_str.parse(){
Ok(mesh_id)=>model::MeshId::new(mesh_id),
Err(e)=>{
println!("Brush model int parse error: {e} model={model}");
return;
},
},
_=>mesh_deferred_loader.acquire_mesh_id(model),
};
world_models.push(model::Model{
mesh,
attributes,
transform:integer::Planar64Affine3::from_translation(
valve_transform(origin.into())
),
color:(glam::Vec3::from_array([
rendercolor.r as f32,
rendercolor.g as f32,
rendercolor.b as f32
])/255.0).extend(1.0),
});
}
pub fn convert<'a>(
bsp:&'a crate::Bsp,
render_config_deferred_loader:&mut RenderConfigDeferredLoader<Cow<'a,str>>,
@@ -134,40 +160,52 @@ pub fn convert<'a>(
color:glam::Vec4::W,
});
const WHITE:vbsp::Color=vbsp::Color{r:255,g:255,b:255};
for raw_ent in bsp.entities.iter(){
match raw_ent.parse(){
Ok(vbsp::basic::Entity::Brush(brush))
|Ok(vbsp::basic::Entity::BrushIllusionary(brush))
|Ok(vbsp::basic::Entity::BrushWall(brush))
|Ok(vbsp::basic::Entity::BrushWallToggle(brush))=>{
//The first character of brush.model is '*'
match brush.model[1..].parse(){
Ok(mesh_id)=>{
world_models.push(model::Model{
mesh:model::MeshId::new(mesh_id),
attributes:ATTRIBUTE_DECORATION,
transform:integer::Planar64Affine3::from_translation(
valve_transform(brush.origin.into())
),
color:(glam::Vec3::from_array([
brush.color.r as f32,
brush.color.g as f32,
brush.color.b as f32
])/255.0).extend(1.0),
});
},
Err(e)=>{
println!("Brush model int parse error: {e}");
},
}
},
_=>(),
}
match raw_ent.parse(){
Ok(vbsp::css::Entity::Cycler(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::EnvSprite(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor.parse().unwrap_or(WHITE),ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncBreakable(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncBrush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncDoor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncIllusionary(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncMonitor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncMovelinear(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncPhysbox(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncPhysboxMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncRotButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncTracktrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncTrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncWall(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncWallToggle(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::FuncWaterAnalog(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor.unwrap_or(WHITE),ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropDynamic(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropDynamicOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropPhysics(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropPhysicsMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropPhysicsOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::PropRagdoll(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerGravity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerHurt(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerLook(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerMultiple(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerOnce(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerProximity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerPush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerSoundscape(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerTeleport(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerVphysicsMotion(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::TriggerWind(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
Ok(vbsp::css::Entity::InfoPlayerCounterterrorist(spawn))=>{
found_spawn=Some(valve_transform(spawn.origin.into()));
},
Ok(vbsp::css::Entity::InfoPlayerTerrorist(spawn))=>{
found_spawn=Some(valve_transform(spawn.origin.into()));
},
Err(e)=>{
println!("Bsp Entity parse error: {e}");
},

View File

@@ -47,7 +47,7 @@ pub enum MeshError{
Io(std::io::Error),
VMDL(vmdl::ModelError),
VBSP(vbsp::BspError),
MissingMdl,
MissingMdl(String),
MissingVtx,
MissingVvd,
}
@@ -132,7 +132,7 @@ impl<'bsp,'vpk,'a> Loader for ModelLoader<'bsp,'vpk,'a>
vvd_path.set_extension("vvd");
vtx_path.set_extension("dx90.vtx");
// TODO: search more packs, possibly using an index of multiple packs
let mdl=self.finder.find(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl)?;
let mdl=self.finder.find(mdl_path_lower.as_str())?.ok_or(MeshError::MissingMdl(mdl_path_lower))?;
let vtx=self.finder.find(vtx_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVtx)?;
let vvd=self.finder.find(vvd_path.as_os_str().to_str().unwrap())?.ok_or(MeshError::MissingVvd)?;
Ok(vmdl::Model::from_parts(

View File

@@ -25,7 +25,7 @@ strafesnet_rbx_loader = { version = "0.6.0", path = "../lib/rbx_loader", registr
strafesnet_snf = { version = "0.3.0", path = "../lib/snf", registry = "strafesnet" }
thiserror = "2.0.11"
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "fs"] }
vbsp = { version = "0.7.0-codegen1", registry = "strafesnet" }
vbsp = { version = "0.7.0-codegen3", registry = "strafesnet" }
vmdl = "0.2.0"
vmt-parser = "0.2.0"
vpk = "0.2.0"