Compare commits
6 Commits
master
...
debug-bug3
Author | SHA1 | Date | |
---|---|---|---|
54e82ee1a6 | |||
dcda00f18d | |||
5108d58847 | |||
84111d752c | |||
e6284ae4dc | |||
99f16706c6 |
engine/physics/src
@ -61,6 +61,7 @@ impl<T> Body<T>
|
||||
self.velocity+(self.acceleration*dt).map(|elem|elem.divide().clamp_1())
|
||||
}
|
||||
pub fn advance_time(&mut self,time:Time<T>){
|
||||
println!("advance_time");
|
||||
self.position=self.extrapolated_position(time);
|
||||
self.velocity=self.extrapolated_velocity(time);
|
||||
self.time=time;
|
||||
@ -102,6 +103,7 @@ impl<T> Body<T>
|
||||
self.acceleration.map(|elem|(dt*elem).divide().clamp())+self.velocity
|
||||
}
|
||||
pub fn advance_time_ratio_dt(&mut self,dt:crate::model::GigaTime){
|
||||
println!("advance_time_ratio_dt");
|
||||
self.position=self.extrapolated_position_ratio_dt(dt);
|
||||
self.velocity=self.extrapolated_velocity_ratio_dt(dt);
|
||||
self.time+=dt.into();
|
||||
|
@ -4,6 +4,7 @@ use crate::physics::{Time,Body};
|
||||
|
||||
use core::ops::Bound;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Transition<M:MeshQuery>{
|
||||
Miss,
|
||||
Next(FEV<M>,GigaTime),
|
||||
@ -76,6 +77,8 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
||||
M::Face:Copy,
|
||||
M::Edge:Copy,
|
||||
M::Vert:Copy,
|
||||
M:std::fmt::Debug,
|
||||
F:std::fmt::Display,
|
||||
F:core::ops::Mul<Fixed<1,32>,Output=Fixed<4,128>>,
|
||||
<F as core::ops::Mul<Fixed<1,32>>>::Output:core::iter::Sum,
|
||||
M::Offset:core::ops::Sub<<F as std::ops::Mul<Fixed<1,32>>>::Output>,
|
||||
@ -90,10 +93,15 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
||||
//n=face.normal d=face.dot
|
||||
//n.a t^2+n.v t+n.p-d==0
|
||||
let (n,d)=mesh.face_nd(face_id);
|
||||
println!("Face n={} d={}",n,d);
|
||||
//TODO: use higher precision d value?
|
||||
//use the mesh transform translation instead of baking it into the d value.
|
||||
for dt in Fixed::<4,128>::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
|
||||
if low(&lower_bound,&dt)&&upp(&dt,&upper_bound)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
|
||||
let low=low(&lower_bound,&dt);
|
||||
let upp=upp(&dt,&upper_bound);
|
||||
let into=n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative();
|
||||
println!("dt={} low={low} upp={upp} into={into}",dt.divide());
|
||||
if low&&upp&&into{
|
||||
upper_bound=Bound::Included(dt);
|
||||
best_transition=Transition::Hit(face_id,dt);
|
||||
break;
|
||||
@ -127,10 +135,16 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
||||
let face_n=mesh.face_nd(edge_face_id).0;
|
||||
//edge_n gets parity from the order of edge_faces
|
||||
let n=face_n.cross(edge_n)*((i as i64)*2-1);
|
||||
let d=n.dot(delta_pos).wrap_4();
|
||||
println!("Edge Face={:?} boundary_n={} boundary_d={}",edge_face_id,n,d>>1);
|
||||
//WARNING yada yada d *2
|
||||
//wrap for speed
|
||||
for dt in Fixed::<4,128>::zeroes2(n.dot(delta_pos).wrap_4(),n.dot(body.velocity).wrap_4()*2,n.dot(body.acceleration).wrap_4()){
|
||||
if low(&lower_bound,&dt)&&upp(&dt,&upper_bound)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
|
||||
for dt in Fixed::<4,128>::zeroes2(d,n.dot(body.velocity).wrap_4()*2,n.dot(body.acceleration).wrap_4()){
|
||||
let low=low(&lower_bound,&dt);
|
||||
let upp=upp(&dt,&upper_bound);
|
||||
let into=n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative();
|
||||
println!("dt={} low={low} upp={upp} into={into}",dt.divide());
|
||||
if low&&upp&&into{
|
||||
upper_bound=Bound::Included(dt);
|
||||
best_transition=Transition::Next(FEV::Face(edge_face_id),dt);
|
||||
break;
|
||||
@ -174,8 +188,11 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
||||
pub fn crawl(mut self,mesh:&M,relative_body:&Body,lower_bound:Bound<&Time>,upper_bound:Bound<&Time>)->CrawlResult<M>{
|
||||
let mut lower_bound=lower_bound.map(|&t|into_giga_time(t,relative_body.time));
|
||||
let upper_bound=upper_bound.map(|&t|into_giga_time(t,relative_body.time));
|
||||
println!("crawl begin={self:?}");
|
||||
for _ in 0..20{
|
||||
match self.next_transition(mesh,relative_body,lower_bound,upper_bound){
|
||||
let transition=self.next_transition(mesh,relative_body,lower_bound,upper_bound);
|
||||
println!("transition={transition:?}");
|
||||
match transition{
|
||||
Transition::Miss=>return CrawlResult::Miss(self),
|
||||
Transition::Next(next_fev,next_time)=>(self,lower_bound)=(next_fev,Bound::Included(next_time)),
|
||||
Transition::Hit(face,time)=>return CrawlResult::Hit(face,time),
|
||||
|
@ -76,9 +76,9 @@ struct Face{
|
||||
#[derive(Debug)]
|
||||
struct Vert(Planar64Vec3);
|
||||
pub trait MeshQuery{
|
||||
type Face:Copy;
|
||||
type Edge:Copy+DirectedEdge;
|
||||
type Vert:Copy;
|
||||
type Face:Copy+std::fmt::Debug;
|
||||
type Edge:Copy+DirectedEdge+std::fmt::Debug;
|
||||
type Vert:Copy+std::fmt::Debug;
|
||||
// Vertex must be Planar64Vec3 because it represents an actual position
|
||||
type Normal;
|
||||
type Offset;
|
||||
@ -759,7 +759,9 @@ impl MinkowskiMesh<'_>{
|
||||
})
|
||||
}
|
||||
pub fn predict_collision_in(&self,relative_body:&Body,range:impl RangeBounds<Time>)->Option<(MinkowskiFace,GigaTime)>{
|
||||
println!("@@@BEGIN SETUP@@@");
|
||||
self.closest_fev_not_inside(*relative_body,range.start_bound()).and_then(|fev|{
|
||||
println!("@@@BEGIN REAL CRAWL@@@");
|
||||
//continue forwards along the body parabola
|
||||
fev.crawl(self,relative_body,range.start_bound(),range.end_bound()).hit()
|
||||
})
|
||||
|
@ -28,6 +28,7 @@ pub enum InternalInstruction{
|
||||
CollisionStart(Collision,model_physics::GigaTime),
|
||||
CollisionEnd(Collision,model_physics::GigaTime),
|
||||
StrafeTick,
|
||||
// TODO: add GigaTime to ReachWalkTargetVelocity
|
||||
ReachWalkTargetVelocity,
|
||||
// Water,
|
||||
}
|
||||
@ -1130,10 +1131,11 @@ impl PhysicsData{
|
||||
|
||||
//this is the one who asks
|
||||
fn next_instruction_internal(state:&PhysicsState,data:&PhysicsData,time_limit:Time)->Option<TimedInstruction<InternalInstruction,Time>>{
|
||||
println!("==== next_instruction_internal ====");
|
||||
//JUST POLLING!!! NO MUTATION
|
||||
let mut collector=instruction::InstructionCollector::new(time_limit);
|
||||
|
||||
collector.collect(state.next_move_instruction());
|
||||
// collector.collect(state.next_move_instruction());
|
||||
|
||||
//check for collision ends
|
||||
state.touching.predict_collision_end(&mut collector,&data.models,&data.hitbox_mesh,&state.body,state.time);
|
||||
@ -1145,6 +1147,7 @@ impl PhysicsData{
|
||||
//let relative_body=state.body.relative_to(&Body::ZERO);
|
||||
let relative_body=&state.body;
|
||||
data.bvh.sample_aabb(&aabb,&mut |&convex_mesh_id|{
|
||||
println!("Sampling object id={:?}",convex_mesh_id.model_id);
|
||||
//no checks are needed because of the time limits.
|
||||
let model_mesh=data.models.mesh(convex_mesh_id);
|
||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh());
|
||||
@ -1260,6 +1263,7 @@ fn set_velocity_cull(body:&mut Body,touching:&mut TouchingState,models:&PhysicsM
|
||||
let n=contact_normal(models,hitbox_mesh,contact);
|
||||
let r=n.dot(v).is_positive();
|
||||
if r{
|
||||
println!("culled {:?}",contact.model_id);
|
||||
culled=true;
|
||||
}
|
||||
!r
|
||||
@ -1627,6 +1631,7 @@ fn collision_end_contact(
|
||||
_attr:&gameplay_attributes::ContactAttributes,
|
||||
contact:ContactCollision,
|
||||
){
|
||||
println!("collision_end {:?}",contact.model_id);
|
||||
touching.remove(&Collision::Contact(contact));//remove contact before calling contact_constrain_acceleration
|
||||
//check ground
|
||||
//TODO do better
|
||||
@ -1674,18 +1679,16 @@ fn collision_end_intersect(
|
||||
}
|
||||
}
|
||||
fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedInstruction<InternalInstruction,Time>){
|
||||
println!("\n==== atomic_internal_instruction ====");
|
||||
state.time=ins.time;
|
||||
let (should_advance_body,goober_time)=match ins.instruction{
|
||||
match ins.instruction{
|
||||
// collisions advance the body precisely
|
||||
InternalInstruction::CollisionStart(_,dt)
|
||||
|InternalInstruction::CollisionEnd(_,dt)=>(true,Some(dt)),
|
||||
InternalInstruction::StrafeTick
|
||||
|InternalInstruction::ReachWalkTargetVelocity=>(true,None),
|
||||
};
|
||||
if should_advance_body{
|
||||
match goober_time{
|
||||
Some(dt)=>state.body.advance_time_ratio_dt(dt),
|
||||
None=>state.body.advance_time(state.time),
|
||||
}
|
||||
|InternalInstruction::CollisionEnd(_,dt)=>state.body.advance_time_ratio_dt(dt),
|
||||
// this advances imprecisely
|
||||
InternalInstruction::ReachWalkTargetVelocity=>state.body.advance_time(state.time),
|
||||
// strafe tick decides for itself whether to advance the body.
|
||||
InternalInstruction::StrafeTick=>(),
|
||||
}
|
||||
match ins.instruction{
|
||||
InternalInstruction::CollisionStart(collision,_)=>{
|
||||
@ -1732,6 +1735,8 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
||||
let masked_controls=strafe_settings.mask(controls);
|
||||
let control_dir=state.style.get_control_dir(masked_controls);
|
||||
if control_dir!=vec3::ZERO{
|
||||
// manually advance time
|
||||
state.body.advance_time(state.time);
|
||||
let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
|
||||
if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE).divide().wrap_1()){
|
||||
//this is wrong but will work ig
|
||||
|
Loading…
x
Reference in New Issue
Block a user