forked from StrafesNET/strafe-client
wip
This commit is contained in:
parent
8687c65e80
commit
56bf453337
@ -1,7 +1,7 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use strafesnet_common::map;
|
use strafesnet_common::map;
|
||||||
use strafesnet_common::model;
|
|
||||||
use strafesnet_common::integer;
|
use strafesnet_common::integer;
|
||||||
|
use strafesnet_common::model::{self,ColorId,NormalId,PositionId,TextureCoordinateId,VertexId};
|
||||||
use wgpu::{util::DeviceExt,AstcBlock,AstcChannel};
|
use wgpu::{util::DeviceExt,AstcBlock,AstcChannel};
|
||||||
use crate::model_graphics::{GraphicsVertex,GraphicsModelColor4,GraphicsModelInstance,GraphicsModelSingleTexture,IndexedGraphicsModelSingleTexture,IndexedGroupFixedTexture};
|
use crate::model_graphics::{GraphicsVertex,GraphicsModelColor4,GraphicsModelInstance,GraphicsModelSingleTexture,IndexedGraphicsModelSingleTexture,IndexedGroupFixedTexture};
|
||||||
|
|
||||||
@ -332,73 +332,73 @@ impl GraphicsState{
|
|||||||
let model=&unique_texture_models[model_id];
|
let model=&unique_texture_models[model_id];
|
||||||
let instance=&model.instances[instance_id];
|
let instance=&model.instances[instance_id];
|
||||||
//just hash word slices LOL
|
//just hash word slices LOL
|
||||||
let map_pos_id:Vec<u32>=model.unique_pos.iter().map(|untransformed_pos|{
|
let map_pos_id:Vec<PositionId>=model.unique_pos.iter().map(|untransformed_pos|{
|
||||||
let pos=instance.transform.transform_point3(glam::Vec3::from_array(untransformed_pos.clone())).to_array();
|
let pos=instance.transform.transform_point3(glam::Vec3::from_array(untransformed_pos.clone())).to_array();
|
||||||
let h=pos.map(|v|bytemuck::cast::<f32,u32>(v));
|
let h=bytemuck::cast::<[f32;3],[u32;3]>(pos);
|
||||||
(if let Some(&pos_id)=pos_id_from.get(&h){
|
PositionId::id((if let Some(&pos_id)=pos_id_from.get(&h){
|
||||||
pos_id
|
pos_id
|
||||||
}else{
|
}else{
|
||||||
let pos_id=unique_pos.len();
|
let pos_id=unique_pos.len();
|
||||||
unique_pos.push(pos.clone());
|
unique_pos.push(pos);
|
||||||
pos_id_from.insert(h,pos_id);
|
pos_id_from.insert(h,pos_id);
|
||||||
pos_id
|
pos_id
|
||||||
}) as u32
|
}) as u32)
|
||||||
}).collect();
|
}).collect();
|
||||||
let map_tex_id:Vec<u32>=model.unique_tex.iter().map(|tex|{
|
let map_tex_id:Vec<TextureCoordinateId>=model.unique_tex.iter().map(|&tex|{
|
||||||
let h=tex.map(|v|bytemuck::cast::<f32,u32>(v));
|
let h=bytemuck::cast::<[f32;2],[u32;2]>(tex);
|
||||||
(if let Some(&tex_id)=tex_id_from.get(&h){
|
TextureCoordinateId::id((if let Some(&tex_id)=tex_id_from.get(&h){
|
||||||
tex_id
|
tex_id
|
||||||
}else{
|
}else{
|
||||||
let tex_id=unique_tex.len();
|
let tex_id=unique_tex.len();
|
||||||
unique_tex.push(tex.clone());
|
unique_tex.push(tex);
|
||||||
tex_id_from.insert(h,tex_id);
|
tex_id_from.insert(h,tex_id);
|
||||||
tex_id
|
tex_id
|
||||||
}) as u32
|
}) as u32)
|
||||||
}).collect();
|
}).collect();
|
||||||
let map_normal_id:Vec<u32>=model.unique_normal.iter().map(|untransformed_normal|{
|
let map_normal_id:Vec<NormalId>=model.unique_normal.iter().map(|untransformed_normal|{
|
||||||
let normal=(instance.normal_transform*glam::Vec3::from_array(untransformed_normal.clone())).to_array();
|
let normal=(instance.normal_transform*glam::Vec3::from_array(untransformed_normal.clone())).to_array();
|
||||||
let h=normal.map(|v|bytemuck::cast::<f32,u32>(v));
|
let h=bytemuck::cast::<[f32;3],[u32;3]>(normal);
|
||||||
(if let Some(&normal_id)=normal_id_from.get(&h){
|
NormalId::id((if let Some(&normal_id)=normal_id_from.get(&h){
|
||||||
normal_id
|
normal_id
|
||||||
}else{
|
}else{
|
||||||
let normal_id=unique_normal.len();
|
let normal_id=unique_normal.len();
|
||||||
unique_normal.push(normal.clone());
|
unique_normal.push(normal);
|
||||||
normal_id_from.insert(h,normal_id);
|
normal_id_from.insert(h,normal_id);
|
||||||
normal_id
|
normal_id
|
||||||
}) as u32
|
}) as u32)
|
||||||
}).collect();
|
}).collect();
|
||||||
let map_color_id:Vec<u32>=model.unique_color.iter().map(|color|{
|
let map_color_id:Vec<ColorId>=model.unique_color.iter().map(|&color|{
|
||||||
let h=color.map(|v|bytemuck::cast::<f32,u32>(v));
|
let h=bytemuck::cast::<[f32;4],[u32;4]>(color);
|
||||||
(if let Some(&color_id)=color_id_from.get(&h){
|
ColorId::id((if let Some(&color_id)=color_id_from.get(&h){
|
||||||
color_id
|
color_id
|
||||||
}else{
|
}else{
|
||||||
let color_id=unique_color.len();
|
let color_id=unique_color.len();
|
||||||
unique_color.push(color.clone());
|
unique_color.push(color);
|
||||||
color_id_from.insert(h,color_id);
|
color_id_from.insert(h,color_id);
|
||||||
color_id
|
color_id
|
||||||
}) as u32
|
}) as u32)
|
||||||
}).collect();
|
}).collect();
|
||||||
//map the indexed vertices onto new indices
|
//map the indexed vertices onto new indices
|
||||||
//creating the vertex map is slightly different because the vertices are directly hashable
|
//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 map_vertex_id:Vec<VertexId>=model.unique_vertices.iter().map(|unmapped_vertex|{
|
||||||
let vertex=model::IndexedVertex{
|
let vertex=model::IndexedVertex{
|
||||||
pos:map_pos_id[unmapped_vertex.pos as usize],
|
pos:map_pos_id[unmapped_vertex.pos.get() as usize],
|
||||||
tex:map_tex_id[unmapped_vertex.tex as usize],
|
tex:map_tex_id[unmapped_vertex.tex.get() as usize],
|
||||||
normal:map_normal_id[unmapped_vertex.normal as usize],
|
normal:map_normal_id[unmapped_vertex.normal.get() as usize],
|
||||||
color:map_color_id[unmapped_vertex.color as usize],
|
color:map_color_id[unmapped_vertex.color.get() as usize],
|
||||||
};
|
};
|
||||||
(if let Some(&vertex_id)=vertex_id_from.get(&vertex){
|
VertexId::id((if let Some(&vertex_id)=vertex_id_from.get(&vertex){
|
||||||
vertex_id
|
vertex_id
|
||||||
}else{
|
}else{
|
||||||
let vertex_id=unique_vertices.len();
|
let vertex_id=unique_vertices.len();
|
||||||
unique_vertices.push(vertex.clone());
|
unique_vertices.push(vertex.clone());
|
||||||
vertex_id_from.insert(vertex,vertex_id);
|
vertex_id_from.insert(vertex,vertex_id);
|
||||||
vertex_id
|
vertex_id
|
||||||
}) as u32
|
}) as u32)
|
||||||
}).collect();
|
}).collect();
|
||||||
for group in &model.groups{
|
for group in &model.groups{
|
||||||
for poly in &group.polys{
|
for poly in &group.polys{
|
||||||
polys.push(model::IndexedPolygon{vertices:poly.vertices.iter().map(|&vertex_id|map_vertex_id[vertex_id as usize]).collect()});
|
polys.push(model::PolygonGroup::PolygonList(poly.vertices.iter().map(|&vertex_id|map_vertex_id[vertex_id.get() as usize]).collect()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,12 +445,12 @@ impl GraphicsState{
|
|||||||
indices.push(i);
|
indices.push(i);
|
||||||
}else{
|
}else{
|
||||||
let i=vertices.len();
|
let i=vertices.len();
|
||||||
let vertex=&model.unique_vertices[vertex_index as usize];
|
let vertex=&model.unique_vertices[vertex_index.get() as usize];
|
||||||
vertices.push(GraphicsVertex{
|
vertices.push(GraphicsVertex{
|
||||||
pos: model.unique_pos[vertex.pos as usize],
|
pos: model.unique_pos[vertex.pos.get() as usize],
|
||||||
tex: model.unique_tex[vertex.tex as usize],
|
tex: model.unique_tex[vertex.tex.get() as usize],
|
||||||
normal: model.unique_normal[vertex.normal as usize],
|
normal: model.unique_normal[vertex.normal.get() as usize],
|
||||||
color:model.unique_color[vertex.color as usize],
|
color:model.unique_color[vertex.color.get() as usize],
|
||||||
});
|
});
|
||||||
index_from_vertex.insert(vertex_index,i);
|
index_from_vertex.insert(vertex_index,i);
|
||||||
indices.push(i);
|
indices.push(i);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use strafesnet_common::model::{IndexedVertex,IndexedPolygon};
|
use strafesnet_common::model::{IndexedVertex,IndexedVertexList};
|
||||||
#[derive(Clone,Copy,Pod,Zeroable)]
|
#[derive(Clone,Copy,Pod,Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GraphicsVertex{
|
pub struct GraphicsVertex{
|
||||||
@ -9,7 +9,7 @@ pub struct GraphicsVertex{
|
|||||||
pub color:[f32;4],
|
pub color:[f32;4],
|
||||||
}
|
}
|
||||||
pub struct IndexedGroupFixedTexture{
|
pub struct IndexedGroupFixedTexture{
|
||||||
pub polys:Vec<IndexedPolygon>,
|
pub polys:Vec<IndexedVertexList>,
|
||||||
}
|
}
|
||||||
pub struct IndexedGraphicsModelSingleTexture{
|
pub struct IndexedGraphicsModelSingleTexture{
|
||||||
pub unique_pos:Vec<[f32;3]>,
|
pub unique_pos:Vec<[f32;3]>,
|
||||||
|
@ -144,14 +144,14 @@ impl From<&model::IndexedModel> for PhysicsMesh{
|
|||||||
let mut face_i=0;
|
let mut face_i=0;
|
||||||
let mut faces=Vec::new();
|
let mut faces=Vec::new();
|
||||||
let mut face_ref_guys=Vec::new();
|
let mut face_ref_guys=Vec::new();
|
||||||
for group in indexed_model.groups.iter(){for poly in group.polys.iter(){
|
for group in indexed_model.polygon_groups.iter(){for poly in group.polys(){
|
||||||
let face_id=FaceId(face_i);
|
let face_id=FaceId(face_i);
|
||||||
//one face per poly
|
//one face per poly
|
||||||
let mut normal=Planar64Vec3::ZERO;
|
let mut normal=Planar64Vec3::ZERO;
|
||||||
let len=poly.vertices.len();
|
let len=poly.vertices.len();
|
||||||
let face_edges=poly.vertices.iter().enumerate().map(|(i,&vert_id)|{
|
let face_edges=poly.vertices.iter().enumerate().map(|(i,&vert_id)|{
|
||||||
let vert0_id=indexed_model.unique_vertices[vert_id as usize].pos as usize;
|
let vert0_id=indexed_model.unique_vertices[vert_id as usize].pos.get() as usize;
|
||||||
let vert1_id=indexed_model.unique_vertices[poly.vertices[(i+1)%len] as usize].pos as usize;
|
let vert1_id=indexed_model.unique_vertices[poly.vertices[(i+1)%len] as usize].pos.get() as usize;
|
||||||
//https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal (Newell's Method)
|
//https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal (Newell's Method)
|
||||||
let v0=indexed_model.unique_pos[vert0_id];
|
let v0=indexed_model.unique_pos[vert0_id];
|
||||||
let v1=indexed_model.unique_pos[vert1_id];
|
let v1=indexed_model.unique_pos[vert1_id];
|
||||||
@ -180,7 +180,7 @@ impl From<&model::IndexedModel> for PhysicsMesh{
|
|||||||
normal=normal/len as i64;
|
normal=normal/len as i64;
|
||||||
let mut dot=Planar64::ZERO;
|
let mut dot=Planar64::ZERO;
|
||||||
for &v in poly.vertices.iter(){
|
for &v in poly.vertices.iter(){
|
||||||
dot+=normal.dot(indexed_model.unique_pos[indexed_model.unique_vertices[v as usize].pos as usize]);
|
dot+=normal.dot(indexed_model.unique_pos[indexed_model.unique_vertices[v as usize].pos.get() as usize]);
|
||||||
}
|
}
|
||||||
faces.push(Face{normal,dot:dot/len as i64});
|
faces.push(Face{normal,dot:dot/len as i64});
|
||||||
face_ref_guys.push(FaceRefEdges(face_edges));
|
face_ref_guys.push(FaceRefEdges(face_edges));
|
||||||
@ -740,7 +740,6 @@ fn test_is_empty_volume(){
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_me_a_cube(){
|
fn build_me_a_cube(){
|
||||||
let unit_cube=crate::primitives::unit_cube();
|
let mesh=PhysicsMesh::unit_cube();
|
||||||
let mesh=PhysicsMesh::from(&unit_cube);
|
|
||||||
//println!("mesh={:?}",mesh);
|
//println!("mesh={:?}",mesh);
|
||||||
}
|
}
|
119
src/physics.rs
119
src/physics.rs
@ -171,11 +171,13 @@ impl PhysicsModels{
|
|||||||
//TODO: "statically" verify the maps don't refer to any nonexistant data, if they do delete the references.
|
//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.
|
//then I can make these getter functions unchecked.
|
||||||
fn mesh(&self,model_id:ModelId)->TransformedMesh{
|
fn mesh(&self,model_id:ModelId)->TransformedMesh{
|
||||||
|
let idx=model_id.get() as usize;
|
||||||
|
let mesh_id=self.models[idx].mesh_id;
|
||||||
TransformedMesh::new(
|
TransformedMesh::new(
|
||||||
&self.meshes[self.models[model_id].mesh_id],
|
&self.meshes[mesh_id.model_id.get() as usize].groups[mesh_id.group_id.get() as usize],
|
||||||
&self.models[model_id].transform,
|
&self.models[idx].transform,
|
||||||
&self.models[model_id].normal_transform,
|
&self.models[idx].normal_transform,
|
||||||
self.models[model_id].transform_det,
|
self.models[idx].transform_det,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn model(&self,model_id:ModelId)->&PhysicsModel{
|
fn model(&self,model_id:ModelId)->&PhysicsModel{
|
||||||
@ -192,7 +194,7 @@ impl PhysicsModels{
|
|||||||
self.models.push(model);
|
self.models.push(model);
|
||||||
model_id
|
model_id
|
||||||
}
|
}
|
||||||
fn push_attr(&mut self,attr:PhysicsCollisionAttributes)->PhysicsAttributeId{
|
fn push_attr(&mut self,attr:PhysicsCollisionAttributes)->PhysicsAttributesId{
|
||||||
let attr_id=self.attributes.len();
|
let attr_id=self.attributes.len();
|
||||||
self.attributes.push(attr);
|
self.attributes.push(attr);
|
||||||
attr_id
|
attr_id
|
||||||
@ -271,8 +273,8 @@ impl std::default::Default for ModeState{
|
|||||||
Self{
|
Self{
|
||||||
stage_id:gameplay_modes::StageId::id(0),
|
stage_id:gameplay_modes::StageId::id(0),
|
||||||
next_ordered_checkpoint_id:gameplay_modes::CheckpointId::id(0),
|
next_ordered_checkpoint_id:gameplay_modes::CheckpointId::id(0),
|
||||||
unordered_checkpoints:std::collections::HashSet::new(),
|
unordered_checkpoints:HashSet::new(),
|
||||||
jump_counts:std::collections::HashMap::new(),
|
jump_counts:HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,8 +530,8 @@ impl Collision{
|
|||||||
}
|
}
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct TouchingState{
|
struct TouchingState{
|
||||||
contacts:std::collections::HashSet::<ContactCollision>,
|
contacts:HashSet::<ContactCollision>,
|
||||||
intersects:std::collections::HashSet::<IntersectCollision>,
|
intersects:HashSet::<IntersectCollision>,
|
||||||
}
|
}
|
||||||
impl TouchingState{
|
impl TouchingState{
|
||||||
fn clear(&mut self){
|
fn clear(&mut self){
|
||||||
@ -778,9 +780,9 @@ pub struct PhysicsState{
|
|||||||
controls:u32,//TODO this should be a struct
|
controls:u32,//TODO this should be a struct
|
||||||
move_state:MoveState,
|
move_state:MoveState,
|
||||||
//does not belong here
|
//does not belong here
|
||||||
//bvh:bvh::BvhNode,
|
bvh:bvh::BvhNode,
|
||||||
//models:PhysicsModels,
|
models:PhysicsModels,
|
||||||
//modes:gameplay_modes::Modes,
|
modes:gameplay_modes::Modes,
|
||||||
}
|
}
|
||||||
impl Default for PhysicsState{
|
impl Default for PhysicsState{
|
||||||
fn default()->Self{
|
fn default()->Self{
|
||||||
@ -795,19 +797,16 @@ impl Default for PhysicsState{
|
|||||||
controls:0,
|
controls:0,
|
||||||
world:WorldState{},
|
world:WorldState{},
|
||||||
mode_state:ModeState::default(),
|
mode_state:ModeState::default(),
|
||||||
//modes:Modes::default(),
|
modes:Modes::default(),
|
||||||
//bvh:bvh::BvhNode::default(),
|
bvh:bvh::BvhNode::default(),
|
||||||
//models:PhysicsModels::default(),
|
models:PhysicsModels::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PhysicsState {
|
impl PhysicsState {
|
||||||
pub fn clear(&mut self){
|
pub fn clear(&mut self){
|
||||||
self.models.clear();
|
|
||||||
self.modes.clear();
|
|
||||||
self.touching.clear();
|
self.touching.clear();
|
||||||
self.bvh=bvh::BvhNode::default();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output(&self)->PhysicsOutputState{
|
pub fn output(&self)->PhysicsOutputState{
|
||||||
@ -818,20 +817,19 @@ impl PhysicsState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(&mut self,spawn_point:Planar64Vec3){
|
pub fn spawn(&mut self){
|
||||||
self.mode_state.stage_id=0;
|
self.mode_state.stage_id=gameplay_modes::StageId::id(0);
|
||||||
self.spawn_point=spawn_point;
|
|
||||||
self.process_instruction(instruction::TimedInstruction{
|
self.process_instruction(instruction::TimedInstruction{
|
||||||
time:self.time,
|
time:self.time,
|
||||||
instruction: PhysicsInstruction::Input(PhysicsInputInstruction::Reset),
|
instruction: PhysicsInstruction::Input(PhysicsInputInstruction::Reset),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_models(&mut self,indexed_models:&map::Map){
|
pub fn generate_models(&mut self,map:&map::Map){
|
||||||
let mut starts=Vec::new();
|
let mut starts=Vec::new();
|
||||||
let mut spawns=Vec::new();
|
let mut spawns=Vec::new();
|
||||||
let mut attr_hash=std::collections::HashMap::new();
|
let mut attr_hash=HashMap::new();
|
||||||
for model in &indexed_models.models{
|
for model in &map.models{
|
||||||
let mesh_id=self.models.meshes.len();
|
let mesh_id=self.models.meshes.len();
|
||||||
let mut make_mesh=false;
|
let mut make_mesh=false;
|
||||||
for model_instance in &model.instances{
|
for model_instance in &model.instances{
|
||||||
@ -1084,67 +1082,53 @@ fn run_teleport_behaviour(wormhole:&Option<gameplay_attributes::Wormhole>,game:&
|
|||||||
//TODO: jump count and checkpoints are always reset on teleport.
|
//TODO: jump count and checkpoints are always reset on teleport.
|
||||||
//Map makers are expected to use tools to prevent
|
//Map makers are expected to use tools to prevent
|
||||||
//multi-boosting on JumpLimit boosters such as spawning into a SetVelocity
|
//multi-boosting on JumpLimit boosters such as spawning into a SetVelocity
|
||||||
let stage_element=mode.get_element(model_id)?;
|
if let Some(stage_element)=mode.get_element(model_id){
|
||||||
{
|
let stage=mode.get_stage(stage_element.stage_id)?;
|
||||||
if stage_element.force||game.stage_id<stage_element.stage_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
|
//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;
|
game.stage_id=stage_element.stage_id;
|
||||||
}
|
}
|
||||||
match &stage_element.behaviour{
|
match &stage_element.behaviour{
|
||||||
gameplay_modes::StageElementBehaviour::SpawnAt=>None,
|
gameplay_modes::StageElementBehaviour::SpawnAt=>(),
|
||||||
gameplay_modes::StageElementBehaviour::Trigger
|
gameplay_modes::StageElementBehaviour::Trigger
|
||||||
|gameplay_modes::StageElementBehaviour::Teleport=>{
|
|gameplay_modes::StageElementBehaviour::Teleport=>{
|
||||||
//I guess this is correct behaviour when trying to teleport to a non-existent spawn but it's still weird
|
//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,mode,models,game.stage_id)
|
return teleport_to_spawn(body,touching,style,mode,models,game.stage_id);
|
||||||
},
|
},
|
||||||
gameplay_modes::StageElementBehaviour::Platform=>None,
|
gameplay_modes::StageElementBehaviour::Platform=>(),
|
||||||
&gameplay_modes::StageElementBehaviour::Checkpoint=>{
|
&gameplay_modes::StageElementBehaviour::Checkpoint=>{
|
||||||
// let mode=modes.get_mode(stage_element.mode_id)?;
|
//checkpoint check
|
||||||
// if mode.ordered_checkpoint_id.map_or(true,|id|id<game.next_ordered_checkpoint_id)
|
//TODO: need to check all stages
|
||||||
// &&mode.unordered_checkpoint_count<=game.unordered_checkpoints.len() as u32{
|
if stage.ordered_checkpoint_id.map_or(true,|id|id<game.next_ordered_checkpoint_id)
|
||||||
// //pass
|
&&stage.unordered_checkpoint_count<=game.unordered_checkpoints.len() as u32{
|
||||||
None
|
//pass
|
||||||
// }else{
|
}else{
|
||||||
// //fail
|
//fail
|
||||||
// teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id)
|
return teleport_to_spawn(body,touching,style,mode,models,game.stage_id);
|
||||||
// }
|
}
|
||||||
},
|
},
|
||||||
&gameplay_modes::StageElementBehaviour::Ordered{checkpoint_id}=>{
|
}
|
||||||
if checkpoint_id<game.next_ordered_checkpoint_id{
|
if let Some(next_checkpoint)=stage.ordered_checkpoints.get(&game.next_ordered_checkpoint_id){
|
||||||
//if you hit a checkpoint you already hit, nothing happens
|
if model_id==next_checkpoint{
|
||||||
None
|
|
||||||
}else if game.next_ordered_checkpoint_id==checkpoint_id{
|
|
||||||
//if you hit the next number in a sequence of ordered checkpoints
|
//if you hit the next number in a sequence of ordered checkpoints
|
||||||
//increment the current checkpoint id
|
//increment the current checkpoint id
|
||||||
game.next_ordered_checkpoint_id+=1;
|
game.next_ordered_checkpoint_id=gameplay_modes::CheckpointId::id(game.next_ordered_checkpoint_id.get()+1);
|
||||||
None
|
|
||||||
}else{
|
|
||||||
//If you hit an ordered checkpoint after missing a previous one
|
|
||||||
teleport_to_spawn(body,touching,style,mode,models,game.stage_id)
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
gameplay_modes::StageElementBehaviour::Unordered=>{
|
if stage.unordered_checkpoints.contains(&model_id){
|
||||||
//count model id in accumulated unordered checkpoints
|
//count model id in accumulated unordered checkpoints
|
||||||
game.unordered_checkpoints.insert(model_id);
|
game.unordered_checkpoints.insert(model_id);
|
||||||
None
|
|
||||||
},
|
|
||||||
&gameplay_modes::StageElementBehaviour::JumpLimit(jump_limit)=>{
|
|
||||||
//let count=game.jump_counts.get(&model.id);
|
|
||||||
//TODO
|
|
||||||
None
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}.or_else(||
|
}
|
||||||
match wormhole{
|
match wormhole{
|
||||||
Some(gameplay_attributes::Wormhole{destination_model})=>{
|
&Some(gameplay_attributes::Wormhole{destination_model})=>{
|
||||||
let origin_model=models.model(model_id);
|
let origin_model=models.model(model_id);
|
||||||
let destination_model=models.get_wormhole_model(destination_model)?;
|
let destination_model=models.model(destination_model);
|
||||||
//ignore the transform for now
|
//ignore the transform for now
|
||||||
Some(teleport(body,touching,models,style,body.position-origin_model.transform.translation+destination_model.transform.translation))
|
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 {
|
impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
||||||
@ -1208,14 +1192,14 @@ impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
|||||||
//check ground
|
//check ground
|
||||||
self.touching.insert(c);
|
self.touching.insert(c);
|
||||||
//I love making functions with 10 arguments to dodge the borrow checker
|
//I love making functions with 10 arguments to dodge the borrow checker
|
||||||
run_teleport_behaviour(&general.teleport_behaviour,&mut self.mode_state,&self.models,&self.modes,&self.style,&mut self.touching,&mut self.body,model_id);
|
run_teleport_behaviour(&general.wormhole,&mut self.mode_state,&self.models,&self.modes.get_mode(self.mode).unwrap(),&self.style,&mut self.touching,&mut self.body,model_id);
|
||||||
//flatten v
|
//flatten v
|
||||||
self.touching.constrain_velocity(&self.models,&style_mesh,&mut v);
|
self.touching.constrain_velocity(&self.models,&style_mesh,&mut v);
|
||||||
match &general.booster{
|
match &general.booster{
|
||||||
Some(booster)=>{
|
Some(booster)=>{
|
||||||
//DELETE THIS when boosters get converted to height machines
|
//DELETE THIS when boosters get converted to height machines
|
||||||
match booster{
|
match booster{
|
||||||
&gameplay_attributes::Booster::Affine(transform)=>v=transform.transform_point3(v),
|
//&gameplay_attributes::Booster::Affine(transform)=>v=transform.transform_point3(v),
|
||||||
&gameplay_attributes::Booster::Velocity(velocity)=>v+=velocity,
|
&gameplay_attributes::Booster::Velocity(velocity)=>v+=velocity,
|
||||||
&gameplay_attributes::Booster::Energy{direction: _,energy: _}=>todo!(),
|
&gameplay_attributes::Booster::Energy{direction: _,energy: _}=>todo!(),
|
||||||
}
|
}
|
||||||
@ -1252,7 +1236,7 @@ impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
|||||||
(PhysicsCollisionAttributes::Intersect{intersecting: _,general},Collision::Intersect(intersect))=>{
|
(PhysicsCollisionAttributes::Intersect{intersecting: _,general},Collision::Intersect(intersect))=>{
|
||||||
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
||||||
self.touching.insert(c);
|
self.touching.insert(c);
|
||||||
run_teleport_behaviour(&general.teleport_behaviour,&mut self.mode_state,&self.models,&self.modes,&self.style,&mut self.touching,&mut self.body,model_id);
|
run_teleport_behaviour(&general.wormhole,&mut self.mode_state,&self.models,&self.modes.get_mode(self.mode).unwrap(),&self.style,&mut self.touching,&mut self.body,model_id);
|
||||||
},
|
},
|
||||||
_=>panic!("invalid pair"),
|
_=>panic!("invalid pair"),
|
||||||
}
|
}
|
||||||
@ -1339,7 +1323,12 @@ impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
|||||||
},
|
},
|
||||||
PhysicsInputInstruction::Reset => {
|
PhysicsInputInstruction::Reset => {
|
||||||
//it matters which of these runs first, but I have not thought it through yet as it doesn't matter yet
|
//it matters which of these runs first, but I have not thought it through yet as it doesn't matter yet
|
||||||
set_position(&mut self.body,&mut self.touching,self.spawn_point);
|
let spawn_point={
|
||||||
|
let mode=self.modes.get_mode(self.mode).unwrap();
|
||||||
|
let stage=mode.get_stage(gameplay_modes::StageId::FIRST).unwrap();
|
||||||
|
self.models.model(stage.spawn()).transform.translation
|
||||||
|
};
|
||||||
|
set_position(&mut self.body,&mut self.touching,spawn_point);
|
||||||
set_velocity(&mut self.body,&self.touching,&self.models,&self.style.mesh(),Planar64Vec3::ZERO);
|
set_velocity(&mut self.body,&self.touching,&self.models,&self.style.mesh(),Planar64Vec3::ZERO);
|
||||||
(self.move_state,self.body.acceleration)=self.touching.get_move_state(&self.body,&self.models,&self.style,&self.camera,self.controls,&self.next_mouse,self.time);
|
(self.move_state,self.body.acceleration)=self.touching.get_move_state(&self.body,&self.models,&self.style,&self.camera,self.controls,&self.next_mouse,self.time);
|
||||||
refresh_walk_target=false;
|
refresh_walk_target=false;
|
||||||
|
@ -120,7 +120,7 @@ pub enum Instruction{
|
|||||||
},
|
},
|
||||||
Instruction::GenerateModels(indexed_model_instances)=>{
|
Instruction::GenerateModels(indexed_model_instances)=>{
|
||||||
physics.generate_models(&indexed_model_instances);
|
physics.generate_models(&indexed_model_instances);
|
||||||
physics.spawn(indexed_model_instances.spawn_point);
|
physics.spawn();
|
||||||
graphics_worker.send(crate::graphics_worker::Instruction::GenerateModels(indexed_model_instances)).unwrap();
|
graphics_worker.send(crate::graphics_worker::Instruction::GenerateModels(indexed_model_instances)).unwrap();
|
||||||
},
|
},
|
||||||
Instruction::ClearModels=>{
|
Instruction::ClearModels=>{
|
||||||
|
Loading…
Reference in New Issue
Block a user