diff --git a/src/graphics.rs b/src/graphics.rs index 0a0be3a..3ad4135 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,4 +1,6 @@ use std::borrow::Cow; +use strafesnet_common::map; +use strafesnet_common::model; use strafesnet_common::integer; use wgpu::{util::DeviceExt,AstcBlock,AstcChannel}; use crate::model_graphics::{GraphicsVertex,GraphicsModelColor4,GraphicsModelInstance,GraphicsModelSingleTexture,IndexedGraphicsModelSingleTexture,IndexedGroupFixedTexture}; @@ -145,14 +147,14 @@ impl GraphicsState{ pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){ self.camera.fov=user_settings.calculate_fov(1.0,&self.camera.screen_size).as_vec2(); } - pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,indexed_models:crate::model::IndexedModelInstances){ + pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:map::Map){ //generate texture view per texture //idk how to do this gooder lol let mut double_map=std::collections::HashMap::::new(); let mut texture_loading_threads=Vec::new(); - let num_textures=indexed_models.textures.len(); - for (i,texture_id) in indexed_models.textures.into_iter().enumerate(){ + let num_textures=map.textures.len(); + for (i,texture_id) in map.textures.into_iter().enumerate(){ let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_id)); if let Ok(mut file) = std::fs::File::open(path.clone()){ double_map.insert(i as u32, texture_loading_threads.len() as u32); @@ -216,9 +218,9 @@ impl GraphicsState{ //split groups with different textures into separate models //the models received here are supposed to be tightly packed, i.e. no code needs to check if two models are using the same groups. - let indexed_models_len=indexed_models.models.len(); + let indexed_models_len=map.models.len(); let mut unique_texture_models=Vec::with_capacity(indexed_models_len); - for model in indexed_models.models.into_iter(){ + for model in map.models.into_iter(){ //convert ModelInstance into GraphicsModelInstance let instances:Vec=model.instances.into_iter().filter_map(|instance|{ if instance.color.w==0.0{ @@ -379,7 +381,7 @@ impl GraphicsState{ //map the indexed vertices onto new indices //creating the vertex map is slightly different because the vertices are directly hashable let map_vertex_id:Vec=model.unique_vertices.iter().map(|unmapped_vertex|{ - let vertex=crate::model::IndexedVertex{ + let vertex=model::IndexedVertex{ pos:map_pos_id[unmapped_vertex.pos as usize], tex:map_tex_id[unmapped_vertex.tex as usize], normal:map_normal_id[unmapped_vertex.normal as usize], @@ -396,7 +398,7 @@ impl GraphicsState{ }).collect(); for group in &model.groups{ for poly in &group.polys{ - polys.push(crate::model::IndexedPolygon{vertices:poly.vertices.iter().map(|&vertex_id|map_vertex_id[vertex_id as usize]).collect()}); + polys.push(model::IndexedPolygon{vertices:poly.vertices.iter().map(|&vertex_id|map_vertex_id[vertex_id as usize]).collect()}); } } } diff --git a/src/graphics_worker.rs b/src/graphics_worker.rs index 378269c..ca284a7 100644 --- a/src/graphics_worker.rs +++ b/src/graphics_worker.rs @@ -4,7 +4,7 @@ pub enum Instruction{ Render(crate::physics::PhysicsOutputState,integer::Time,glam::IVec2), //UpdateModel(crate::graphics::GraphicsModelUpdate), Resize(winit::dpi::PhysicalSize,crate::settings::UserSettings), - GenerateModels(crate::model::IndexedModelInstances), + GenerateModels(strafesnet_common::map::Map), ClearModels, } diff --git a/src/model_graphics.rs b/src/model_graphics.rs index 8e871e7..cdc4935 100644 --- a/src/model_graphics.rs +++ b/src/model_graphics.rs @@ -1,24 +1,24 @@ use bytemuck::{Pod, Zeroable}; -use crate::model::{IndexedVertex,IndexedPolygon}; -#[derive(Clone, Copy, Pod, Zeroable)] +use strafesnet_common::model::{IndexedVertex,IndexedPolygon}; +#[derive(Clone,Copy,Pod,Zeroable)] #[repr(C)] -pub struct GraphicsVertex { - pub pos: [f32; 3], - pub tex: [f32; 2], - pub normal: [f32; 3], - pub color: [f32; 4], +pub struct GraphicsVertex{ + pub pos:[f32;3], + pub tex:[f32;2], + pub normal:[f32;3], + pub color:[f32;4], } pub struct IndexedGroupFixedTexture{ pub polys:Vec, } pub struct IndexedGraphicsModelSingleTexture{ - pub unique_pos:Vec<[f32; 3]>, - pub unique_tex:Vec<[f32; 2]>, - pub unique_normal:Vec<[f32; 3]>, - pub unique_color:Vec<[f32; 4]>, + pub unique_pos:Vec<[f32;3]>, + pub unique_tex:Vec<[f32;2]>, + pub unique_normal:Vec<[f32;3]>, + pub unique_color:Vec<[f32;4]>, pub unique_vertices:Vec, pub texture:Option,//RenderPattern? material/texture/shader/flat color - pub groups: Vec, + pub groups:Vec, pub instances:Vec, } pub enum Entities{ diff --git a/src/model_physics.rs b/src/model_physics.rs index 7e31ac0..081ab70 100644 --- a/src/model_physics.rs +++ b/src/model_physics.rs @@ -1,4 +1,5 @@ use std::borrow::{Borrow,Cow}; +use strafesnet_common::model; use strafesnet_common::zeroes; use strafesnet_common::integer::{self,Planar64,Planar64Vec3}; @@ -134,8 +135,8 @@ impl EdgePool{ (&mut unsafe{self.edge_guys.get_unchecked_mut(edge_id)}.1,EdgeId(edge_id)) } } -impl From<&crate::model::IndexedModel> for PhysicsMesh{ - fn from(indexed_model:&crate::model::IndexedModel)->Self{ +impl From<&model::IndexedModel> for PhysicsMesh{ + fn from(indexed_model:&model::IndexedModel)->Self{ assert!(indexed_model.unique_pos.len()!=0,"Mesh cannot have 0 vertices"); let verts=indexed_model.unique_pos.iter().map(|v|Vert(v.clone())).collect(); let mut vert_ref_guys=vec![VertRefGuy::default();indexed_model.unique_pos.len()]; diff --git a/src/physics.rs b/src/physics.rs index 73a6b83..f2e50ef 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -8,7 +8,7 @@ use strafesnet_common::gameplay_attributes; use strafesnet_common::gameplay_modes; use strafesnet_common::map; use strafesnet_common::model; -use strafesnet_common::gameplay_style::{self,StyleModifiers,StrafeSettings}; +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}; use strafesnet_common::model::ModelId; @@ -346,10 +346,10 @@ impl StyleHelper for StyleModifiers{ //fn get_jump_energy(&self)->Planar64 fn get_jump_deltav(&self)->Planar64{ match &self.jump_impulse{ - &JumpImpulse::FromTime(time)=>self.gravity.length()*(time/2), - &JumpImpulse::FromHeight(height)=>(self.gravity.length()*height*2).sqrt(), - &JumpImpulse::FromDeltaV(deltav)=>deltav, - &JumpImpulse::FromEnergy(energy)=>(energy*2/self.mass).sqrt(), + &gameplay_style::JumpImpulse::FromTime(time)=>self.gravity.length()*(time/2), + &gameplay_style::JumpImpulse::FromHeight(height)=>(self.gravity.length()*height*2).sqrt(), + &gameplay_style::JumpImpulse::FromDeltaV(deltav)=>deltav, + &gameplay_style::JumpImpulse::FromEnergy(energy)=>(energy*2/self.mass).sqrt(), } } @@ -423,23 +423,6 @@ enum MoveState{ Ladder(WalkState), } -pub struct PhysicsState{ - time:Time, - body:Body, - world:WorldState,//currently there is only one state the world can be in - mode_state:ModeState, - style:StyleModifiers,//mode style with custom style updates applied - touching:TouchingState, - //camera must exist in state because wormholes modify the camera, also camera punch - camera:PhysicsCamera, - pub next_mouse:MouseState,//Where is the mouse headed next - controls:u32,//TODO this should be a struct - move_state:MoveState, - //does not belong here - //bvh:bvh::BvhNode, - //models:PhysicsModels, - //modes:gameplay_modes::Modes, -} #[derive(Clone,Default)] pub struct PhysicsOutputState{ body:Body, @@ -483,15 +466,18 @@ enum PhysicsAttributesId{ Intersect(IntersectAttributesId) } +//id assigned to deindexed IndexedPhysicsGroup +struct PhysicsModelId(u32); +struct PhysicsGroupId(u32); //unique physics meshes indexed by this -struct MeshId{ - model_id:ModelId, - group_id:GroupId, +struct ConvexMeshId{ + model_id:PhysicsModelId,// = IndexedModelId + group_id:PhysicsGroupId,// group in model } pub struct PhysicsModel{ //A model is a thing that has a hitbox. can be represented by a list of TreyMesh-es //in this iteration, all it needs is extents. - mesh_id:MeshId, + mesh_id:ConvexMeshId, //put these up on the Model (data normalization) general_attributes:GeneralAttributesId, collision_attributes:PhysicsAttributesId, @@ -501,7 +487,7 @@ pub struct PhysicsModel{ } impl PhysicsModel{ - pub fn new(mesh_id:MeshId,attr_id:PhysicsAttributesId,transform:integer::Planar64Affine3)->Self{ + pub fn new(mesh_id:ConvexMeshId,attr_id:PhysicsAttributesId,transform:integer::Planar64Affine3)->Self{ Self{ mesh_id, attr_id, @@ -626,7 +612,7 @@ impl TouchingState{ PhysicsCollisionAttributes::Contact{contacting,general}=>{ let normal=contact_normal(models,&style_mesh,contact); match &contacting.contact_behaviour{ - Some(model::ContactingBehaviour::Ladder(_))=>{ + Some(gameplay_attributes::ContactingBehaviour::Ladder(_))=>{ //ladder walkstate let mut target_velocity=style.get_ladder_target_velocity(camera,controls,next_mouse,time,&normal); self.constrain_velocity(models,&style_mesh,&mut target_velocity); @@ -779,23 +765,39 @@ impl VirtualBody<'_>{ } } +pub struct PhysicsState{ + time:Time, + body:Body, + world:WorldState,//currently there is only one state the world can be in + mode_state:ModeState, + style:StyleModifiers,//mode style with custom style updates applied + touching:TouchingState, + //camera must exist in state because wormholes modify the camera, also camera punch + camera:PhysicsCamera, + pub next_mouse:MouseState,//Where is the mouse headed next + controls:u32,//TODO this should be a struct + move_state:MoveState, + //does not belong here + //bvh:bvh::BvhNode, + //models:PhysicsModels, + //modes:gameplay_modes::Modes, +} impl Default for PhysicsState{ fn default()->Self{ Self{ - spawn_point:Planar64Vec3::int(0,50,0), body:Body::new(Planar64Vec3::int(0,50,0),Planar64Vec3::int(0,0,0),Planar64Vec3::int(0,-100,0),Time::ZERO), time:Time::ZERO, style:StyleModifiers::default(), touching:TouchingState::default(), - models:PhysicsModels::default(), - bvh:bvh::BvhNode::default(), move_state: MoveState::Air, camera:PhysicsCamera::default(), next_mouse:MouseState::default(), controls:0, world:WorldState{}, mode_state:ModeState::default(), - modes:Modes::default(), + //modes:Modes::default(), + //bvh:bvh::BvhNode::default(), + //models:PhysicsModels::default(), } } } @@ -1072,7 +1074,7 @@ fn teleport(body:&mut Body,touching:&mut TouchingState,models:&PhysicsModels,sty set_acceleration(body,touching,models,&style.mesh(),style.gravity); MoveState::Air } -fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModifiers,mode:&gameplay_modes::Mode,models:&PhysicsModels,stage_id:StageId)->Option{ +fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModifiers,mode:&gameplay_modes::Mode,models:&PhysicsModels,stage_id:gameplay_modes::StageId)->Option{ let model=models.model(mode.get_spawn_model_id(stage_id)?); let point=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(style.hitbox.halfsize.y()+Planar64::ONE/16); Some(teleport(body,touching,models,style,point)) @@ -1082,20 +1084,21 @@ fn run_teleport_behaviour(wormhole:&Option,game:& //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 - mode.get_element(model_id).map(|stage_element|{ + let stage_element=mode.get_element(model_id)?; + { if stage_element.force||game.stage_idNone, - model::StageElementBehaviour::Trigger - |model::StageElementBehaviour::Teleport=>{ + gameplay_modes::StageElementBehaviour::SpawnAt=>None, + gameplay_modes::StageElementBehaviour::Trigger + |gameplay_modes::StageElementBehaviour::Teleport=>{ //I guess this is correct behaviour when trying to teleport to a non-existent spawn but it's still weird - teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id) + teleport_to_spawn(body,touching,style,mode,models,game.stage_id) }, - model::StageElementBehaviour::Platform=>None, - &model::StageElementBehaviour::Checkpoint=>{ + gameplay_modes::StageElementBehaviour::Platform=>None, + &gameplay_modes::StageElementBehaviour::Checkpoint=>{ // let mode=modes.get_mode(stage_element.mode_id)?; // if mode.ordered_checkpoint_id.map_or(true,|id|id,game:& // teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id) // } }, - &model::StageElementBehaviour::Ordered{checkpoint_id}=>{ + &gameplay_modes::StageElementBehaviour::Ordered{checkpoint_id}=>{ if checkpoint_id,game:& None }else{ //If you hit an ordered checkpoint after missing a previous one - teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id) + teleport_to_spawn(body,touching,style,mode,models,game.stage_id) } }, - model::StageElementBehaviour::Unordered=>{ + gameplay_modes::StageElementBehaviour::Unordered=>{ //count model id in accumulated unordered checkpoints game.unordered_checkpoints.insert(model_id); None }, - &model::StageElementBehaviour::JumpLimit(jump_limit)=>{ + &gameplay_modes::StageElementBehaviour::JumpLimit(jump_limit)=>{ //let count=game.jump_counts.get(&model.id); //TODO None }, } - }).or_else(|| - match wormhole{ - Some(gameplay_attributes::Wormhole{destination_model})=>{ - let origin_model=models.model(model_id); - let destination_model=models.get_wormhole_model(destination_model)?; - //ignore the transform for now - Some(teleport(body,touching,models,style,body.position-origin_model.transform.translation+destination_model.transform.translation)) + }.or_else(|| + match wormhole{ + Some(gameplay_attributes::Wormhole{destination_model})=>{ + let origin_model=models.model(model_id); + let destination_model=models.get_wormhole_model(destination_model)?; + //ignore the transform for now + Some(teleport(body,touching,models,style,body.position-origin_model.transform.translation+destination_model.transform.translation)) + } + None=>None, } - None=>None, - }) + ) } impl instruction::InstructionConsumer for PhysicsState { diff --git a/src/physics_worker.rs b/src/physics_worker.rs index 8a483f9..b58fd2a 100644 --- a/src/physics_worker.rs +++ b/src/physics_worker.rs @@ -18,7 +18,7 @@ pub enum Instruction{ Input(InputInstruction), Render, Resize(winit::dpi::PhysicalSize,crate::settings::UserSettings), - GenerateModels(crate::model::IndexedModelInstances), + GenerateModels(strafesnet_common::map::Map), ClearModels, //Graphics(crate::graphics_worker::Instruction), }