forked from StrafesNET/strafe-client
work on indexing meshes and attributes
This commit is contained in:
parent
1ec9412b49
commit
e92eaed2d3
@ -156,28 +156,48 @@ impl Default for Modes{
|
||||
|
||||
#[derive(Default)]
|
||||
struct PhysicsModels{
|
||||
//TODO: put meshes, attributes in here, indexed!
|
||||
meshes:Vec<PhysicsMesh>,
|
||||
models:Vec<PhysicsModel>,
|
||||
attributes:Vec<PhysicsCollisionAttributes>,
|
||||
model_id_from_wormhole_id:std::collections::HashMap::<u32,usize>,
|
||||
}
|
||||
impl PhysicsModels{
|
||||
fn clear(&mut self){
|
||||
self.meshes.clear();
|
||||
self.models.clear();
|
||||
self.attributes.clear();
|
||||
self.model_id_from_wormhole_id.clear();
|
||||
}
|
||||
//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 get(&self,model_id:usize)->Option<&PhysicsModel>{
|
||||
self.models.get(model_id)
|
||||
fn mesh(&self,model_id:usize)->TransformedMesh{
|
||||
TransformedMesh{
|
||||
mesh:&self.meshes[self.models[model_id].mesh_id],
|
||||
transform:&self.models[model_id].transform,
|
||||
normal_transform:&self.models[model_id].normal_transform,
|
||||
normal_determinant:self.models[model_id].normal_determinant,
|
||||
}
|
||||
}
|
||||
fn model(&self,model_id:usize)->&PhysicsModel{
|
||||
&self.models[model_id]
|
||||
}
|
||||
fn attr(&self,model_id:usize)->&PhysicsCollisionAttributes{
|
||||
&self.attributes[self.models[model_id].attr_id]
|
||||
}
|
||||
fn get_wormhole_model(&self,wormhole_id:u32)->Option<&PhysicsModel>{
|
||||
self.models.get(*self.model_id_from_wormhole_id.get(&wormhole_id)?)
|
||||
}
|
||||
fn push(&mut self,model:PhysicsModel)->usize{
|
||||
fn push_mesh(&mut self,mesh:PhysicsMesh){
|
||||
self.meshes.push(mesh);
|
||||
}
|
||||
fn push_model(&mut self,model:PhysicsModel)->usize{
|
||||
let model_id=self.models.len();
|
||||
self.models.push(model);
|
||||
model_id
|
||||
}
|
||||
fn push_attr(&mut self,attr:PhysicsCollisionAttributes){
|
||||
self.attributes.push(attr);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -624,35 +644,30 @@ 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:usize,
|
||||
attributes:PhysicsCollisionAttributes,
|
||||
attr_id:usize,
|
||||
transform:crate::integer::Planar64Affine3,
|
||||
normal_transform:crate::integer::Planar64Mat3,
|
||||
normal_determinant:Planar64,
|
||||
}
|
||||
|
||||
impl PhysicsModel{
|
||||
fn new(mesh_id:usize,transform:crate::integer::Planar64Affine3,attributes:PhysicsCollisionAttributes)->Self{
|
||||
fn new(mesh_id:usize,attr_id:usize,transform:crate::integer::Planar64Affine3)->Self{
|
||||
let normal_transform=transform.matrix3.inverse().transpose();
|
||||
Self{
|
||||
mesh_id,
|
||||
attributes,
|
||||
attr_id,
|
||||
transform,
|
||||
normal_transform:transform.matrix3.inverse().transpose(),
|
||||
normal_transform,
|
||||
normal_determinant:normal_transform.determinant(),
|
||||
}
|
||||
}
|
||||
pub fn from_model(mesh_id:usize,instance:&crate::model::ModelInstance) -> Option<Self> {
|
||||
pub fn from_model(mesh_id:usize,instance:&crate::model::ModelInstance)->Option<Self>{
|
||||
match &instance.attributes{
|
||||
crate::model::CollisionAttributes::Contact{contacting,general}=>Some(PhysicsModel::new(mesh_id,instance.transform.clone(),PhysicsCollisionAttributes::Contact{contacting:contacting.clone(),general:general.clone()})),
|
||||
crate::model::CollisionAttributes::Intersect{intersecting,general}=>Some(PhysicsModel::new(mesh_id,instance.transform.clone(),PhysicsCollisionAttributes::Intersect{intersecting:intersecting.clone(),general:general.clone()})),
|
||||
crate::model::CollisionAttributes::Decoration=>None,
|
||||
}
|
||||
}
|
||||
pub fn mesh<'a>(&self,meshes:&Vec<PhysicsMesh>)->TransformedMesh<'a>{
|
||||
TransformedMesh{
|
||||
mesh:&meshes[self.mesh_id],
|
||||
transform:&self.transform,
|
||||
normal_transform:&self.normal_transform,
|
||||
normal_determinant:self.normal_transform.determinant(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug,Clone,Eq,Hash,PartialEq)]
|
||||
@ -697,7 +712,7 @@ impl TouchingState{
|
||||
//contact constrain?
|
||||
todo!()
|
||||
}
|
||||
fn constrain_velocity(&self,meshes:&Vec<PhysicsModel>,models:&PhysicsModels,velocity:&mut Planar64Vec3){
|
||||
fn constrain_velocity(&self,models:&PhysicsModels,velocity:&mut Planar64Vec3){
|
||||
for contact in &self.contacts{
|
||||
//trey push solve
|
||||
}
|
||||
@ -823,7 +838,8 @@ impl PhysicsState {
|
||||
for model_instance in &model.instances{
|
||||
if let Some(model_physics)=PhysicsModel::from_model(mesh_id,model_instance){
|
||||
make_mesh=true;
|
||||
let model_id=self.models.push(model_physics);
|
||||
//TODO: index attributes
|
||||
let model_id=self.models.push_model(model_physics);
|
||||
for attr in &model_instance.temp_indexing{
|
||||
match attr{
|
||||
crate::model::TempIndexedAttributes::Start(s)=>starts.push((model_id,s.clone())),
|
||||
@ -991,7 +1007,7 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
|
||||
aabb.inflate(self.style.hitbox_halfsize);
|
||||
self.bvh.the_tester(&aabb,&mut |id|{
|
||||
//no checks are needed because of the time limits.
|
||||
let minkowski=crate::model_physics::MinkowskiMesh::minkowski_sum(self.style.mesh,self.models.mesh(id));
|
||||
let minkowski=crate::model_physics::MinkowskiMesh::minkowski_sum(self.style.mesh,&self.models.mesh(id));
|
||||
let relative_body=VirtualBody::relative(&self.body,&Body::default()).body(self.time);
|
||||
collector.collect(crate::face_crawler::predict_collision(&minkowski,&relative_body,collector.time()).map(|(face,time)|{
|
||||
//TODO: match model attribute and generate Collision::{Contact,Intersect}
|
||||
@ -1012,12 +1028,12 @@ fn teleport(body:&mut Body,touching:&mut TouchingState,style:&StyleModifiers,poi
|
||||
//touching.recalculate(body);
|
||||
}
|
||||
fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModifiers,mode:&crate::model::ModeDescription,models:&PhysicsModels,stage_id:u32)->Option<MoveState>{
|
||||
let model=models.get(*mode.get_spawn_model_id(stage_id)? as usize)?;
|
||||
let model=models.model(*mode.get_spawn_model_id(stage_id)? as usize);
|
||||
let point=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(style.hitbox_halfsize.y()+Planar64::ONE/16);
|
||||
Some(teleport(body,touching,style,point))
|
||||
}
|
||||
|
||||
fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehaviour>,game:&mut GameMechanicsState,models:&PhysicsModels,modes:&Modes,style:&StyleModifiers,touching:&mut TouchingState,body:&mut Body,model:&PhysicsModel)->Option<MoveState>{
|
||||
fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehaviour>,game:&mut GameMechanicsState,models:&PhysicsModels,modes:&Modes,style:&StyleModifiers,touching:&mut TouchingState,body:&mut Body,model_id:usize)->Option<MoveState>{
|
||||
match teleport_behaviour{
|
||||
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
|
||||
if stage_element.force||game.stage_id<stage_element.stage_id{
|
||||
@ -1049,7 +1065,7 @@ fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehav
|
||||
}
|
||||
},
|
||||
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{
|
||||
let origin_model=model;
|
||||
let origin_model=models.model(model_id);
|
||||
let destination_model=models.get_wormhole_model(wormhole.destination_model_id)?;
|
||||
//ignore the transform for now
|
||||
Some(teleport(body,touching,style,body.position-origin_model.transform.translation+destination_model.transform.translation))
|
||||
@ -1110,9 +1126,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
||||
},
|
||||
}
|
||||
//check ground
|
||||
self.touching.insert_contact(c.model,c);
|
||||
self.touching.insert(c);
|
||||
//I love making functions with 10 arguments to dodge the borrow checker
|
||||
run_teleport_behaviour(&general.teleport_behaviour,&mut self.game,&self.models,&self.modes,&self.style,&mut self.touching,&mut self.body,model);
|
||||
run_teleport_behaviour(&general.teleport_behaviour,&mut self.game,&self.models,&self.modes,&self.style,&mut self.touching,&mut self.body,model_id);
|
||||
//flatten v
|
||||
self.touching.constrain_velocity(&self.models,&mut v);
|
||||
match &general.booster{
|
||||
@ -1150,16 +1166,15 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
||||
},
|
||||
PhysicsCollisionAttributes::Intersect{intersecting: _,general}=>{
|
||||
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
|
||||
self.touching.insert_intersect(c.model,c);
|
||||
run_teleport_behaviour(&general.teleport_behaviour,&mut self.game,&self.models,&self.modes,&self.style,&mut self.touching,&mut self.body,model);
|
||||
self.touching.insert(c);
|
||||
run_teleport_behaviour(&general.teleport_behaviour,&mut self.game,&self.models,&self.modes,&self.style,&mut self.touching,&mut self.body,model_id);
|
||||
},
|
||||
}
|
||||
},
|
||||
PhysicsInstruction::CollisionEnd(c) => {
|
||||
let model=c.model(&self.models).unwrap();
|
||||
match &model.attributes{
|
||||
match self.models.attr(c.model_id()){
|
||||
PhysicsCollisionAttributes::Contact{contacting: _,general: _}=>{
|
||||
self.touching.remove_contact(c.model);//remove contact before calling contact_constrain_acceleration
|
||||
self.touching.remove(&c);//remove contact before calling contact_constrain_acceleration
|
||||
let mut a=self.style.gravity;
|
||||
if let Some(rocket_force)=self.style.rocket_force{
|
||||
a+=self.style.get_propulsion_control_dir(&self.camera,self.controls,&self.next_mouse,self.time)*rocket_force;
|
||||
@ -1179,7 +1194,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|
||||
}
|
||||
},
|
||||
PhysicsCollisionAttributes::Intersect{intersecting: _,general: _}=>{
|
||||
self.touching.remove_intersect(c.model);
|
||||
self.touching.remove(&c);
|
||||
},
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user