forked from StrafesNET/strafe-client
wip
This commit is contained in:
parent
8687c65e80
commit
56bf453337
@ -1,7 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
use strafesnet_common::map;
|
||||
use strafesnet_common::model;
|
||||
use strafesnet_common::integer;
|
||||
use strafesnet_common::model::{self,ColorId,NormalId,PositionId,TextureCoordinateId,VertexId};
|
||||
use wgpu::{util::DeviceExt,AstcBlock,AstcChannel};
|
||||
use crate::model_graphics::{GraphicsVertex,GraphicsModelColor4,GraphicsModelInstance,GraphicsModelSingleTexture,IndexedGraphicsModelSingleTexture,IndexedGroupFixedTexture};
|
||||
|
||||
@ -332,73 +332,73 @@ impl GraphicsState{
|
||||
let model=&unique_texture_models[model_id];
|
||||
let instance=&model.instances[instance_id];
|
||||
//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 h=pos.map(|v|bytemuck::cast::<f32,u32>(v));
|
||||
(if let Some(&pos_id)=pos_id_from.get(&h){
|
||||
let h=bytemuck::cast::<[f32;3],[u32;3]>(pos);
|
||||
PositionId::id((if let Some(&pos_id)=pos_id_from.get(&h){
|
||||
pos_id
|
||||
}else{
|
||||
let pos_id=unique_pos.len();
|
||||
unique_pos.push(pos.clone());
|
||||
unique_pos.push(pos);
|
||||
pos_id_from.insert(h,pos_id);
|
||||
pos_id
|
||||
}) as u32
|
||||
}) as u32)
|
||||
}).collect();
|
||||
let map_tex_id:Vec<u32>=model.unique_tex.iter().map(|tex|{
|
||||
let h=tex.map(|v|bytemuck::cast::<f32,u32>(v));
|
||||
(if let Some(&tex_id)=tex_id_from.get(&h){
|
||||
let map_tex_id:Vec<TextureCoordinateId>=model.unique_tex.iter().map(|&tex|{
|
||||
let h=bytemuck::cast::<[f32;2],[u32;2]>(tex);
|
||||
TextureCoordinateId::id((if let Some(&tex_id)=tex_id_from.get(&h){
|
||||
tex_id
|
||||
}else{
|
||||
let tex_id=unique_tex.len();
|
||||
unique_tex.push(tex.clone());
|
||||
unique_tex.push(tex);
|
||||
tex_id_from.insert(h,tex_id);
|
||||
tex_id
|
||||
}) as u32
|
||||
}) as u32)
|
||||
}).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 h=normal.map(|v|bytemuck::cast::<f32,u32>(v));
|
||||
(if let Some(&normal_id)=normal_id_from.get(&h){
|
||||
let h=bytemuck::cast::<[f32;3],[u32;3]>(normal);
|
||||
NormalId::id((if let Some(&normal_id)=normal_id_from.get(&h){
|
||||
normal_id
|
||||
}else{
|
||||
let normal_id=unique_normal.len();
|
||||
unique_normal.push(normal.clone());
|
||||
unique_normal.push(normal);
|
||||
normal_id_from.insert(h,normal_id);
|
||||
normal_id
|
||||
}) as u32
|
||||
}) as u32)
|
||||
}).collect();
|
||||
let map_color_id:Vec<u32>=model.unique_color.iter().map(|color|{
|
||||
let h=color.map(|v|bytemuck::cast::<f32,u32>(v));
|
||||
(if let Some(&color_id)=color_id_from.get(&h){
|
||||
let map_color_id:Vec<ColorId>=model.unique_color.iter().map(|&color|{
|
||||
let h=bytemuck::cast::<[f32;4],[u32;4]>(color);
|
||||
ColorId::id((if let Some(&color_id)=color_id_from.get(&h){
|
||||
color_id
|
||||
}else{
|
||||
let color_id=unique_color.len();
|
||||
unique_color.push(color.clone());
|
||||
unique_color.push(color);
|
||||
color_id_from.insert(h,color_id);
|
||||
color_id
|
||||
}) as u32
|
||||
}) as u32)
|
||||
}).collect();
|
||||
//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 map_vertex_id:Vec<VertexId>=model.unique_vertices.iter().map(|unmapped_vertex|{
|
||||
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],
|
||||
color:map_color_id[unmapped_vertex.color as usize],
|
||||
pos:map_pos_id[unmapped_vertex.pos.get() as usize],
|
||||
tex:map_tex_id[unmapped_vertex.tex.get() as usize],
|
||||
normal:map_normal_id[unmapped_vertex.normal.get() 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
|
||||
}else{
|
||||
let vertex_id=unique_vertices.len();
|
||||
unique_vertices.push(vertex.clone());
|
||||
vertex_id_from.insert(vertex,vertex_id);
|
||||
vertex_id
|
||||
}) as u32
|
||||
}) as u32)
|
||||
}).collect();
|
||||
for group in &model.groups{
|
||||
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);
|
||||
}else{
|
||||
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{
|
||||
pos: model.unique_pos[vertex.pos as usize],
|
||||
tex: model.unique_tex[vertex.tex as usize],
|
||||
normal: model.unique_normal[vertex.normal as usize],
|
||||
color:model.unique_color[vertex.color as usize],
|
||||
pos: model.unique_pos[vertex.pos.get() as usize],
|
||||
tex: model.unique_tex[vertex.tex.get() as usize],
|
||||
normal: model.unique_normal[vertex.normal.get() as usize],
|
||||
color:model.unique_color[vertex.color.get() as usize],
|
||||
});
|
||||
index_from_vertex.insert(vertex_index,i);
|
||||
indices.push(i);
|
||||
|
@ -1,5 +1,5 @@
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use strafesnet_common::model::{IndexedVertex,IndexedPolygon};
|
||||
use strafesnet_common::model::{IndexedVertex,IndexedVertexList};
|
||||
#[derive(Clone,Copy,Pod,Zeroable)]
|
||||
#[repr(C)]
|
||||
pub struct GraphicsVertex{
|
||||
@ -9,7 +9,7 @@ pub struct GraphicsVertex{
|
||||
pub color:[f32;4],
|
||||
}
|
||||
pub struct IndexedGroupFixedTexture{
|
||||
pub polys:Vec<IndexedPolygon>,
|
||||
pub polys:Vec<IndexedVertexList>,
|
||||
}
|
||||
pub struct IndexedGraphicsModelSingleTexture{
|
||||
pub unique_pos:Vec<[f32;3]>,
|
||||
|
@ -144,14 +144,14 @@ impl From<&model::IndexedModel> for PhysicsMesh{
|
||||
let mut face_i=0;
|
||||
let mut faces=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);
|
||||
//one face per poly
|
||||
let mut normal=Planar64Vec3::ZERO;
|
||||
let len=poly.vertices.len();
|
||||
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 vert1_id=indexed_model.unique_vertices[poly.vertices[(i+1)%len] 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.get() as usize;
|
||||
//https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal (Newell's Method)
|
||||
let v0=indexed_model.unique_pos[vert0_id];
|
||||
let v1=indexed_model.unique_pos[vert1_id];
|
||||
@ -180,7 +180,7 @@ impl From<&model::IndexedModel> for PhysicsMesh{
|
||||
normal=normal/len as i64;
|
||||
let mut dot=Planar64::ZERO;
|
||||
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});
|
||||
face_ref_guys.push(FaceRefEdges(face_edges));
|
||||
@ -740,7 +740,6 @@ fn test_is_empty_volume(){
|
||||
|
||||
#[test]
|
||||
fn build_me_a_cube(){
|
||||
let unit_cube=crate::primitives::unit_cube();
|
||||
let mesh=PhysicsMesh::from(&unit_cube);
|
||||
let mesh=PhysicsMesh::unit_cube();
|
||||
//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.
|
||||
//then I can make these getter functions unchecked.
|
||||
fn mesh(&self,model_id:ModelId)->TransformedMesh{
|
||||
let idx=model_id.get() as usize;
|
||||
let mesh_id=self.models[idx].mesh_id;
|
||||
TransformedMesh::new(
|
||||
&self.meshes[self.models[model_id].mesh_id],
|
||||
&self.models[model_id].transform,
|
||||
&self.models[model_id].normal_transform,
|
||||
self.models[model_id].transform_det,
|
||||
&self.meshes[mesh_id.model_id.get() as usize].groups[mesh_id.group_id.get() as usize],
|
||||
&self.models[idx].transform,
|
||||
&self.models[idx].normal_transform,
|
||||
self.models[idx].transform_det,
|
||||
)
|
||||
}
|
||||
fn model(&self,model_id:ModelId)->&PhysicsModel{
|
||||
@ -192,7 +194,7 @@ impl PhysicsModels{
|
||||
self.models.push(model);
|
||||
model_id
|
||||
}
|
||||
fn push_attr(&mut self,attr:PhysicsCollisionAttributes)->PhysicsAttributeId{
|
||||
fn push_attr(&mut self,attr:PhysicsCollisionAttributes)->PhysicsAttributesId{
|
||||
let attr_id=self.attributes.len();
|
||||
self.attributes.push(attr);
|
||||
attr_id
|
||||
@ -271,8 +273,8 @@ impl std::default::Default for ModeState{
|
||||
Self{
|
||||
stage_id:gameplay_modes::StageId::id(0),
|
||||
next_ordered_checkpoint_id:gameplay_modes::CheckpointId::id(0),
|
||||
unordered_checkpoints:std::collections::HashSet::new(),
|
||||
jump_counts:std::collections::HashMap::new(),
|
||||
unordered_checkpoints:HashSet::new(),
|
||||
jump_counts:HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -528,8 +530,8 @@ impl Collision{
|
||||
}
|
||||
#[derive(Default)]
|
||||
struct TouchingState{
|
||||
contacts:std::collections::HashSet::<ContactCollision>,
|
||||
intersects:std::collections::HashSet::<IntersectCollision>,
|
||||
contacts:HashSet::<ContactCollision>,
|
||||
intersects:HashSet::<IntersectCollision>,
|
||||
}
|
||||
impl TouchingState{
|
||||
fn clear(&mut self){
|
||||
@ -778,9 +780,9 @@ pub struct PhysicsState{
|
||||
controls:u32,//TODO this should be a struct
|
||||
move_state:MoveState,
|
||||
//does not belong here
|
||||
//bvh:bvh::BvhNode,
|
||||
//models:PhysicsModels,
|
||||
//modes:gameplay_modes::Modes,
|
||||
bvh:bvh::BvhNode,
|
||||
models:PhysicsModels,
|
||||
modes:gameplay_modes::Modes,
|
||||
}
|
||||
impl Default for PhysicsState{
|
||||
fn default()->Self{
|
||||
@ -795,19 +797,16 @@ impl Default for PhysicsState{
|
||||
controls:0,
|
||||
world:WorldState{},
|
||||
mode_state:ModeState::default(),
|
||||
//modes:Modes::default(),
|
||||
//bvh:bvh::BvhNode::default(),
|
||||
//models:PhysicsModels::default(),
|
||||
modes:Modes::default(),
|
||||
bvh:bvh::BvhNode::default(),
|
||||
models:PhysicsModels::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PhysicsState {
|
||||
pub fn clear(&mut self){
|
||||
self.models.clear();
|
||||
self.modes.clear();
|
||||
self.touching.clear();
|
||||
self.bvh=bvh::BvhNode::default();
|
||||
}
|
||||
|
||||
pub fn output(&self)->PhysicsOutputState{
|
||||
@ -818,20 +817,19 @@ impl PhysicsState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn(&mut self,spawn_point:Planar64Vec3){
|
||||
self.mode_state.stage_id=0;
|
||||
self.spawn_point=spawn_point;
|
||||
pub fn spawn(&mut self){
|
||||
self.mode_state.stage_id=gameplay_modes::StageId::id(0);
|
||||
self.process_instruction(instruction::TimedInstruction{
|
||||
time:self.time,
|
||||
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 spawns=Vec::new();
|
||||
let mut attr_hash=std::collections::HashMap::new();
|
||||
for model in &indexed_models.models{
|
||||
let mut attr_hash=HashMap::new();
|
||||
for model in &map.models{
|
||||
let mesh_id=self.models.meshes.len();
|
||||
let mut make_mesh=false;
|
||||
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.
|
||||
//Map makers are expected to use tools to prevent
|
||||
//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{
|
||||
//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{
|
||||
gameplay_modes::StageElementBehaviour::SpawnAt=>None,
|
||||
gameplay_modes::StageElementBehaviour::SpawnAt=>(),
|
||||
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,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=>{
|
||||
// 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{
|
||||
// //pass
|
||||
None
|
||||
// }else{
|
||||
// //fail
|
||||
// teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id)
|
||||
// }
|
||||
//checkpoint check
|
||||
//TODO: need to check all stages
|
||||
if stage.ordered_checkpoint_id.map_or(true,|id|id<game.next_ordered_checkpoint_id)
|
||||
&&stage.unordered_checkpoint_count<=game.unordered_checkpoints.len() as u32{
|
||||
//pass
|
||||
}else{
|
||||
//fail
|
||||
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 you hit a checkpoint you already hit, nothing happens
|
||||
None
|
||||
}else if game.next_ordered_checkpoint_id==checkpoint_id{
|
||||
}
|
||||
if let Some(next_checkpoint)=stage.ordered_checkpoints.get(&game.next_ordered_checkpoint_id){
|
||||
if model_id==next_checkpoint{
|
||||
//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{
|
||||
//If you hit an ordered checkpoint after missing a previous one
|
||||
teleport_to_spawn(body,touching,style,mode,models,game.stage_id)
|
||||
game.next_ordered_checkpoint_id=gameplay_modes::CheckpointId::id(game.next_ordered_checkpoint_id.get()+1);
|
||||
}
|
||||
},
|
||||
gameplay_modes::StageElementBehaviour::Unordered=>{
|
||||
}
|
||||
if stage.unordered_checkpoints.contains(&model_id){
|
||||
//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(||
|
||||
}
|
||||
match wormhole{
|
||||
Some(gameplay_attributes::Wormhole{destination_model})=>{
|
||||
&Some(gameplay_attributes::Wormhole{destination_model})=>{
|
||||
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
|
||||
Some(teleport(body,touching,models,style,body.position-origin_model.transform.translation+destination_model.transform.translation))
|
||||
}
|
||||
None=>None,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
||||
@ -1208,14 +1192,14 @@ impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
||||
//check ground
|
||||
self.touching.insert(c);
|
||||
//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
|
||||
self.touching.constrain_velocity(&self.models,&style_mesh,&mut v);
|
||||
match &general.booster{
|
||||
Some(booster)=>{
|
||||
//DELETE THIS when boosters get converted to height machines
|
||||
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::Energy{direction: _,energy: _}=>todo!(),
|
||||
}
|
||||
@ -1252,7 +1236,7 @@ impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
||||
(PhysicsCollisionAttributes::Intersect{intersecting: _,general},Collision::Intersect(intersect))=>{
|
||||
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
||||
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"),
|
||||
}
|
||||
@ -1339,7 +1323,12 @@ impl instruction::InstructionConsumer<PhysicsInstruction> for PhysicsState {
|
||||
},
|
||||
PhysicsInputInstruction::Reset => {
|
||||
//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);
|
||||
(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;
|
||||
|
@ -120,7 +120,7 @@ pub enum Instruction{
|
||||
},
|
||||
Instruction::GenerateModels(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();
|
||||
},
|
||||
Instruction::ClearModels=>{
|
||||
|
Loading…
Reference in New Issue
Block a user