work on indexing meshes and attributes

This commit is contained in:
Quaternions 2023-11-01 16:26:24 -07:00
parent 1ec9412b49
commit e92eaed2d3

View File

@ -156,28 +156,48 @@ impl Default for Modes{
#[derive(Default)] #[derive(Default)]
struct PhysicsModels{ struct PhysicsModels{
//TODO: put meshes, attributes in here, indexed! meshes:Vec<PhysicsMesh>,
models:Vec<PhysicsModel>, models:Vec<PhysicsModel>,
attributes:Vec<PhysicsCollisionAttributes>,
model_id_from_wormhole_id:std::collections::HashMap::<u32,usize>, model_id_from_wormhole_id:std::collections::HashMap::<u32,usize>,
} }
impl PhysicsModels{ impl PhysicsModels{
fn clear(&mut self){ fn clear(&mut self){
self.meshes.clear();
self.models.clear(); self.models.clear();
self.attributes.clear();
self.model_id_from_wormhole_id.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. //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 get(&self,model_id:usize)->Option<&PhysicsModel>{ fn mesh(&self,model_id:usize)->TransformedMesh{
self.models.get(model_id) 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>{ fn get_wormhole_model(&self,wormhole_id:u32)->Option<&PhysicsModel>{
self.models.get(*self.model_id_from_wormhole_id.get(&wormhole_id)?) 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(); let model_id=self.models.len();
self.models.push(model); self.models.push(model);
model_id model_id
} }
fn push_attr(&mut self,attr:PhysicsCollisionAttributes){
self.attributes.push(attr);
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -624,18 +644,21 @@ pub struct PhysicsModel{
//A model is a thing that has a hitbox. can be represented by a list of TreyMesh-es //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. //in this iteration, all it needs is extents.
mesh_id:usize, mesh_id:usize,
attributes:PhysicsCollisionAttributes, attr_id:usize,
transform:crate::integer::Planar64Affine3, transform:crate::integer::Planar64Affine3,
normal_transform:crate::integer::Planar64Mat3, normal_transform:crate::integer::Planar64Mat3,
normal_determinant:Planar64,
} }
impl PhysicsModel{ 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{ Self{
mesh_id, mesh_id,
attributes, attr_id,
transform, 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>{
@ -645,14 +668,6 @@ impl PhysicsModel{
crate::model::CollisionAttributes::Decoration=>None, 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)] #[derive(Debug,Clone,Eq,Hash,PartialEq)]
@ -697,7 +712,7 @@ impl TouchingState{
//contact constrain? //contact constrain?
todo!() 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{ for contact in &self.contacts{
//trey push solve //trey push solve
} }
@ -823,7 +838,8 @@ impl PhysicsState {
for model_instance in &model.instances{ for model_instance in &model.instances{
if let Some(model_physics)=PhysicsModel::from_model(mesh_id,model_instance){ if let Some(model_physics)=PhysicsModel::from_model(mesh_id,model_instance){
make_mesh=true; 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{ for attr in &model_instance.temp_indexing{
match attr{ match attr{
crate::model::TempIndexedAttributes::Start(s)=>starts.push((model_id,s.clone())), 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); aabb.inflate(self.style.hitbox_halfsize);
self.bvh.the_tester(&aabb,&mut |id|{ self.bvh.the_tester(&aabb,&mut |id|{
//no checks are needed because of the time limits. //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); 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)|{ collector.collect(crate::face_crawler::predict_collision(&minkowski,&relative_body,collector.time()).map(|(face,time)|{
//TODO: match model attribute and generate Collision::{Contact,Intersect} //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); //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>{ 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); let point=model.transform.transform_point3(Planar64Vec3::Y)+Planar64Vec3::Y*(style.hitbox_halfsize.y()+Planar64::ONE/16);
Some(teleport(body,touching,style,point)) 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{ match teleport_behaviour{
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{ Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
if stage_element.force||game.stage_id<stage_element.stage_id{ 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))=>{ 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)?; let destination_model=models.get_wormhole_model(wormhole.destination_model_id)?;
//ignore the transform for now //ignore the transform for now
Some(teleport(body,touching,style,body.position-origin_model.transform.translation+destination_model.transform.translation)) 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 //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 //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 //flatten v
self.touching.constrain_velocity(&self.models,&mut v); self.touching.constrain_velocity(&self.models,&mut v);
match &general.booster{ match &general.booster{
@ -1150,16 +1166,15 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
}, },
PhysicsCollisionAttributes::Intersect{intersecting: _,general}=>{ PhysicsCollisionAttributes::Intersect{intersecting: _,general}=>{
//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_intersect(c.model,c); 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); 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) => { PhysicsInstruction::CollisionEnd(c) => {
let model=c.model(&self.models).unwrap(); match self.models.attr(c.model_id()){
match &model.attributes{
PhysicsCollisionAttributes::Contact{contacting: _,general: _}=>{ 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; let mut a=self.style.gravity;
if let Some(rocket_force)=self.style.rocket_force{ 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; 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: _}=>{ PhysicsCollisionAttributes::Intersect{intersecting: _,general: _}=>{
self.touching.remove_intersect(c.model); self.touching.remove(&c);
}, },
} }
}, },