diff --git a/src/model_physics.rs b/src/model_physics.rs index 2002113..3c15c73 100644 --- a/src/model_physics.rs +++ b/src/model_physics.rs @@ -110,7 +110,7 @@ pub struct PhysicsMeshTopology{ edge_topology:Vec, vert_topology:Vec, } -#[derive(Hash,id::Id,Eq,PartialEq)] +#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq)] pub struct PhysicsMeshId(u32); impl Into for PhysicsMeshId{ fn into(self)->MeshId{ @@ -395,11 +395,6 @@ pub struct PhysicsMeshView<'a>{ data:&'a PhysicsMeshData, topology:&'a PhysicsMeshTopology, } -impl PhysicsMeshView<'_>{ - pub fn verts<'a>(&'a self)->impl Iterator+'a{ - self.data.verts.iter().map(|&Vert(pos)|pos) - } -} impl MeshQuery for PhysicsMeshView<'_>{ fn face_nd(&self,face_id:SubmeshFaceId)->(Planar64Vec3,Planar64){ let face_idx=self.topology.faces[face_id.get() as usize].get() as usize; @@ -456,6 +451,9 @@ impl TransformedMesh<'_>{ transform, } } + pub fn verts<'a>(&'a self)->impl Iterator+'a{ + self.view.data.verts.iter().map(|&Vert(pos)|self.transform.vertex.transform_point3(pos)) + } fn farthest_vert(&self,dir:Planar64Vec3)->SubmeshVertId{ let mut best_dot=Planar64::MIN; let mut best_vert=SubmeshVertId(0); diff --git a/src/physics.rs b/src/physics.rs index f448a0f..d6f65fd 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -6,7 +6,7 @@ use strafesnet_common::map; use strafesnet_common::aabb; use strafesnet_common::gameplay_modes::{self,StageId}; use strafesnet_common::gameplay_attributes::{self,CollisionAttributesId}; -use strafesnet_common::model::ModelId; +use strafesnet_common::model::{MeshId,ModelId}; use strafesnet_common::gameplay_style::{self,StyleModifiers}; use strafesnet_common::instruction::{self,InstructionEmitter,InstructionConsumer,TimedInstruction}; use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64Vec2}; @@ -324,13 +324,15 @@ impl HitboxMesh{ fn new(mesh:PhysicsMesh,transform:integer::Planar64Affine3)->Self{ //calculate extents let mut aabb=aabb::Aabb::default(); - for vert in mesh.complete_mesh_view().verts(){ - aabb.grow(transform.transform_point3(vert)); + let transform=PhysicsMeshTransform::new(transform); + let transformed_mesh=TransformedMesh::new(mesh.complete_mesh_view(),&transform); + for vert in transformed_mesh.verts(){ + aabb.grow(vert); } Self{ halfsize:aabb.size()/2, mesh, - transform:PhysicsMeshTransform::new(transform) + transform, } } #[inline] @@ -508,7 +510,7 @@ impl TryFrom<&gameplay_attributes::CollisionAttributes> for PhysicsCollisionAttr } } } -#[derive(Hash,id::Id,Eq,PartialEq)] +#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq)] struct PhysicsAttributesId(u32); impl Into for PhysicsAttributesId{ fn into(self)->CollisionAttributesId{ @@ -988,25 +990,53 @@ impl PhysicsContext{ pub fn generate_models(&mut self,map:&map::CompleteMap){ self.data.modes=map.modes.clone(); - self.data.models.attributes=map.attributes - .iter().enumerate().filter_map(|(attr_id,m_attr)| - PhysicsCollisionAttributes::try_from(m_attr).ok().map(|p_attr| - (PhysicsAttributesId::new(attr_id as u32),p_attr) - ) - ).collect(); - self.data.models.meshes=map.meshes.iter().enumerate().map(|(mesh_id,mesh)| - (PhysicsMeshId::new(mesh_id as u32),PhysicsMesh::from(mesh)) - ).collect(); - self.data.models.models=map.models.iter().enumerate().map(|(model_id,model)| - (PhysicsModelId::new(model_id as u32),PhysicsModel::new(model.mesh.into(),model.attributes.into(),PhysicsMeshTransform::new(model.transform))) - ).collect(); + //TODO redo this with models first and only add used atributes and meshes + let mut used_attributes=Vec::new(); + let mut physics_attr_id_from_model_attr_id=HashMap::::new(); + let mut used_meshes=Vec::new(); + let mut physics_mesh_id_from_model_mesh_id=HashMap::::new(); + self.data.models.models=map.models.iter().enumerate().filter_map(|(model_id,model)|{ + let attr_id=if let Some(&attr_id)=physics_attr_id_from_model_attr_id.get(&model.attributes){ + attr_id + }else{ + //check if it's real + match map.attributes.get(model.attributes.get() as usize).and_then(|m_attr|{ + PhysicsCollisionAttributes::try_from(m_attr).map_or(None,|p_attr|{ + let attr_id=PhysicsAttributesId::new(used_attributes.len() as u32); + used_attributes.push(p_attr); + physics_attr_id_from_model_attr_id.insert(model.attributes,attr_id); + Some(attr_id) + }) + }){ + Some(attr_id)=>attr_id, + None=>return None, + } + }; + let mesh_id=if let Some(&mesh_id)=physics_mesh_id_from_model_mesh_id.get(&model.mesh){ + mesh_id + }else{ + match map.meshes.get(model.mesh.get() as usize).and_then(|mesh|{ + let mesh_id=PhysicsMeshId::new(used_meshes.len() as u32); + used_meshes.push(PhysicsMesh::from(mesh)); + physics_mesh_id_from_model_mesh_id.insert(model.mesh,mesh_id); + Some(mesh_id) + }){ + Some(mesh_id)=>mesh_id, + None=>return None, + } + }; + Some((PhysicsModelId::new(model_id as u32),PhysicsModel::new(mesh_id,attr_id,PhysicsMeshTransform::new(model.transform)))) + }).collect(); + self.data.models.attributes=used_attributes.into_iter().enumerate().map(|(attr_id,attr)|(PhysicsAttributesId::new(attr_id as u32),attr)).collect(); + self.data.models.meshes=used_meshes.into_iter().enumerate().map(|(mesh_id,mesh)|(PhysicsMeshId::new(mesh_id as u32),mesh)).collect(); let convex_mesh_aabb_list=self.data.models.models.iter() .flat_map(|(&model_id,model)|{ self.data.models.meshes[&model.mesh_id].submesh_views() .enumerate().map(move|(submesh_id,view)|{ let mut aabb=aabb::Aabb::default(); - for v in view.verts(){ - aabb.grow(v) + let transformed_mesh=TransformedMesh::new(view,&model.transform); + for v in transformed_mesh.verts(){ + aabb.grow(v); } (ConvexMeshId{ model_id,