physics: flush face transfer
This commit is contained in:
parent
2a5f610650
commit
b8a0175686
@ -26,6 +26,8 @@ use strafesnet_common::physics::{Instruction,MouseInstruction,ModeInstruction,Mi
|
||||
#[derive(Debug)]
|
||||
pub enum InternalInstruction{
|
||||
CollisionStart(Collision,model_physics::GigaTime),
|
||||
// transfer to a flush minkowski face
|
||||
CollisionTransfer(ContactCollision,model_physics::MinkowskiFace),
|
||||
CollisionEnd(Collision,model_physics::GigaTime),
|
||||
StrafeTick,
|
||||
ReachWalkTargetVelocity,
|
||||
@ -785,19 +787,40 @@ impl TouchingState{
|
||||
crate::push_solve::push_solve(&contacts,acceleration)
|
||||
}
|
||||
fn predict_collision_end(&self,collector:&mut instruction::InstructionCollector<InternalInstruction,Time>,models:&PhysicsModels,hitbox_mesh:&HitboxMesh,body:&Body,start_time:Time){
|
||||
use model_physics::DirectedEdge;
|
||||
// let relative_body=body.relative_to(&Body::ZERO);
|
||||
let relative_body=body;
|
||||
for contact in &self.contacts{
|
||||
//detect face slide off
|
||||
let model_mesh=models.contact_mesh(contact);
|
||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
|
||||
collector.collect(minkowski.predict_collision_face_out(&relative_body,start_time..collector.time(),contact.face_id).map(|(_face,time)|{
|
||||
TimedInstruction{
|
||||
time:relative_body.time+time.into(),
|
||||
instruction:InternalInstruction::CollisionEnd(
|
||||
Collision::Contact(*contact),
|
||||
time
|
||||
),
|
||||
collector.collect(minkowski.predict_collision_face_out(&relative_body,start_time..collector.time(),contact.face_id).map(|(out_edge,time)|{
|
||||
// TODO: determine if this code should go inside predict_collision_face_out
|
||||
// check if the face across the out_edge is flush to contact.face_id
|
||||
let (src_face_n,_src_face_d)=minkowski.face_nd(contact.face_id);
|
||||
// the face across may be left or right depending on the directed edge parity
|
||||
let dst_face=minkowski.edge_faces(out_edge.as_undirected()).as_ref()[!out_edge.parity() as usize];
|
||||
let (dst_face_n,_dst_face_d)=minkowski.face_nd(dst_face);
|
||||
// are they exactly flush
|
||||
if src_face_n.cross(dst_face_n)==vec3::ZERO_6
|
||||
// implicitly don't need to check d values because faces share two vertices
|
||||
// && n0*d1==n1*d0
|
||||
{
|
||||
TimedInstruction{
|
||||
time:relative_body.time+time.into(),
|
||||
instruction:InternalInstruction::CollisionTransfer(
|
||||
*contact,
|
||||
dst_face,
|
||||
),
|
||||
}
|
||||
}else{
|
||||
TimedInstruction{
|
||||
time:relative_body.time+time.into(),
|
||||
instruction:InternalInstruction::CollisionEnd(
|
||||
Collision::Contact(*contact),
|
||||
time
|
||||
),
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
@ -1656,6 +1679,7 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
||||
|InternalInstruction::CollisionEnd(_,dt)=>(true,Some(dt)),
|
||||
InternalInstruction::StrafeTick
|
||||
|InternalInstruction::ReachWalkTargetVelocity=>(true,None),
|
||||
InternalInstruction::CollisionTransfer(..)=>(false,None),
|
||||
};
|
||||
if should_advance_body{
|
||||
match goober_time{
|
||||
@ -1700,6 +1724,15 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
||||
state.time
|
||||
),
|
||||
},
|
||||
InternalInstruction::CollisionTransfer(collision,dst_face)=>{
|
||||
// transfer to a flush surface of the same object
|
||||
state.touching.contacts.remove(&collision);
|
||||
state.touching.contacts.insert(ContactCollision{
|
||||
face_id:dst_face,
|
||||
model_id:collision.model_id,
|
||||
submesh_id:collision.submesh_id,
|
||||
});
|
||||
},
|
||||
InternalInstruction::StrafeTick=>{
|
||||
//TODO make this less huge
|
||||
if let Some(strafe_settings)=&state.style.strafe{
|
||||
|
Loading…
x
Reference in New Issue
Block a user