compiles!!!

This commit is contained in:
Quaternions 2024-02-08 20:16:59 -08:00
parent fcc52a1215
commit 1540710942
5 changed files with 95 additions and 93 deletions

View File

@ -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<wgpu::TextureView>=map.textures.into_iter().enumerate().map(|(texture_id,texture_data)|{
let texture_views:Vec<wgpu::TextureView>=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::<glam::Vec3>::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::<glam::Vec3>::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::<glam::Vec3>::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::<glam::Vec3>::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::<ModelI
const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*4;
fn get_instances_buffer_data(instances:&[GraphicsModelOwned])->Vec<f32>{
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

View File

@ -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<GraphicsModelOwned>,
}
#[derive(Clone,PartialEq,id::Id)]
#[derive(Clone,Copy,PartialEq,id::Id)]
pub struct GraphicsModelColor4(glam::Vec4);
impl std::hash::Hash for GraphicsModelColor4{
fn hash<H:std::hash::Hasher>(&self,state:&mut H) {

View File

@ -92,7 +92,7 @@ struct VertRefs{
faces:Vec<SubmeshFaceId>,
edges:Vec<SubmeshDirectedEdgeId>,
}
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<Face>,//MeshFaceId indexes this list
verts:Vec<Vert>,//MeshVertId indexes this list
}
struct PhysicsMeshTopology{
pub struct PhysicsMeshTopology{
//mapping of local ids to PhysicsMeshData ids
faces:Vec<MeshFaceId>,//SubmeshFaceId indexes this list
verts:Vec<MeshVertId>,//SubmeshVertId indexes this list
@ -126,11 +126,10 @@ impl From<MeshId> 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<PhysicsMeshTopology>,
}
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<PhysicsMeshTopology>=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::<MeshVertId,SubmeshVertId>::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_dot<d{
best_dot=d;

View File

@ -170,7 +170,7 @@ impl PhysicsModels{
//TODO: "statically" verify the maps don't refer to any nonexistant data, if they do delete the references.
//then I can make these getter functions unchecked.
fn mesh(&self,convex_mesh_id:ConvexMeshId)->TransformedMesh{
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<u32>{
pub fn get_jump_count(&self,model_id:ModelId)->Option<u32>{
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<gameplay_attributes::Wormhole>,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<MoveState>{
fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,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<MoveState>{
//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<gameplay_attributes::Wormhole>,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<gameplay_attributes::Wormhole>,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<gameplay_attributes::Wormhole>,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"),
}

View File

@ -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)){