tab down this function

This commit is contained in:
Quaternions 2024-02-13 18:44:57 -08:00
parent 05f466727c
commit ea55d4bcfb

View File

@ -13,217 +13,217 @@ where
AcquireTextureId:FnMut(&str)->model::TextureId, AcquireTextureId:FnMut(&str)->model::TextureId,
AcquireMeshId:FnMut(&str)->model::MeshId, AcquireMeshId:FnMut(&str)->model::MeshId,
{ {
let mut spawn_point=integer::Planar64Vec3::ZERO; let mut spawn_point=integer::Planar64Vec3::ZERO;
let vertices: Vec<_> = bsp let vertices: Vec<_> = bsp
.vertices .vertices
.iter() .iter()
.map(|vertex|<[f32;3]>::from(vertex.position)) .map(|vertex|<[f32;3]>::from(vertex.position))
.collect(); .collect();
let mut name_from_texture_id=Vec::new(); let mut name_from_texture_id=Vec::new();
let mut texture_id_from_name=std::collections::HashMap::new(); let mut texture_id_from_name=std::collections::HashMap::new();
let mut models=bsp.models().map(|world_model|{ let mut models=bsp.models().map(|world_model|{
//non-deduplicated //non-deduplicated
let mut spam_pos=Vec::new(); let mut spam_pos=Vec::new();
let mut spam_tex=Vec::new(); let mut spam_tex=Vec::new();
let mut spam_normal=Vec::new(); let mut spam_normal=Vec::new();
let mut spam_vertices=Vec::new(); let mut spam_vertices=Vec::new();
let groups=world_model.faces() let groups=world_model.faces()
.filter(|face|face.is_visible())//TODO: look at this .filter(|face|face.is_visible())//TODO: look at this
.map(|face|{ .map(|face|{
let face_texture=face.texture(); let face_texture=face.texture();
let face_texture_data=face_texture.texture_data(); let face_texture_data=face_texture.texture_data();
let (texture_u,texture_v)=(glam::Vec3A::from_slice(&face_texture.texture_transforms_u[0..3]),glam::Vec3A::from_slice(&face_texture.texture_transforms_v[0..3])); let (texture_u,texture_v)=(glam::Vec3A::from_slice(&face_texture.texture_transforms_u[0..3]),glam::Vec3A::from_slice(&face_texture.texture_transforms_v[0..3]));
let texture_offset=glam::vec2(face_texture.texture_transforms_u[3],face_texture.texture_transforms_v[3]); let texture_offset=glam::vec2(face_texture.texture_transforms_u[3],face_texture.texture_transforms_v[3]);
let texture_size=glam::vec2(face_texture_data.width as f32,face_texture_data.height as f32); let texture_size=glam::vec2(face_texture_data.width as f32,face_texture_data.height as f32);
//texture //texture
let texture_id=if let Some(&texture_id)=texture_id_from_name.get(face_texture_data.name()){ let texture_id=if let Some(&texture_id)=texture_id_from_name.get(face_texture_data.name()){
texture_id texture_id
}else{ }else{
let texture_id=name_from_texture_id.len() as u32; let texture_id=name_from_texture_id.len() as u32;
texture_id_from_name.insert(face_texture_data.name().to_string(),texture_id); texture_id_from_name.insert(face_texture_data.name().to_string(),texture_id);
name_from_texture_id.push(face_texture_data.name().to_string()); name_from_texture_id.push(face_texture_data.name().to_string());
texture_id texture_id
}; };
//normal //normal
let normal=face.normal(); let normal=face.normal();
let normal_idx=spam_normal.len() as u32; let normal_idx=spam_normal.len() as u32;
spam_normal.push(valve_transform(<[f32;3]>::from(normal))); spam_normal.push(valve_transform(<[f32;3]>::from(normal)));
let mut indices:Vec<u32>=face.vertex_positions().map(|vertex_position|{ let mut indices:Vec<u32>=face.vertex_positions().map(|vertex_position|{
let vertex_xyz=<[f32;3]>::from(vertex_position); let vertex_xyz=<[f32;3]>::from(vertex_position);
let pos=glam::Vec3A::from_array(vertex_xyz); let pos=glam::Vec3A::from_array(vertex_xyz);
let pos_idx=spam_pos.len(); let pos_idx=spam_pos.len();
spam_pos.push(valve_transform(vertex_xyz)); spam_pos.push(valve_transform(vertex_xyz));
//calculate texture coordinates //calculate texture coordinates
let tex=(glam::vec2(pos.dot(texture_u),pos.dot(texture_v))+texture_offset)/texture_size; let tex=(glam::vec2(pos.dot(texture_u),pos.dot(texture_v))+texture_offset)/texture_size;
let tex_idx=spam_tex.len() as u32; let tex_idx=spam_tex.len() as u32;
spam_tex.push(tex); spam_tex.push(tex);
let i=spam_vertices.len() as u32; let i=spam_vertices.len() as u32;
spam_vertices.push(model::IndexedVertex{ spam_vertices.push(model::IndexedVertex{
pos: pos_idx as u32, pos: pos_idx as u32,
tex: tex_idx as u32, tex: tex_idx as u32,
normal: normal_idx, normal: normal_idx,
color: 0, color: 0,
}); });
i i
}).collect();
indices.reverse();
texture:Some(texture_id),
model::IndexedGroup::PolygonList(vec![model::IndexedPolygon{indices}])
}).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,
groups,
instances:vec![model::Model{
attributes:gameplay_attributes::CollisionAttributes::Decoration,
transform:integer::Planar64Affine3::new(
integer::Planar64Mat3::default(),
valve_transform(<[f32;3]>::from(world_model.origin))
),
..Default::default()
}],
}
}).collect(); }).collect();
indices.reverse();
texture:Some(texture_id),
model::IndexedGroup::PolygonList(vec![model::IndexedPolygon{indices}])
}).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,
groups,
instances:vec![model::Model{
attributes:gameplay_attributes::CollisionAttributes::Decoration,
transform:integer::Planar64Affine3::new(
integer::Planar64Mat3::default(),
valve_transform(<[f32;3]>::from(world_model.origin))
),
..Default::default()
}],
}
}).collect();
//dedupe prop models //dedupe prop models
let mut model_dedupe=std::collections::HashSet::new(); let mut model_dedupe=std::collections::HashSet::new();
for prop in bsp.static_props(){ for prop in bsp.static_props(){
model_dedupe.insert(prop.model()); model_dedupe.insert(prop.model());
} }
//generate unique meshes //generate unique meshes
let mut model_map=std::collections::HashMap::with_capacity(model_dedupe.len()); let mut model_map=std::collections::HashMap::with_capacity(model_dedupe.len());
let mut prop_models=Vec::new(); let mut prop_models=Vec::new();
for model_name in model_dedupe{ for model_name in model_dedupe{
let model_name_lower=model_name.to_lowercase(); let model_name_lower=model_name.to_lowercase();
//.mdl, .vvd, .dx90.vtx //.mdl, .vvd, .dx90.vtx
let mut path=std::path::PathBuf::from(model_name_lower.as_str()); let mut path=std::path::PathBuf::from(model_name_lower.as_str());
let file_name=std::path::PathBuf::from(path.file_stem().unwrap()); let file_name=std::path::PathBuf::from(path.file_stem().unwrap());
path.pop(); path.pop();
path.push(file_name); path.push(file_name);
let mut vvd_path=path.clone(); let mut vvd_path=path.clone();
let mut vtx_path=path.clone(); let mut vtx_path=path.clone();
vvd_path.set_extension("vvd"); vvd_path.set_extension("vvd");
vtx_path.set_extension("dx90.vtx"); 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())){ 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)))=>{ (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())){ 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))=>{ (Ok(mdl),Ok(vvd),Ok(vtx))=>{
let model=vmdl::Model::from_parts(mdl,vtx,vvd); let model=vmdl::Model::from_parts(mdl,vtx,vvd);
let texture_paths=model.texture_directories(); let texture_paths=model.texture_directories();
if texture_paths.len()!=1{ if texture_paths.len()!=1{
println!("WARNING: multiple texture paths"); 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:i as u32,
tex:i as u32,
normal:i as u32,
color: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::<Vec<usize>>().chunks(3).map(|tri|{
model::IndexedPolygon{vertices:vec![tri[0] as u32,tri[1] as u32,tri[2] as u32]}
}).collect::<Vec<model::IndexedPolygon>>()
}).flatten().collect()
},
}
}).collect(),
instances:Vec::new(),
});
},
_=>println!("model_name={} error",model_name),
} }
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:i as u32,
tex:i as u32,
normal:i as u32,
color: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::<Vec<usize>>().chunks(3).map(|tri|{
model::IndexedPolygon{vertices:vec![tri[0] as u32,tri[1] as u32,tri[2] as u32]}
}).collect::<Vec<model::IndexedPolygon>>()
}).flatten().collect()
},
}
}).collect(),
instances:Vec::new(),
});
}, },
_=>println!("no model name={}",model_name), _=>println!("model_name={} error",model_name),
} }
} },
_=>println!("no model name={}",model_name),
}
}
//generate model instances //generate model instances
for prop in bsp.static_props(){ for prop in bsp.static_props(){
let placement=prop.as_prop_placement(); let placement=prop.as_prop_placement();
if let Some(&model_index)=model_map.get(placement.model){ if let Some(&model_index)=model_map.get(placement.model){
prop_models[model_index].instances.push(model::ModelInstance{ prop_models[model_index].instances.push(model::ModelInstance{
transform:integer::Planar64Affine3::new( transform:integer::Planar64Affine3::new(
integer::Planar64Mat3::try_from( integer::Planar64Mat3::try_from(
glam::Mat3A::from_diagonal(glam::Vec3::splat(placement.scale)) glam::Mat3A::from_diagonal(glam::Vec3::splat(placement.scale))
//TODO: figure this out //TODO: figure this out
*glam::Mat3A::from_quat(glam::Quat::from_xyzw( *glam::Mat3A::from_quat(glam::Quat::from_xyzw(
placement.rotation.v.x,//b placement.rotation.v.x,//b
placement.rotation.v.y,//c placement.rotation.v.y,//c
placement.rotation.v.z,//d placement.rotation.v.z,//d
placement.rotation.s,//a placement.rotation.s,//a
)) ))
).unwrap(), ).unwrap(),
valve_transform(<[f32;3]>::from(placement.origin)), valve_transform(<[f32;3]>::from(placement.origin)),
), ),
attributes:model::CollisionAttributes::Decoration, attributes:model::CollisionAttributes::Decoration,
..Default::default() ..Default::default()
}); });
}else{ }else{
//println!("model not found {}",placement.model); //println!("model not found {}",placement.model);
} }
} }
//actually add the prop models //actually add the prop models
prop_models.append(&mut models); prop_models.append(&mut models);
Ok(model::MeshInstances{ Ok(model::MeshInstances{
textures:name_from_texture_id, textures:name_from_texture_id,
models:prop_models, models:prop_models,
spawn_point, spawn_point,
modes:Vec::new(), modes:Vec::new(),
}) })
} }