This commit is contained in:
Quaternions 2024-02-04 22:37:09 -08:00
parent 8687c65e80
commit 56bf453337
5 changed files with 104 additions and 116 deletions

View File

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

View File

@ -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]>,

View File

@ -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);
} }

View File

@ -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{
// //fail
// teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_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
}else if game.next_ordered_checkpoint_id==checkpoint_id{
//if you hit the next number in a sequence of ordered checkpoints
//increment the current checkpoint id
game.next_ordered_checkpoint_id+=1;
None
}else{ }else{
//If you hit an ordered checkpoint after missing a previous one //fail
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::Unordered=>{
//count model id in accumulated unordered checkpoints
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(|| if let Some(next_checkpoint)=stage.ordered_checkpoints.get(&game.next_ordered_checkpoint_id){
match wormhole{ if model_id==next_checkpoint{
Some(gameplay_attributes::Wormhole{destination_model})=>{ //if you hit the next number in a sequence of ordered checkpoints
let origin_model=models.model(model_id); //increment the current checkpoint id
let destination_model=models.get_wormhole_model(destination_model)?; game.next_ordered_checkpoint_id=gameplay_modes::CheckpointId::id(game.next_ordered_checkpoint_id.get()+1);
//ignore the transform for now
Some(teleport(body,touching,models,style,body.position-origin_model.transform.translation+destination_model.transform.translation))
} }
None=>None,
} }
) if stage.unordered_checkpoints.contains(&model_id){
//count model id in accumulated unordered checkpoints
game.unordered_checkpoints.insert(model_id);
}
}
match wormhole{
&Some(gameplay_attributes::Wormhole{destination_model})=>{
let origin_model=models.model(model_id);
let destination_model=models.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,
}
} }
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;

View File

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