Compare commits
4 Commits
master
...
minkowksi-
Author | SHA1 | Date | |
---|---|---|---|
05999f73f4 | |||
dcdf57b389 | |||
b8a0175686 | |||
2a5f610650 |
engine/physics/src
@ -757,7 +757,7 @@ impl MinkowskiMesh<'_>{
|
|||||||
.map(|(face,time)|(face,-time))
|
.map(|(face,time)|(face,-time))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn predict_collision_face_out(&self,relative_body:&Body,Range{start:start_time,end:time_limit}:Range<Time>,contact_face_id:MinkowskiFace)->Option<(MinkowskiEdge,GigaTime)>{
|
pub fn predict_collision_face_out(&self,relative_body:&Body,Range{start:start_time,end:time_limit}:Range<Time>,contact_face_id:MinkowskiFace)->Option<(MinkowskiDirectedEdge,GigaTime)>{
|
||||||
//no algorithm needed, there is only one state and two cases (Edge,None)
|
//no algorithm needed, there is only one state and two cases (Edge,None)
|
||||||
//determine when it passes an edge ("sliding off" case)
|
//determine when it passes an edge ("sliding off" case)
|
||||||
let start_time={
|
let start_time={
|
||||||
@ -787,7 +787,7 @@ impl MinkowskiMesh<'_>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
best_edge.map(|e|(e.as_undirected(),best_time))
|
best_edge.map(|e|(e,best_time))
|
||||||
}
|
}
|
||||||
fn infinity_in(&self,infinity_body:Body)->Option<(MinkowskiFace,GigaTime)>{
|
fn infinity_in(&self,infinity_body:Body)->Option<(MinkowskiFace,GigaTime)>{
|
||||||
let infinity_fev=self.infinity_fev(-infinity_body.velocity,infinity_body.position);
|
let infinity_fev=self.infinity_fev(-infinity_body.velocity,infinity_body.position);
|
||||||
|
@ -26,6 +26,8 @@ use strafesnet_common::physics::{Instruction,MouseInstruction,ModeInstruction,Mi
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InternalInstruction{
|
pub enum InternalInstruction{
|
||||||
CollisionStart(Collision,model_physics::GigaTime),
|
CollisionStart(Collision,model_physics::GigaTime),
|
||||||
|
// transfer to a flush minkowski face
|
||||||
|
CollisionTransfer(ContactCollision,model_physics::MinkowskiFace),
|
||||||
CollisionEnd(Collision,model_physics::GigaTime),
|
CollisionEnd(Collision,model_physics::GigaTime),
|
||||||
StrafeTick,
|
StrafeTick,
|
||||||
ReachWalkTargetVelocity,
|
ReachWalkTargetVelocity,
|
||||||
@ -785,19 +787,39 @@ impl TouchingState{
|
|||||||
crate::push_solve::push_solve(&contacts,acceleration)
|
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){
|
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.relative_to(&Body::ZERO);
|
||||||
let relative_body=body;
|
let relative_body=body;
|
||||||
for contact in &self.contacts{
|
for contact in &self.contacts{
|
||||||
//detect face slide off
|
//detect face slide off
|
||||||
let model_mesh=models.contact_mesh(contact);
|
let model_mesh=models.contact_mesh(contact);
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh());
|
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)|{
|
collector.collect(minkowski.predict_collision_face_out(&relative_body,start_time..collector.time(),contact.face_id).map(|(out_edge,time)|{
|
||||||
TimedInstruction{
|
// TODO: determine if this code should go inside predict_collision_face_out
|
||||||
time:relative_body.time+time.into(),
|
// the face across may be left or right depending on the directed edge parity
|
||||||
instruction:InternalInstruction::CollisionEnd(
|
let &[f0,f1]=minkowski.edge_faces(out_edge.as_undirected()).as_ref();
|
||||||
Collision::Contact(*contact),
|
let (f0n,_f0d)=minkowski.face_nd(f0);
|
||||||
time
|
let (f1n,_f1d)=minkowski.face_nd(f1);
|
||||||
),
|
// are they exactly flush
|
||||||
|
if f0n.cross(f1n)==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,
|
||||||
|
if out_edge.parity(){f1}else{f0},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
TimedInstruction{
|
||||||
|
time:relative_body.time+time.into(),
|
||||||
|
instruction:InternalInstruction::CollisionEnd(
|
||||||
|
Collision::Contact(*contact),
|
||||||
|
time
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -1656,6 +1678,7 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
|||||||
|InternalInstruction::CollisionEnd(_,dt)=>(true,Some(dt)),
|
|InternalInstruction::CollisionEnd(_,dt)=>(true,Some(dt)),
|
||||||
InternalInstruction::StrafeTick
|
InternalInstruction::StrafeTick
|
||||||
|InternalInstruction::ReachWalkTargetVelocity=>(true,None),
|
|InternalInstruction::ReachWalkTargetVelocity=>(true,None),
|
||||||
|
InternalInstruction::CollisionTransfer(..)=>(false,None),
|
||||||
};
|
};
|
||||||
if should_advance_body{
|
if should_advance_body{
|
||||||
match goober_time{
|
match goober_time{
|
||||||
@ -1700,6 +1723,15 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
|||||||
state.time
|
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=>{
|
InternalInstruction::StrafeTick=>{
|
||||||
//TODO make this less huge
|
//TODO make this less huge
|
||||||
if let Some(strafe_settings)=&state.style.strafe{
|
if let Some(strafe_settings)=&state.style.strafe{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user