From 8687c65e8049d16fcffcee77e33a4d34bde6d88a Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Sun, 4 Feb 2024 20:59:33 -0800
Subject: [PATCH] wip

---
 src/graphics.rs        |  16 +++---
 src/graphics_worker.rs |   2 +-
 src/model_graphics.rs  |  24 ++++-----
 src/model_physics.rs   |   5 +-
 src/physics.rs         | 110 +++++++++++++++++++++--------------------
 src/physics_worker.rs  |   2 +-
 6 files changed, 83 insertions(+), 76 deletions(-)

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::<u32,u32>::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<GraphicsModelInstance>=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<u32>=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<u32>,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<IndexedPolygon>,
 }
 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<IndexedVertex>,
 	pub texture:Option<u32>,//RenderPattern? material/texture/shader/flat color
-	pub groups: Vec<IndexedGroupFixedTexture>,
+	pub groups:Vec<IndexedGroupFixedTexture>,
 	pub instances:Vec<GraphicsModelInstance>,
 }
 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<MoveState>{
+fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModifiers,mode:&gameplay_modes::Mode,models:&PhysicsModels,stage_id:gameplay_modes::StageId)->Option<MoveState>{
 	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<gameplay_attributes::Wormhole>,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_id<stage_element.stage_id{
 			//TODO: check if all checkpoints are complete up to destination stage id, otherwise set to checkpoint completion stage it
 			game.stage_id=stage_element.stage_id;
 		}
 		match &stage_element.behaviour{
-			model::StageElementBehaviour::SpawnAt=>None,
-			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.next_ordered_checkpoint_id)
 				// 	&&mode.unordered_checkpoint_count<=game.unordered_checkpoints.len() as u32{
@@ -1106,7 +1109,7 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,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.next_ordered_checkpoint_id{
 					//if you hit a checkpoint you already hit, nothing happens
 					None
@@ -1117,30 +1120,31 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,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<PhysicsInstruction> 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<u32>,crate::settings::UserSettings),
-	GenerateModels(crate::model::IndexedModelInstances),
+	GenerateModels(strafesnet_common::map::Map),
 	ClearModels,
 	//Graphics(crate::graphics_worker::Instruction),
 }