data structure rewrite + refactor loaders
This commit is contained in:
parent
79b8120106
commit
38efed0d04
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -200,6 +200,16 @@ version = "0.14.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "id"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.itzana.me/Quaternions/id?rev=1f710976cc786c8853dab73d6e1cee53158deeb0#1f710976cc786c8853dab73d6e1cee53158deeb0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
@ -344,9 +354,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "strafesnet_common"
|
name = "strafesnet_common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.itzana.me/StrafesNET/common?rev=434ca29aef7e3015c9ca1ed45de8fef42e33fdfb#434ca29aef7e3015c9ca1ed45de8fef42e33fdfb"
|
source = "git+https://git.itzana.me/StrafesNET/common?rev=47cdea0c8a5d10a2440ca6270a975d560aa3642d#47cdea0c8a5d10a2440ca6270a975d560aa3642d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
|
"id",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7,6 +7,6 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glam = "0.25.0"
|
glam = "0.25.0"
|
||||||
strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "434ca29aef7e3015c9ca1ed45de8fef42e33fdfb" }
|
strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "47cdea0c8a5d10a2440ca6270a975d560aa3642d" }
|
||||||
vbsp = "0.5.0"
|
vbsp = "0.5.0"
|
||||||
vmdl = "0.1.1"
|
vmdl = "0.1.1"
|
||||||
|
221
src/bsp.rs
221
src/bsp.rs
@ -1,108 +1,126 @@
|
|||||||
use strafesnet_common::{model,integer};
|
use strafesnet_common::{map,model,integer,gameplay_attributes};
|
||||||
|
|
||||||
const VALVE_SCALE:f32=1.0/16.0;
|
const VALVE_SCALE:f32=1.0/16.0;
|
||||||
fn valve_transform(v:[f32;3])->integer::Planar64Vec3{
|
fn valve_transform(v:[f32;3])->integer::Planar64Vec3{
|
||||||
integer::Planar64Vec3::try_from([v[0]*VALVE_SCALE,v[2]*VALVE_SCALE,-v[1]*VALVE_SCALE]).unwrap()
|
integer::Planar64Vec3::try_from([v[0]*VALVE_SCALE,v[2]*VALVE_SCALE,-v[1]*VALVE_SCALE]).unwrap()
|
||||||
}
|
}
|
||||||
pub fn generate_indexed_models<R:std::io::Read+std::io::Seek>(input:&mut R)->Result<model::IndexedModelInstances,vbsp::BspError>{
|
pub fn convert<AcquireTextureId,AcquireMeshId>(
|
||||||
let mut s=Vec::new();
|
bsp:&vbsp::Bsp,
|
||||||
|
mut acquire_texture_id:AcquireTextureId,
|
||||||
|
mut acquire_mesh_id:AcquireMeshId
|
||||||
|
)->strafesnet_common::map::CompleteMap
|
||||||
|
where
|
||||||
|
AcquireTextureId:FnMut(&str)->model::TextureId,
|
||||||
|
AcquireMeshId:FnMut(&str)->model::MeshId,
|
||||||
|
{
|
||||||
|
let mut unique_render_configs=Vec::new();
|
||||||
|
|
||||||
match input.read_to_end(&mut s){
|
let mut unique_attributes=Vec::new();
|
||||||
Ok(_)=>(),
|
unique_attributes.push(gameplay_attributes::CollisionAttributes::contact_default());
|
||||||
Err(e)=>println!("load_bsp::generate_indexed_models read_to_end failed: {:?}",e),
|
const TEMP_TOUCH_ME_ATTRIBUTE:gameplay_attributes::CollisionAttributesId=gameplay_attributes::CollisionAttributesId::new(0);
|
||||||
|
|
||||||
|
//declare all prop models to Loader
|
||||||
|
for prop in bsp.static_props(){
|
||||||
|
acquire_mesh_id(prop.model());
|
||||||
}
|
}
|
||||||
|
|
||||||
match vbsp::Bsp::read(s.as_slice()){
|
//TODO: make the main map one single mesh with a bunch of different physics groups and graphics groups
|
||||||
Ok(bsp)=>{
|
|
||||||
let mut spawn_point=integer::Planar64Vec3::ZERO;
|
|
||||||
|
|
||||||
let vertices: Vec<_> = bsp
|
//the generated MeshIds in here will collide with the Loader Mesh Ids
|
||||||
.vertices
|
//but I can't think of a good workaround other than just remapping one later.
|
||||||
.iter()
|
let (meshes,models):(Vec<model::Mesh>,Vec<model::Model>)=bsp.models().enumerate().map(|(mesh_id,world_model)|{
|
||||||
.map(|vertex|<[f32;3]>::from(vertex.position))
|
let mesh_id=model::MeshId::new(mesh_id as u32);
|
||||||
.collect();
|
//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 graphics_groups=Vec::new();
|
||||||
|
let mut physics_group=model::IndexedPhysicsGroup::default();
|
||||||
|
let polygon_groups=world_model.faces().enumerate().map(|(polygon_group_id,face)|{
|
||||||
|
let polygon_group_id=model::PolygonGroupId::new(polygon_group_id as u32);
|
||||||
|
let face_texture=face.texture();
|
||||||
|
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_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 mut name_from_texture_id=Vec::new();
|
//texture
|
||||||
let mut texture_id_from_name=std::collections::HashMap::new();
|
let texture_id=acquire_texture_id(face_texture_data.name()); //this is equivalent to a get_or_create pattern because there is a singular no-texture RenderId
|
||||||
|
//so RenderId==TextureId
|
||||||
|
//not the most failsafe code but this is just for the map tool lmao
|
||||||
|
if unique_render_configs.len()==texture_id.get() as usize{
|
||||||
|
unique_render_configs.push(model::RenderConfig::texture(texture_id));
|
||||||
|
};
|
||||||
|
let render_id=model::RenderConfigId::new(texture_id.get());
|
||||||
|
|
||||||
let mut models=bsp.models().map(|world_model|{
|
//normal
|
||||||
//non-deduplicated
|
let normal=face.normal();
|
||||||
let mut spam_pos=Vec::new();
|
let normal_idx=spam_normal.len() as u32;
|
||||||
let mut spam_tex=Vec::new();
|
spam_normal.push(valve_transform(<[f32;3]>::from(normal)));
|
||||||
let mut spam_normal=Vec::new();
|
let mut indices:Vec<model::VertexId>=face.vertex_positions().map(|vertex_position|{
|
||||||
let mut spam_vertices=Vec::new();
|
let vertex_xyz=<[f32;3]>::from(vertex_position);
|
||||||
let groups=world_model.faces()
|
let pos=glam::Vec3A::from_array(vertex_xyz);
|
||||||
.filter(|face| face.is_visible())//TODO: look at this
|
let pos_idx=spam_pos.len();
|
||||||
.map(|face|{
|
spam_pos.push(valve_transform(vertex_xyz));
|
||||||
let face_texture=face.texture();
|
|
||||||
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_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);
|
|
||||||
|
|
||||||
//texture
|
//calculate texture coordinates
|
||||||
let texture_id=if let Some(&texture_id)=texture_id_from_name.get(face_texture_data.name()){
|
let tex=(glam::vec2(pos.dot(texture_u),pos.dot(texture_v))+texture_offset)/texture_size;
|
||||||
texture_id
|
let tex_idx=spam_tex.len() as u32;
|
||||||
}else{
|
spam_tex.push(tex);
|
||||||
let texture_id=name_from_texture_id.len() as u32;
|
|
||||||
texture_id_from_name.insert(face_texture_data.name().to_string(),texture_id);
|
|
||||||
name_from_texture_id.push(face_texture_data.name().to_string());
|
|
||||||
texture_id
|
|
||||||
};
|
|
||||||
|
|
||||||
//normal
|
let vertex_id=model::VertexId::new(spam_vertices.len() as u32);
|
||||||
let normal=face.normal();
|
spam_vertices.push(model::IndexedVertex{
|
||||||
let normal_idx=spam_normal.len() as u32;
|
pos:model::PositionId::new(pos_idx as u32),
|
||||||
spam_normal.push(valve_transform(<[f32;3]>::from(normal)));
|
tex:model::TextureCoordinateId::new(tex_idx as u32),
|
||||||
let mut vertices:Vec<u32>=face.vertex_indexes().map(|vertex_index|{
|
normal:model::NormalId::new(normal_idx),
|
||||||
let pos=glam::Vec3A::from_array(vertices[vertex_index as usize]);
|
color:model::ColorId::new(0),
|
||||||
let pos_idx=spam_pos.len();
|
});
|
||||||
spam_pos.push(valve_transform(vertices[vertex_index as usize]));
|
vertex_id
|
||||||
|
|
||||||
//calculate texture coordinates
|
|
||||||
let tex=(glam::vec2(pos.dot(texture_u),pos.dot(texture_v))+texture_offset)/texture_size;
|
|
||||||
let tex_idx=spam_tex.len() as u32;
|
|
||||||
spam_tex.push(tex);
|
|
||||||
|
|
||||||
let i=spam_vertices.len() as u32;
|
|
||||||
spam_vertices.push(model::IndexedVertex{
|
|
||||||
pos: pos_idx as u32,
|
|
||||||
tex: tex_idx as u32,
|
|
||||||
normal: normal_idx,
|
|
||||||
color: 0,
|
|
||||||
});
|
|
||||||
i
|
|
||||||
}).collect();
|
|
||||||
vertices.reverse();
|
|
||||||
model::IndexedGroup{
|
|
||||||
texture:Some(texture_id),
|
|
||||||
polys:vec![model::IndexedPolygon{vertices}],
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
model::IndexedModel{
|
|
||||||
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::ModelInstance{
|
|
||||||
attributes:model::CollisionAttributes::Decoration,
|
|
||||||
transform:integer::Planar64Affine3::new(
|
|
||||||
integer::Planar64Mat3::default(),
|
|
||||||
valve_transform(<[f32;3]>::from(world_model.origin))
|
|
||||||
),
|
|
||||||
..Default::default()
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
}).collect();
|
}).collect();
|
||||||
|
if face.is_visible(){
|
||||||
//dedupe prop models
|
graphics_groups.push(model::IndexedGraphicsGroup{
|
||||||
let mut model_dedupe=std::collections::HashSet::new();
|
render:render_id,
|
||||||
for prop in bsp.static_props(){
|
groups:vec![polygon_group_id],
|
||||||
model_dedupe.insert(prop.model());
|
})
|
||||||
}
|
}
|
||||||
|
physics_group.groups.push(polygon_group_id);
|
||||||
|
model::PolygonGroup::PolygonList(model::PolygonList::new(vec![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,
|
||||||
|
polygon_groups,
|
||||||
|
graphics_groups,
|
||||||
|
physics_groups:vec![physics_group],
|
||||||
|
},
|
||||||
|
model::Model{
|
||||||
|
mesh:mesh_id,
|
||||||
|
attributes:TEMP_TOUCH_ME_ATTRIBUTE,
|
||||||
|
transform:integer::Planar64Affine3::new(
|
||||||
|
integer::Planar64Mat3::default(),
|
||||||
|
valve_transform(<[f32;3]>::from(world_model.origin))
|
||||||
|
),
|
||||||
|
color:glam::Vec4::ONE,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}).unzip();
|
||||||
|
|
||||||
|
map::CompleteMap{
|
||||||
|
attributes:unique_attributes,
|
||||||
|
meshes,
|
||||||
|
render_configs:unique_render_configs,
|
||||||
|
models,
|
||||||
|
modes:strafesnet_common::gameplay_modes::Modes::new(Vec::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//call self.acquire_texture_id for each texture in the mesh
|
||||||
//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();
|
||||||
@ -137,16 +155,16 @@ pub fn generate_indexed_models<R:std::io::Read+std::io::Seek>(input:&mut R)->Res
|
|||||||
spam_normal.push(valve_transform(<[f32;3]>::from(vertex.normal)));
|
spam_normal.push(valve_transform(<[f32;3]>::from(vertex.normal)));
|
||||||
spam_tex.push(glam::Vec2::from_array(vertex.texture_coordinates));
|
spam_tex.push(glam::Vec2::from_array(vertex.texture_coordinates));
|
||||||
spam_vertices.push(model::IndexedVertex{
|
spam_vertices.push(model::IndexedVertex{
|
||||||
pos:i as u32,
|
pos:model::PositionId::new(i as u32),
|
||||||
tex:i as u32,
|
tex:model::TextureCoordinateId::new(i as u32),
|
||||||
normal:i as u32,
|
normal:model::NormalId::new(i as u32),
|
||||||
color:0,
|
color:model::ColorId::new(0),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let model_id=prop_models.len();
|
let model_id=prop_models.len();
|
||||||
model_map.insert(model_name,model_id);
|
model_map.insert(model_name,model_id);
|
||||||
prop_models.push(model::IndexedModel{
|
prop_models.push(model::Mesh{
|
||||||
unique_pos:spam_pos,
|
unique_pos:spam_pos,
|
||||||
unique_normal:spam_normal,
|
unique_normal:spam_normal,
|
||||||
unique_tex:spam_tex,
|
unique_tex:spam_tex,
|
||||||
@ -221,17 +239,4 @@ pub fn generate_indexed_models<R:std::io::Read+std::io::Seek>(input:&mut R)->Res
|
|||||||
|
|
||||||
//actually add the prop models
|
//actually add the prop models
|
||||||
prop_models.append(&mut models);
|
prop_models.append(&mut models);
|
||||||
|
*/
|
||||||
Ok(model::IndexedModelInstances{
|
|
||||||
textures:name_from_texture_id,
|
|
||||||
models:prop_models,
|
|
||||||
spawn_point,
|
|
||||||
modes:Vec::new(),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
Err(e)=>{
|
|
||||||
println!("rotten {:?}",e);
|
|
||||||
Err(e)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
37
src/lib.rs
37
src/lib.rs
@ -1 +1,36 @@
|
|||||||
pub mod bsp;
|
mod bsp;
|
||||||
|
|
||||||
|
pub struct Bsp(vbsp::Bsp);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ReadError{
|
||||||
|
Bsp(vbsp::BspError),
|
||||||
|
Io(std::io::Error),
|
||||||
|
}
|
||||||
|
impl std::fmt::Display for ReadError{
|
||||||
|
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
|
||||||
|
write!(f,"{self:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl std::error::Error for ReadError{}
|
||||||
|
|
||||||
|
pub fn read<R:std::io::Read>(mut input:R)->Result<Bsp,ReadError>{
|
||||||
|
let mut s=Vec::new();
|
||||||
|
|
||||||
|
//TODO: mmap
|
||||||
|
input.read_to_end(&mut s).map_err(ReadError::Io)?;
|
||||||
|
|
||||||
|
vbsp::Bsp::read(s.as_slice()).map(Bsp).map_err(ReadError::Bsp)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert<AcquireTextureId,AcquireMeshId>(
|
||||||
|
bsp:&Bsp,
|
||||||
|
acquire_texture_id:AcquireTextureId,
|
||||||
|
acquire_mesh_id:AcquireMeshId
|
||||||
|
)->strafesnet_common::map::CompleteMap
|
||||||
|
where
|
||||||
|
AcquireTextureId:FnMut(&str)->strafesnet_common::model::TextureId,
|
||||||
|
AcquireMeshId:FnMut(&str)->strafesnet_common::model::MeshId,
|
||||||
|
{
|
||||||
|
bsp::convert(&bsp.0,acquire_texture_id,acquire_mesh_id)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user