bsp_loader: rewrite world models to use mesh builder

This commit is contained in:
Quaternions 2025-02-03 17:09:10 -08:00
parent d504b82441
commit 8eca99fd9c

@ -7,6 +7,31 @@ use strafesnet_deferred_loader::texture::{RenderConfigs,Texture};
use crate::valve_transform;
fn ingest_vertex(
mb:&mut model::MeshBuilder,
world_position:vbsp::Vector,
texture_transform_u:glam::Vec4,
texture_transform_v:glam::Vec4,
normal:model::NormalId,
color:model::ColorId,
)->model::VertexId{
//world_model.origin seems to always be 0,0,0
let vertex_xyz=world_position.into();
let pos=mb.acquire_pos_id(valve_transform(vertex_xyz));
//calculate texture coordinates
let pos_4d=glam::Vec3::from_array(vertex_xyz).extend(1.0);
let tex=glam::vec2(texture_transform_u.dot(pos_4d),texture_transform_v.dot(pos_4d));
let tex=mb.acquire_tex_id(tex);
mb.acquire_vertex_id(model::IndexedVertex{
pos,
tex,
normal,
color,
})
}
pub fn convert<'a>(
bsp:&'a crate::Bsp,
render_config_deferred_loader:&mut RenderConfigDeferredLoader<Cow<'a,str>>,
@ -48,11 +73,9 @@ 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|{
//non-deduplicated
let mut spam_pos=Vec::new();
let mut spam_tex=Vec::new();
let mut spam_normal=Vec::new();
let mut spam_vertices=Vec::new();
let mut mb=model::MeshBuilder::new();
let color=mb.acquire_color_id(glam::Vec4::ONE);
let mut graphics_groups=Vec::new();
let mut physics_group=model::IndexedPhysicsGroup::default();
let polygon_groups=world_model.faces().enumerate().map(|(polygon_group_id,face)|{
@ -68,36 +91,20 @@ pub fn convert<'a>(
let render_id=render_config_deferred_loader.acquire_render_config_id(Some(Cow::Borrowed(face_texture_data.name())));
//normal
let normal=face.normal();
let normal_idx=spam_normal.len() as u32;
spam_normal.push(valve_transform(normal.into()));
let mut polygon_iter=face.vertex_positions().map(|vertex_position|{
//world_model.origin seems to always be 0,0,0
let vertex_xyz=(world_model.origin+vertex_position).into();
let pos_idx=spam_pos.len();
spam_pos.push(valve_transform(vertex_xyz));
//calculate texture coordinates
let pos=glam::Vec3::from_array(vertex_xyz).extend(1.0);
let tex=glam::vec2(texture_transform_u.dot(pos),texture_transform_v.dot(pos));
let tex_idx=spam_tex.len() as u32;
spam_tex.push(tex);
let vertex_id=model::VertexId::new(spam_vertices.len() as u32);
spam_vertices.push(model::IndexedVertex{
pos:model::PositionId::new(pos_idx as u32),
tex:model::TextureCoordinateId::new(tex_idx as u32),
normal:model::NormalId::new(normal_idx),
color:model::ColorId::new(0),
});
vertex_id
});
let normal=mb.acquire_normal_id(valve_transform(face.normal().into()));
let mut polygon_iter=face.vertex_positions().map(|vertex_position|
world_model.origin+vertex_position
);
let polygon_list=std::iter::from_fn(move||{
match (polygon_iter.next(),polygon_iter.next(),polygon_iter.next()){
(Some(v1),Some(v2),Some(v3))=>Some(vec![v1,v2,v3]),
(Some(v1),Some(v2),Some(v3))=>Some([v1,v2,v3]),
//ignore extra vertices, not sure what to do in this case, failing the whole conversion could be appropriate
_=>None,
}
}).map(|triplet|{
triplet.map(|world_position|
ingest_vertex(&mut mb,world_position,texture_transform_u,texture_transform_v,normal,color)
).to_vec()
}).collect();
if face.is_visible(){
//TODO: deduplicate graphics groups by render id
@ -109,16 +116,8 @@ pub fn convert<'a>(
physics_group.groups.push(polygon_group_id);
model::PolygonGroup::PolygonList(model::PolygonList::new(polygon_list))
}).collect();
model::Mesh{
unique_pos:spam_pos,
unique_tex:spam_tex,
unique_normal:spam_normal,
unique_color:vec![glam::Vec4::ONE],
unique_vertices:spam_vertices,
polygon_groups,
graphics_groups,
physics_groups:vec![physics_group],
}
mb.build(polygon_groups,graphics_groups,vec![physics_group])
}).collect();
let world_models:Vec<model::Model>=