From 00523cbd89e3682f35896aa9ed90a32e5ee9e842 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Tue, 25 Feb 2025 13:23:07 -0800
Subject: [PATCH] append non-world brushes to prop models

---
 lib/bsp_loader/src/bsp.rs | 127 +++++++++++++++++++++-----------------
 1 file changed, 71 insertions(+), 56 deletions(-)

diff --git a/lib/bsp_loader/src/bsp.rs b/lib/bsp_loader/src/bsp.rs
index 245682f..9dfcff6 100644
--- a/lib/bsp_loader/src/bsp.rs
+++ b/lib/bsp_loader/src/bsp.rs
@@ -34,30 +34,45 @@ 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){
+fn add_brush<'a>(
+	mesh_deferred_loader:&mut MeshDeferredLoader<&'a str>,
+	world_models:&mut Vec<model::Model>,
+	prop_models:&mut Vec<model::Model>,
+	model:&'a str,
+	origin:vbsp::Vector,
+	rendercolor:vbsp::Color,
+	attributes:gameplay_attributes::CollisionAttributesId,
+){
+	let transform=integer::Planar64Affine3::from_translation(
+		valve_transform(origin.into())
+	);
+	let color=(glam::Vec3::from_array([
+		rendercolor.r as f32,
+		rendercolor.g as f32,
+		rendercolor.b as f32
+	])/255.0).extend(1.0);
+
+	match model.split_at(1){
+		// The first character of brush.model is '*'
 		("*",id_str)=>match id_str.parse(){
-			Ok(mesh_id)=>model::MeshId::new(mesh_id),
+			Ok(mesh_id)=>{
+				let mesh=model::MeshId::new(mesh_id);
+				world_models.push(
+					model::Model{mesh,attributes,transform,color}
+				);
+			},
 			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),
-	});
+		_=>{
+			let mesh=mesh_deferred_loader.acquire_mesh_id(model);
+			prop_models.push(
+				model::Model{mesh,attributes,transform,color}
+			);
+		}
+	}
 }
 
 pub fn convert<'a>(
@@ -76,7 +91,7 @@ pub fn convert<'a>(
 	const ATTRIBUTE_INTERSECT_DEFAULT:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(2);
 
 	//declare all prop models to Loader
-	let prop_models=bsp.static_props().map(|prop|{
+	let mut prop_models=bsp.static_props().map(|prop|{
 		//get or create mesh_id
 		let mesh_id=mesh_deferred_loader.acquire_mesh_id(prop.model());
 		let placement=prop.as_prop_placement();
@@ -165,43 +180,43 @@ pub fn convert<'a>(
 	const WHITE:vbsp::Color=vbsp::Color{r:255,g:255,b:255};
 	for raw_ent in bsp.entities.iter(){
 		match raw_ent.parse(){
-			Ok(Entity::Cycler(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::EnvSprite(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor.parse().unwrap_or(WHITE),ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncBreakable(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncBrush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncDoor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncIllusionary(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncMonitor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncMovelinear(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncPhysbox(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncPhysboxMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncRotButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncTracktrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncTrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncWall(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncWallToggle(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
-			Ok(Entity::FuncWaterAnalog(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,brush.rendercolor.unwrap_or(WHITE),ATTRIBUTE_DECORATION),
-			Ok(Entity::PropDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::PropDynamic(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::PropDynamicOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::PropPhysics(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::PropPhysicsMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::PropPhysicsOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::PropRagdoll(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerGravity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerHurt(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerLook(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerMultiple(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerOnce(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerProximity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerPush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerSoundscape(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerTeleport(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerVphysicsMotion(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
-			Ok(Entity::TriggerWind(brush))=>add_brush(mesh_deferred_loader,&mut world_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::Cycler(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::EnvSprite(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor.parse().unwrap_or(WHITE),ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncBreakable(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncBrush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncDoor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncIllusionary(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncMonitor(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncMovelinear(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncPhysbox(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncPhysboxMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncRotButton(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncTracktrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncTrain(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncWall(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncWallToggle(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin.unwrap_or_default(),brush.rendercolor,ATTRIBUTE_DECORATION),
+			Ok(Entity::FuncWaterAnalog(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,brush.rendercolor.unwrap_or(WHITE),ATTRIBUTE_DECORATION),
+			Ok(Entity::PropDoorRotating(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::PropDynamic(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::PropDynamicOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::PropPhysics(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::PropPhysicsMultiplayer(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::PropPhysicsOverride(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::PropRagdoll(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerGravity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerHurt(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerLook(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerMultiple(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerOnce(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerProximity(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerPush(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerSoundscape(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerTeleport(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model.unwrap_or_default(),brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerVphysicsMotion(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
+			Ok(Entity::TriggerWind(brush))=>add_brush(mesh_deferred_loader,&mut world_models,&mut prop_models,brush.model,brush.origin,WHITE,ATTRIBUTE_DECORATION),
 			Ok(Entity::InfoPlayerCounterterrorist(spawn))=>{
 				found_spawn=Some(valve_transform(spawn.origin.into()));
 			},