diff --git a/lib/bsp_loader/src/bsp.rs b/lib/bsp_loader/src/bsp.rs index b625774..72558e6 100644 --- a/lib/bsp_loader/src/bsp.rs +++ b/lib/bsp_loader/src/bsp.rs @@ -41,7 +41,9 @@ pub fn convert<'a>( //figure out real attributes later let mut unique_attributes=Vec::new(); unique_attributes.push(gameplay_attributes::CollisionAttributes::Decoration); + unique_attributes.push(gameplay_attributes::CollisionAttributes::contact_default()); const ATTRIBUTE_DECORATION:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(0); + const ATTRIBUTE_CONTACT_DEFAULT:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(1); //declare all prop models to Loader let prop_models=bsp.static_props().map(|prop|{ @@ -67,7 +69,7 @@ pub fn convert<'a>( //the generated MeshIds in here will collide with the Loader Mesh Ids //but I can't think of a good workaround other than just remapping one later. - let world_meshes:Vec<model::Mesh>=bsp.models().map(|world_model|{ + let mut world_meshes:Vec<model::Mesh>=bsp.models().map(|world_model|{ let mut mb=model::MeshBuilder::new(); let color=mb.acquire_color_id(glam::Vec4::ONE); @@ -118,6 +120,41 @@ pub fn convert<'a>( mb.build(polygon_groups,graphics_groups,vec![]) }).collect(); + let brush_mesh_start_idx=world_meshes.len(); + for brush in &bsp.brushes{ + let brush_start_idx=brush.brush_side as usize; + if let Some(sides)=bsp.brush_sides.get(brush_start_idx..brush_start_idx+brush.num_brush_sides as usize){ + let mut mb=model::MeshBuilder::new(); + let color=mb.acquire_color_id(glam::Vec4::ONE); + let tex=mb.acquire_tex_id(glam::Vec2::ZERO); + let mut polygon_list=Vec::new(); + for side in sides{ + if let Some(displacement)=bsp.displacement(side.displacement_info as usize){ + if let Some(face)=displacement.face(){ + let normal=mb.acquire_normal_id(valve_transform(face.normal().into())); + polygon_list.push(face.vertices().map(|vertex|{ + let vertex_xyz=vertex.position.into(); + let pos=mb.acquire_pos_id(valve_transform(vertex_xyz)); + mb.acquire_vertex_id(model::IndexedVertex{ + pos, + tex, + normal, + color, + }) + }).collect()); + } + } + } + if !polygon_list.is_empty(){ + let polygon_groups=model::PolygonGroup::PolygonList(model::PolygonList::new(polygon_list)); + let physics_groups=vec![model::IndexedPhysicsGroup{ + groups:vec![model::PolygonGroupId::new(0)], + }]; + world_meshes.push(mb.build(vec![polygon_groups],vec![],physics_groups)); + } + } + } + let world_models:Vec<model::Model>= //one instance of the main world mesh std::iter::once(( @@ -151,7 +188,18 @@ pub fn convert<'a>( valve_transform(model_origin.into()) ), color:(glam::Vec3::from_array([r as f32,g as f32,b as f32])/255.0).extend(1.0), - }).collect(); + }).chain( + // physics models + (brush_mesh_start_idx..world_meshes.len()).map(|mesh_id|model::Model{ + mesh:model::MeshId::new(mesh_id as u32), + attributes:ATTRIBUTE_CONTACT_DEFAULT, + transform:integer::Planar64Affine3::new( + integer::mat3::identity(), + integer::vec3::ZERO, + ), + color:glam::Vec4::ONE, + }) + ).collect(); PartialMap1{ attributes:unique_attributes,