diff --git a/src/graphics.rs b/src/graphics.rs index 00edd3f..224948a 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -150,7 +150,7 @@ impl GraphicsState{ pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::CompleteMap){ //generate texture view per texture let num_textures=map.textures.len(); - let texture_views:Vec=map.textures.into_iter().enumerate().map(|(texture_id,texture_data)|{ + let texture_views:Vec=map.textures.iter().enumerate().map(|(texture_id,texture_data)|{ let image=ddsfile::Dds::read(std::io::Cursor::new(texture_data)).unwrap(); let (mut width,mut height)=(image.get_width(),image.get_height()); @@ -214,7 +214,7 @@ impl GraphicsState{ color:GraphicsModelColor4::new(model.color), }; //get or create owned mesh map - let mut owned_mesh_map=if let Some(map)=owned_mesh_id_from_mesh_id_render_config_id.get_mut(&model.mesh){ + let owned_mesh_map=if let Some(map)=owned_mesh_id_from_mesh_id_render_config_id.get_mut(&model.mesh){ map }else{ let map=HashMap::new(); @@ -225,41 +225,38 @@ impl GraphicsState{ //check each group, if it's using a new render config then make a new clone of the model if let Some(mesh)=map.meshes.get(model.mesh.get() as usize){ for graphics_group in mesh.graphics_groups.iter(){ - let render_config=map.render_configs[graphics_group.render.get() as usize]; + let render_config=&map.render_configs[graphics_group.render.get() as usize]; if model.color.w==0.0&&render_config.texture.is_none(){ continue; } //get or create owned mesh - let mut owned_mesh=unique_render_config_models.get_mut( - if let Some(&owned_mesh_id)=owned_mesh_map.get(&graphics_group.render){ - owned_mesh_id - }else{ - //create - let owned_mesh_id=IndexedGraphicsMeshOwnedRenderConfigId::new(unique_render_config_models.len() as u32); - owned_mesh_map.insert(graphics_group.render,owned_mesh_id); - //push - unique_render_config_models.push(IndexedGraphicsMeshOwnedRenderConfig{ - unique_pos:mesh.unique_pos.iter().map(|&v|*Into::::into(v).as_ref()).collect(), - unique_tex:mesh.unique_tex.iter().map(|v|*v.as_ref()).collect(), - unique_normal:mesh.unique_normal.iter().map(|&v|*Into::::into(v).as_ref()).collect(), - unique_color:mesh.unique_color.iter().map(|v|*v.as_ref()).collect(), - unique_vertices:mesh.unique_vertices.clone(), - render_config:graphics_group.render, - polys:model::PolygonGroup::PolygonList(model::PolygonList::new( - graphics_group.groups.iter().flat_map(|polygon_group_id|{ - mesh.polygon_groups[polygon_group_id.get() as usize].polys() - }) - .map(|vertex_id_slice| - vertex_id_slice.iter().copied().collect() - ).collect() - )), - instances:Vec::new(), - }); - owned_mesh_id - }.get() as usize - ).unwrap(); - //this utm_id is going to take a lot of hashing to generate! - owned_mesh.instances.push(instance); + let owned_mesh_id=if let Some(&owned_mesh_id)=owned_mesh_map.get(&graphics_group.render){ + owned_mesh_id + }else{ + //create + let owned_mesh_id=IndexedGraphicsMeshOwnedRenderConfigId::new(unique_render_config_models.len() as u32); + owned_mesh_map.insert(graphics_group.render,owned_mesh_id); + unique_render_config_models.push(IndexedGraphicsMeshOwnedRenderConfig{ + unique_pos:mesh.unique_pos.iter().map(|&v|*Into::::into(v).as_ref()).collect(), + unique_tex:mesh.unique_tex.iter().map(|v|*v.as_ref()).collect(), + unique_normal:mesh.unique_normal.iter().map(|&v|*Into::::into(v).as_ref()).collect(), + unique_color:mesh.unique_color.iter().map(|v|*v.as_ref()).collect(), + unique_vertices:mesh.unique_vertices.clone(), + render_config:graphics_group.render, + polys:model::PolygonGroup::PolygonList(model::PolygonList::new( + graphics_group.groups.iter().flat_map(|polygon_group_id|{ + mesh.polygon_groups[polygon_group_id.get() as usize].polys() + }) + .map(|vertex_id_slice| + vertex_id_slice.iter().copied().collect() + ).collect() + )), + instances:Vec::new(), + }); + owned_mesh_id + }; + let owned_mesh=unique_render_config_models.get_mut(owned_mesh_id.get() as usize).unwrap(); + owned_mesh.instances.push(instance.clone()); } } } @@ -440,7 +437,7 @@ impl GraphicsState{ indices.push(i); }else{ let i=vertices.len(); - let vertex=model.unique_vertices[vertex_index.get() as usize]; + let vertex=&model.unique_vertices[vertex_index.get() as usize]; vertices.push(GraphicsVertex{ pos:model.unique_pos[vertex.pos.get() as usize], tex:model.unique_tex[vertex.tex.get() as usize], @@ -482,7 +479,7 @@ impl GraphicsState{ contents:bytemuck::cast_slice(&model_uniforms), usage:wgpu::BufferUsages::UNIFORM|wgpu::BufferUsages::COPY_DST, }); - let render_config=map.render_configs[model.render_config.get() as usize]; + let render_config=&map.render_configs[model.render_config.get() as usize]; let texture_view=match render_config.texture{ Some(texture_id)=>&texture_views[texture_id.get() as usize], None=>&self.temp_squid_texture_view, @@ -979,7 +976,7 @@ const MODEL_BUFFER_SIZE:usize=4*4 + 12 + 4;//let size=std::mem::size_of::Vec{ let mut raw=Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len()); - for (i,mi) in instances.iter().enumerate(){ + for mi in instances{ //model transform raw.extend_from_slice(&AsRef::<[f32; 4*4]>::as_ref(&mi.transform)[..]); //normal transform diff --git a/src/model_graphics.rs b/src/model_graphics.rs index 1ad70df..2468cda 100644 --- a/src/model_graphics.rs +++ b/src/model_graphics.rs @@ -1,5 +1,5 @@ use bytemuck::{Pod,Zeroable}; -use strafesnet_common::model::{IndexedVertex,PolygonGroup,RenderConfigId,TextureId}; +use strafesnet_common::model::{IndexedVertex,PolygonGroup,RenderConfigId}; #[derive(Clone,Copy,Pod,Zeroable)] #[repr(C)] pub struct GraphicsVertex{ @@ -8,7 +8,7 @@ pub struct GraphicsVertex{ pub normal:[f32;3], pub color:[f32;4], } -#[derive(id::Id)] +#[derive(Clone,Copy,id::Id)] pub struct IndexedGraphicsMeshOwnedRenderConfigId(u32); pub struct IndexedGraphicsMeshOwnedRenderConfig{ pub unique_pos:Vec<[f32;3]>, @@ -30,7 +30,7 @@ pub struct GraphicsMeshOwnedRenderConfig{ pub render_config:RenderConfigId, pub instances:Vec, } -#[derive(Clone,PartialEq,id::Id)] +#[derive(Clone,Copy,PartialEq,id::Id)] pub struct GraphicsModelColor4(glam::Vec4); impl std::hash::Hash for GraphicsModelColor4{ fn hash(&self,state:&mut H) { diff --git a/src/model_physics.rs b/src/model_physics.rs index dd0980a..6612d5b 100644 --- a/src/model_physics.rs +++ b/src/model_physics.rs @@ -92,7 +92,7 @@ struct VertRefs{ faces:Vec, edges:Vec, } -struct PhysicsMeshData{ +pub struct PhysicsMeshData{ //this contains all real and virtual faces used in both the complete mesh and convex submeshes //faces are sorted such that all faces that belong to the complete mesh appear first, and then //all remaining faces are virtual to operate internal logic of the face crawler @@ -101,7 +101,7 @@ struct PhysicsMeshData{ faces:Vec,//MeshFaceId indexes this list verts:Vec,//MeshVertId indexes this list } -struct PhysicsMeshTopology{ +pub struct PhysicsMeshTopology{ //mapping of local ids to PhysicsMeshData ids faces:Vec,//SubmeshFaceId indexes this list verts:Vec,//SubmeshVertId indexes this list @@ -126,11 +126,10 @@ impl From for PhysicsMeshId{ pub struct PhysicsSubmeshId(u32); pub struct PhysicsMesh{ data:PhysicsMeshData, - //index 0 is the complete mesh. - //index 1-2+ is convex submeshes. - //Most objects in roblox maps are already convex, so the list length is 1 - //as soon as the mesh is divided into 2 submeshes, the list length jumps to 3. - //length 2 is unnecessary since the complete mesh would be a duplicate of the only submesh, but would still function properly + complete_mesh:PhysicsMeshTopology, + //Most objects in roblox maps are already convex, so the list length is 0 + //as soon as the mesh is divided into 2 submeshes, the list length jumps to 2. + //length 1 is unnecessary since the complete mesh would be a duplicate of the only submesh, but would still function properly submeshes:Vec, } impl PhysicsMesh{ @@ -160,12 +159,12 @@ impl PhysicsMesh{ faces:(0..data.faces.len() as u32).map(MeshFaceId::new).collect(), verts:(0..data.verts.len() as u32).map(MeshVertId::new).collect(), face_topology:vec![ - FaceRefs{edges:vec![SubmeshDirectedEdgeId(9223372036854775808),SubmeshDirectedEdgeId(9223372036854775809),SubmeshDirectedEdgeId(9223372036854775810),SubmeshDirectedEdgeId(3)]}, - FaceRefs{edges:vec![SubmeshDirectedEdgeId(9223372036854775812),SubmeshDirectedEdgeId(9223372036854775813),SubmeshDirectedEdgeId(6),SubmeshDirectedEdgeId(1)]}, - FaceRefs{edges:vec![SubmeshDirectedEdgeId(7),SubmeshDirectedEdgeId(2),SubmeshDirectedEdgeId(9223372036854775814),SubmeshDirectedEdgeId(9223372036854775816)]}, - FaceRefs{edges:vec![SubmeshDirectedEdgeId(8),SubmeshDirectedEdgeId(5),SubmeshDirectedEdgeId(9223372036854775817),SubmeshDirectedEdgeId(10)]}, - FaceRefs{edges:vec![SubmeshDirectedEdgeId(9223372036854775815),SubmeshDirectedEdgeId(9223372036854775818),SubmeshDirectedEdgeId(11),SubmeshDirectedEdgeId(9223372036854775811)]}, - FaceRefs{edges:vec![SubmeshDirectedEdgeId(4),SubmeshDirectedEdgeId(0),SubmeshDirectedEdgeId(9223372036854775819),SubmeshDirectedEdgeId(9)]} + FaceRefs{edges:vec![SubmeshDirectedEdgeId((9223372036854775808u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775809u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775810u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId(3)]}, + FaceRefs{edges:vec![SubmeshDirectedEdgeId((9223372036854775812u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775813u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId(6),SubmeshDirectedEdgeId(1)]}, + FaceRefs{edges:vec![SubmeshDirectedEdgeId(7),SubmeshDirectedEdgeId(2),SubmeshDirectedEdgeId((9223372036854775814u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775816u64-(1<<63)+(1<<31)) as u32)]}, + FaceRefs{edges:vec![SubmeshDirectedEdgeId(8),SubmeshDirectedEdgeId(5),SubmeshDirectedEdgeId((9223372036854775817u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId(10)]}, + FaceRefs{edges:vec![SubmeshDirectedEdgeId((9223372036854775815u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775818u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId(11),SubmeshDirectedEdgeId((9223372036854775811u64-(1<<63)+(1<<31)) as u32)]}, + FaceRefs{edges:vec![SubmeshDirectedEdgeId(4),SubmeshDirectedEdgeId(0),SubmeshDirectedEdgeId((9223372036854775819u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId(9)]} ], edge_topology:vec![ EdgeRefs{faces:[SubmeshFaceId(0),SubmeshFaceId(5)],verts:[SubmeshVertId(0),SubmeshVertId(1)]}, @@ -182,19 +181,20 @@ impl PhysicsMesh{ EdgeRefs{faces:[SubmeshFaceId(5),SubmeshFaceId(4)],verts:[SubmeshVertId(0),SubmeshVertId(7)]} ], vert_topology:vec![ - VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(4),SubmeshFaceId(5)],edges:vec![SubmeshDirectedEdgeId(9223372036854775811),SubmeshDirectedEdgeId(9223372036854775819),SubmeshDirectedEdgeId(9223372036854775808)]}, - VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(5),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(9223372036854775812),SubmeshDirectedEdgeId(0),SubmeshDirectedEdgeId(9223372036854775809)]}, - VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(2),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(1),SubmeshDirectedEdgeId(9223372036854775810),SubmeshDirectedEdgeId(9223372036854775814)]}, - VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(2),SubmeshFaceId(4)],edges:vec![SubmeshDirectedEdgeId(2),SubmeshDirectedEdgeId(3),SubmeshDirectedEdgeId(9223372036854775815)]}, - VertRefs{faces:vec![SubmeshFaceId(3),SubmeshFaceId(5),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(4),SubmeshDirectedEdgeId(9223372036854775817),SubmeshDirectedEdgeId(9223372036854775813)]}, - VertRefs{faces:vec![SubmeshFaceId(2),SubmeshFaceId(3),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(5),SubmeshDirectedEdgeId(6),SubmeshDirectedEdgeId(9223372036854775816)]}, - VertRefs{faces:vec![SubmeshFaceId(2),SubmeshFaceId(3),SubmeshFaceId(4)],edges:vec![SubmeshDirectedEdgeId(7),SubmeshDirectedEdgeId(8),SubmeshDirectedEdgeId(9223372036854775818)]}, + VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(4),SubmeshFaceId(5)],edges:vec![SubmeshDirectedEdgeId((9223372036854775811u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775819u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775808u64-(1<<63)+(1<<31)) as u32)]}, + VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(5),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId((9223372036854775812u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId(0),SubmeshDirectedEdgeId((9223372036854775809u64-(1<<63)+(1<<31)) as u32)]}, + VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(2),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(1),SubmeshDirectedEdgeId((9223372036854775810u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775814u64-(1<<63)+(1<<31)) as u32)]}, + VertRefs{faces:vec![SubmeshFaceId(0),SubmeshFaceId(2),SubmeshFaceId(4)],edges:vec![SubmeshDirectedEdgeId(2),SubmeshDirectedEdgeId(3),SubmeshDirectedEdgeId((9223372036854775815u64-(1<<63)+(1<<31)) as u32)]}, + VertRefs{faces:vec![SubmeshFaceId(3),SubmeshFaceId(5),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(4),SubmeshDirectedEdgeId((9223372036854775817u64-(1<<63)+(1<<31)) as u32),SubmeshDirectedEdgeId((9223372036854775813u64-(1<<63)+(1<<31)) as u32)]}, + VertRefs{faces:vec![SubmeshFaceId(2),SubmeshFaceId(3),SubmeshFaceId(1)],edges:vec![SubmeshDirectedEdgeId(5),SubmeshDirectedEdgeId(6),SubmeshDirectedEdgeId((9223372036854775816u64-(1<<63)+(1<<31)) as u32)]}, + VertRefs{faces:vec![SubmeshFaceId(2),SubmeshFaceId(3),SubmeshFaceId(4)],edges:vec![SubmeshDirectedEdgeId(7),SubmeshDirectedEdgeId(8),SubmeshDirectedEdgeId((9223372036854775818u64-(1<<63)+(1<<31)) as u32)]}, VertRefs{faces:vec![SubmeshFaceId(4),SubmeshFaceId(3),SubmeshFaceId(5)],edges:vec![SubmeshDirectedEdgeId(10),SubmeshDirectedEdgeId(11),SubmeshDirectedEdgeId(9)]} ] }; Self{ data, - submeshes:vec![mesh_topology], + complete_mesh:mesh_topology, + submeshes:Vec::new(), } } pub fn unit_cylinder()->Self{ @@ -206,7 +206,7 @@ impl PhysicsMesh{ } #[inline] pub const fn complete_mesh(&self)->&PhysicsMeshTopology{ - &self.submeshes[0] + &self.complete_mesh } #[inline] pub const fn complete_mesh_view(&self)->PhysicsMeshView{ @@ -216,12 +216,16 @@ impl PhysicsMesh{ } } #[inline] - pub const fn submeshes(&self)->&[PhysicsMeshTopology]{ - //the complete mesh is already a convex mesh when len()==1, len()==2 is invalid but will still work - &self.submeshes[self.submeshes.len().saturating_sub(1).min(1)..] + pub fn submeshes(&self)->&[PhysicsMeshTopology]{ + //the complete mesh is already a convex mesh when len()==0, len()==1 is invalid but will still work + if self.submeshes.len()==0{ + std::slice::from_ref(&self.complete_mesh) + }else{ + &self.submeshes.as_slice() + } } #[inline] - pub const fn submesh_view(&self,submesh_id:PhysicsSubmeshId)->PhysicsMeshView{ + pub fn submesh_view(&self,submesh_id:PhysicsSubmeshId)->PhysicsMeshView{ PhysicsMeshView{ data:&self.data, topology:&self.submeshes()[submesh_id.get() as usize], @@ -257,7 +261,7 @@ impl EdgeRefFaces{ const fn new()->Self{ Self([SubmeshFaceId(0);2]) } - const fn push(&mut self,i:usize,face_id:SubmeshFaceId){ + fn push(&mut self,i:usize,face_id:SubmeshFaceId){ self.0[i]=face_id; } } @@ -283,20 +287,21 @@ impl EdgePool{ impl From<&model::Mesh> for PhysicsMesh{ fn from(mesh:&model::Mesh)->Self{ assert!(mesh.unique_pos.len()!=0,"Mesh cannot have 0 vertices"); - let verts=mesh.unique_pos.into_iter().map(Vert).collect(); + let verts=mesh.unique_pos.iter().copied().map(Vert).collect(); let mut faces=Vec::new(); let mut face_id_from_face=HashMap::new(); - let submeshes=mesh.physics_groups.iter().enumerate().map(|(submesh_id,physics_group)|{ + let mut mesh_topologies:Vec=mesh.physics_groups.iter().map(|physics_group|{ //construct submesh let mut submesh_faces=Vec::new();//these contain a map from submeshId->meshId let mut submesh_verts=Vec::new(); let mut submesh_vert_id_from_mesh_vert_id=HashMap::::new(); //lazy closure - let get_submesh_vert_id=|vert_id:MeshVertId|{ + let mut get_submesh_vert_id=|vert_id:MeshVertId|{ if let Some(&submesh_vert_id)=submesh_vert_id_from_mesh_vert_id.get(&vert_id){ submesh_vert_id }else{ - let submesh_vert_id=SubmeshVertId::new(vert_id.get() as u32); + let submesh_vert_id=SubmeshVertId::new(submesh_verts.len() as u32); + submesh_verts.push(vert_id); submesh_vert_id_from_mesh_vert_id.insert(vert_id,submesh_vert_id); submesh_vert_id } @@ -304,9 +309,8 @@ impl From<&model::Mesh> for PhysicsMesh{ let mut edge_pool=EdgePool::default(); let mut vert_ref_guys=vec![VertRefGuy::default();mesh.unique_pos.len()]; let mut face_ref_guys=Vec::new(); - let submesh_id=PhysicsSubmeshId::new(submesh_id as u32); for polygon_group_id in &physics_group.groups{ - let polygon_group=mesh.polygon_groups[polygon_group_id.get() as usize]; + let polygon_group=&mesh.polygon_groups[polygon_group_id.get() as usize]; for poly_vertices in polygon_group.polys(){ let submesh_face_id=SubmeshFaceId::new(submesh_faces.len() as u32); //one face per poly @@ -354,7 +358,7 @@ impl From<&model::Mesh> for PhysicsMesh{ Some(&face_id)=>face_id, None=>{ let face_id=MeshFaceId::new(faces.len() as u32); - face_id_from_face.insert(face,face_id); + face_id_from_face.insert(face.clone(),face_id); faces.push(face); face_id } @@ -385,12 +389,13 @@ impl From<&model::Mesh> for PhysicsMesh{ faces, verts, }, - submeshes, + complete_mesh:mesh_topologies.pop().unwrap(), + submeshes:mesh_topologies, } } } -struct PhysicsMeshView<'a>{ +pub struct PhysicsMeshView<'a>{ data:&'a PhysicsMeshData, topology:&'a PhysicsMeshTopology, } @@ -460,8 +465,7 @@ impl TransformedMesh<'_>{ let mut best_vert=SubmeshVertId(0); //this happens to be well-defined. there are no virtual virtices for (i,vert_id) in self.view.topology.verts.iter().enumerate(){ - let vert=self.view.data.verts[vert_id.get() as usize]; - let p=self.transform.vertex.transform_point3(vert.0); + let p=self.transform.vertex.transform_point3(self.view.data.verts[vert_id.get() as usize].0); let d=dir.dot(p); if best_dotTransformedMesh{ - let model=self.models[&convex_mesh_id.model_id]; + let model=&self.models[&convex_mesh_id.model_id]; TransformedMesh::new( self.meshes[&model.mesh_id].submesh_view(convex_mesh_id.submesh_id), &model.transform @@ -201,7 +201,7 @@ pub struct PhysicsCamera{ } impl PhysicsCamera{ - const ANGLE_PITCH_LOWER_LIMIT:Angle32=-Angle32::FRAC_PI_2; + const ANGLE_PITCH_LOWER_LIMIT:Angle32=Angle32::NEG_FRAC_PI_2; const ANGLE_PITCH_UPPER_LIMIT:Angle32=Angle32::FRAC_PI_2; pub fn move_mouse(&mut self,mouse_pos:glam::IVec2){ let mut unclamped_mouse_pos=mouse_pos-self.mouse.pos+self.clamped_mouse_pos; @@ -261,13 +261,13 @@ mod gameplay{ pub const fn get_next_ordered_checkpoint_id(&self)->gameplay_modes::CheckpointId{ self.next_ordered_checkpoint_id } - pub const fn get_jump_count(&self,model_id:ModelId)->Option{ + pub fn get_jump_count(&self,model_id:ModelId)->Option{ self.jump_counts.get(&model_id).copied() } pub const fn ordered_checkpoint_count(&self)->u32{ self.next_ordered_checkpoint_id.get() } - pub const fn unordered_checkpoint_count(&self)->u32{ + pub fn unordered_checkpoint_count(&self)->u32{ self.unordered_checkpoints.len() as u32 } pub fn set_mode_id(&mut self,mode_id:gameplay_modes::ModeId){ @@ -278,7 +278,7 @@ mod gameplay{ self.clear_checkpoints(); self.stage_id=stage_id; } - pub const fn accumulate_ordered_checkpoint(&mut self,stage:&gameplay_modes::Stage,model_id:ModelId){ + pub fn accumulate_ordered_checkpoint(&mut self,stage:&gameplay_modes::Stage,model_id:ModelId){ if stage.is_next_ordered_checkpoint(self.get_next_ordered_checkpoint_id(),model_id){ self.next_ordered_checkpoint_id=gameplay_modes::CheckpointId::new(self.next_ordered_checkpoint_id.get()+1); } @@ -359,7 +359,7 @@ impl StyleHelper for StyleModifiers{ fn allow_strafe(&self,controls:u32)->bool{ //disable strafing according to strafe settings - self.strafe.is_some_and(|s|s.mask(controls)) + self.strafe.as_ref().is_some_and(|s|s.mask(controls)) } fn get_control_dir(&self,controls:u32)->Planar64Vec3{ @@ -1003,7 +1003,7 @@ impl PhysicsContext{ 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(|(submesh_id,view)|{ + .enumerate().map(move|(submesh_id,view)|{ let mut aabb=aabb::Aabb::default(); for v in view.verts(){ aabb.grow(v) @@ -1036,7 +1036,7 @@ impl PhysicsContext{ MoveState::Walk(WalkState{state,contact,jump_direction:_})=>{ let n=contact_normal(&data.models,&data.hitbox_mesh,contact); let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time); - let mut a; + let a; let mut v=s.style.get_walk_target_velocity(&s.camera,s.controls,&s.next_mouse,s.time,&n); s.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v); let normal_accel=-n.dot(gravity)/n.length(); @@ -1045,8 +1045,8 @@ impl PhysicsContext{ }, MoveState::Ladder(WalkState{state,contact,jump_direction:_})=>{ let n=contact_normal(&data.models,&data.hitbox_mesh,contact); - let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time); - let mut a; + //let gravity=s.touching.base_acceleration(&data.models,&s.style,&s.camera,s.controls,&s.next_mouse,s.time); + let a; let mut v=s.style.get_ladder_target_velocity(&s.camera,s.controls,&s.next_mouse,s.time,&n); s.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v); (*state,a)=WalkEnum::with_target_velocity(&s.body,&s.style,v,&n,s.style.ladder_speed,s.style.ladder_accel); @@ -1069,11 +1069,10 @@ impl PhysicsContext{ aabb.inflate(state.style.hitbox.halfsize); //common body let relative_body=VirtualBody::relative(&Body::default(),&state.body).body(state.time); - let hitbox_mesh=data.hitbox_mesh.transformed_mesh(); data.bvh.the_tester(&aabb,&mut |convex_mesh_id|{ //no checks are needed because of the time limits. let model_mesh=data.models.mesh(convex_mesh_id); - let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh); + let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh()); collector.collect(minkowski.predict_collision_in(&relative_body,collector.time()) //temp (?) code to avoid collision loops .map_or(None,|(face,time)|if time==state.time{None}else{Some((face,time))}) @@ -1170,7 +1169,7 @@ fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModi Some(teleport(body,touching,models,style,hitbox_mesh,point)) } -fn run_teleport_behaviour(wormhole:&Option,mode_state:&mut ModeState,models:&PhysicsModels,mode:&gameplay_modes::Mode,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,touching:&mut TouchingState,body:&mut Body,convex_mesh_id:ConvexMeshId)->Option{ +fn run_teleport_behaviour(wormhole:&Option,models:&PhysicsModels,mode:&gameplay_modes::Mode,style:&StyleModifiers,hitbox_mesh:&HitboxMesh,mode_state:&mut ModeState,touching:&mut TouchingState,body:&mut Body,convex_mesh_id:ConvexMeshId)->Option{ //TODO: jump count and checkpoints are always reset on teleport. //Map makers are expected to use tools to prevent //multi-boosting on JumpLimit boosters such as spawning into a SetVelocity @@ -1275,7 +1274,8 @@ fn run_teleport_behaviour(wormhole:&Option,mode_s let (walk_state,a)=WalkState::ladder(&state.body,&state.style,gravity,target_velocity,contact.clone(),&normal); state.move_state=MoveState::Ladder(walk_state); set_acceleration(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,a); - } + }, + Some(gameplay_attributes::ContactingBehaviour::NoJump)=>todo!("nyi"), None=>if state.style.surf_slope.map_or(true,|s|contact_normal(&data.models,&data.hitbox_mesh,contact).walkable(s,Planar64Vec3::Y)){ //ground let gravity=state.touching.base_acceleration(&data.models,&state.style,&state.camera,state.controls,&state.next_mouse,state.time); @@ -1289,7 +1289,7 @@ fn run_teleport_behaviour(wormhole:&Option,mode_s //check ground state.touching.insert(c); //I love making functions with 10 arguments to dodge the borrow checker - run_teleport_behaviour(&general.wormhole,&mut state.mode_state,&data.models,&data.modes.get_mode(state.mode_state.get_mode_id()).unwrap(),&state.style,&data.hitbox_mesh,&mut state.touching,&mut state.body,convex_mesh_id); + run_teleport_behaviour(&general.wormhole,&data.models,&data.modes.get_mode(state.mode_state.get_mode_id()).unwrap(),&state.style,&data.hitbox_mesh,&mut state.mode_state,&mut state.touching,&mut state.body,convex_mesh_id); //flatten v state.touching.constrain_velocity(&data.models,&data.hitbox_mesh,&mut v); match &general.booster{ @@ -1333,7 +1333,7 @@ fn run_teleport_behaviour(wormhole:&Option,mode_s (PhysicsCollisionAttributes::Intersect{intersecting: _,general},Collision::Intersect(intersect))=>{ //I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop state.touching.insert(c); - run_teleport_behaviour(&general.wormhole,&mut state.mode_state,&data.models,&data.modes.get_mode(state.mode_state.get_mode_id()).unwrap(),&state.style,&data.hitbox_mesh,&mut state.touching,&mut state.body,convex_mesh_id); + run_teleport_behaviour(&general.wormhole,&data.models,&data.modes.get_mode(state.mode_state.get_mode_id()).unwrap(),&state.style,&data.hitbox_mesh,&mut state.mode_state,&mut state.touching,&mut state.body,convex_mesh_id); }, _=>panic!("invalid pair"), } diff --git a/src/window.rs b/src/window.rs index c59e1ca..b0563b2 100644 --- a/src/window.rs +++ b/src/window.rs @@ -27,6 +27,7 @@ impl WindowContext<'_>{ fn window_event(&mut self,time:integer::Time,event: winit::event::WindowEvent) { match event { winit::event::WindowEvent::DroppedFile(path)=>{ + let path=path.as_path(); //blocking because it's simpler... if let Ok(file)=std::fs::File::open(path){ // match strafesnet_snf::read_snf(std::io::BufReader::new(file)){