From 662ccc26bc59bbd381ef1b76d03fb0b1116a9fad Mon Sep 17 00:00:00 2001 From: Quaternions Date: Tue, 13 Feb 2024 20:32:21 -0800 Subject: [PATCH] add mesh loader prototype code --- src/source.rs | 126 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/src/source.rs b/src/source.rs index a51b9fb..cfb2f87 100644 --- a/src/source.rs +++ b/src/source.rs @@ -32,7 +32,127 @@ impl Loader{ pub fn load_textures(&self)->Result{ Ok(Textures::new(Vec::new())) } - // fn load_meshes(&self)->Result{ - // Ok(Meshes::new(Vec::new())) - // } + /* + pub fn load_meshes(&mut self)->Result{ + //call self.acquire_texture_id for each texture in the mesh + //generate unique meshes + let mut model_map=std::collections::HashMap::with_capacity(model_dedupe.len()); + let mut prop_models=Vec::new(); + for model_name in model_dedupe{ + let model_name_lower=model_name.to_lowercase(); + //.mdl, .vvd, .dx90.vtx + let mut path=std::path::PathBuf::from(model_name_lower.as_str()); + let file_name=std::path::PathBuf::from(path.file_stem().unwrap()); + path.pop(); + path.push(file_name); + let mut vvd_path=path.clone(); + let mut vtx_path=path.clone(); + vvd_path.set_extension("vvd"); + vtx_path.set_extension("dx90.vtx"); + match (bsp.pack.get(model_name_lower.as_str()),bsp.pack.get(vvd_path.as_os_str().to_str().unwrap()),bsp.pack.get(vtx_path.as_os_str().to_str().unwrap())){ + (Ok(Some(mdl_file)),Ok(Some(vvd_file)),Ok(Some(vtx_file)))=>{ + match (vmdl::mdl::Mdl::read(mdl_file.as_ref()),vmdl::vvd::Vvd::read(vvd_file.as_ref()),vmdl::vtx::Vtx::read(vtx_file.as_ref())){ + (Ok(mdl),Ok(vvd),Ok(vtx))=>{ + let model=vmdl::Model::from_parts(mdl,vtx,vvd); + let texture_paths=model.texture_directories(); + if texture_paths.len()!=1{ + println!("WARNING: multiple texture paths"); + } + let skin=model.skin_tables().nth(0).unwrap(); + + let mut spam_pos=Vec::with_capacity(model.vertices().len()); + let mut spam_normal=Vec::with_capacity(model.vertices().len()); + let mut spam_tex=Vec::with_capacity(model.vertices().len()); + let mut spam_vertices=Vec::with_capacity(model.vertices().len()); + for (i,vertex) in model.vertices().iter().enumerate(){ + spam_pos.push(valve_transform(<[f32;3]>::from(vertex.position))); + spam_normal.push(valve_transform(<[f32;3]>::from(vertex.normal))); + spam_tex.push(glam::Vec2::from_array(vertex.texture_coordinates)); + spam_vertices.push(model::IndexedVertex{ + pos:model::PositionId::new(i as u32), + tex:model::TextureCoordinateId::new(i as u32), + normal:model::NormalId::new(i as u32), + color:model::ColorId::new(0), + }); + } + + let model_id=prop_models.len(); + model_map.insert(model_name,model_id); + prop_models.push(model::Mesh{ + unique_pos:spam_pos, + unique_normal:spam_normal, + unique_tex:spam_tex, + unique_color:vec![glam::Vec4::ONE], + unique_vertices:spam_vertices, + groups:model.meshes().map(|mesh|{ + let texture=if let (Some(texture_path),Some(texture_name))=(texture_paths.get(0),skin.texture(mesh.material_index())){ + let mut path=std::path::PathBuf::from(texture_path.as_str()); + path.push(texture_name); + let texture_location=path.as_os_str().to_str().unwrap(); + let texture_id=if let Some(&texture_id)=texture_id_from_name.get(texture_location){ + texture_id + }else{ + println!("texture! {}",texture_location); + let texture_id=name_from_texture_id.len() as u32; + texture_id_from_name.insert(texture_location.to_string(),texture_id); + name_from_texture_id.push(texture_location.to_string()); + texture_id + }; + Some(texture_id) + }else{ + None + }; + + model::IndexedGroup{ + texture, + polys:{ + //looking at the code, it would seem that the strips are pre-deindexed into triangle lists when calling this function + mesh.vertex_strip_indices().map(|strip|{ + strip.collect::>().chunks(3).map(|tri|{ + model::IndexedPolygon{vertices:vec![tri[0] as u32,tri[1] as u32,tri[2] as u32]} + }).collect::>() + }).flatten().collect() + }, + } + }).collect(), + instances:Vec::new(), + }); + }, + _=>println!("model_name={} error",model_name), + } + }, + _=>println!("no model name={}",model_name), + } + } + + //generate model instances + for prop in bsp.static_props(){ + let placement=prop.as_prop_placement(); + if let Some(&model_index)=model_map.get(placement.model){ + prop_models[model_index].instances.push(model::ModelInstance{ + transform:integer::Planar64Affine3::new( + integer::Planar64Mat3::try_from( + glam::Mat3A::from_diagonal(glam::Vec3::splat(placement.scale)) + //TODO: figure this out + *glam::Mat3A::from_quat(glam::Quat::from_xyzw( + placement.rotation.v.x,//b + placement.rotation.v.y,//c + placement.rotation.v.z,//d + placement.rotation.s,//a + )) + ).unwrap(), + valve_transform(<[f32;3]>::from(placement.origin)), + ), + attributes:model::CollisionAttributes::Decoration, + ..Default::default() + }); + }else{ + //println!("model not found {}",placement.model); + } + } + + //actually add the prop models + prop_models.append(&mut models); + } + */ } \ No newline at end of file