diff --git a/src/physics.rs b/src/physics.rs index 18d2456..a8c9744 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -22,8 +22,8 @@ use strafesnet_common::physics::Instruction as PhysicsInputInstruction; //when the physics asks itself what happens next, this is how it's represented #[derive(Debug)] enum PhysicsInternalInstruction{ - CollisionStart(Collision), - CollisionEnd(Collision), + CollisionStart(Collision,model_physics::GigaTime), + CollisionEnd(Collision,model_physics::GigaTime), StrafeTick, ReachWalkTargetVelocity, // Water, @@ -793,9 +793,10 @@ impl TouchingState{ let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh()); collector.collect(minkowski.predict_collision_face_out(&relative_body,collector.time(),contact.face_id).map(|(_face,time)|{ TimedInstruction{ - time, + time:relative_body.time+time.into(), instruction:PhysicsInternalInstruction::CollisionEnd( - Collision::Contact(*contact) + Collision::Contact(*contact), + time ), } })); @@ -806,9 +807,10 @@ impl TouchingState{ let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,hitbox_mesh.transformed_mesh()); collector.collect(minkowski.predict_collision_out(&relative_body,collector.time()).map(|(_face,time)|{ TimedInstruction{ - time, + time:relative_body.time+time.into(), instruction:PhysicsInternalInstruction::CollisionEnd( - Collision::Intersect(*intersect) + Collision::Intersect(*intersect), + time ), } })); @@ -836,6 +838,11 @@ impl Body{ let dt=time-self.time; self.velocity+(self.acceleration*dt).map(|elem|elem.divide().fix_1()) } + pub fn advance_time(&mut self,time:Time){ + self.position=self.extrapolated_position(time); + self.velocity=self.extrapolated_velocity(time); + self.time=time; + } pub fn extrapolated_position_ratio_dt(&self,dt:integer::Ratio)->Planar64Vec3 where // Why? @@ -875,10 +882,10 @@ impl Body{ (self.acceleration.map(|elem|dt*elem)+self.velocity) .map(|elem|elem.divide().fix()) } - pub fn advance_time(&mut self,time:Time){ - self.position=self.extrapolated_position(time); - self.velocity=self.extrapolated_velocity(time); - self.time=time; + pub fn advance_time_ratio_dt(&mut self,dt:model_physics::GigaTime){ + self.position=self.extrapolated_position_ratio_dt(dt); + self.velocity=self.extrapolated_velocity_ratio_dt(dt); + self.time+=dt.into(); } pub fn infinity_dir(&self)->Option{ if self.velocity==vec3::ZERO{ @@ -1274,12 +1281,15 @@ impl PhysicsContext{ let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh()); collector.collect(minkowski.predict_collision_in(relative_body,collector.time()) //temp (?) code to avoid collision loops - .map_or(None,|(face,time)|if time<=state.time{None}else{Some((face,time))}) - .map(|(face,time)| + .map_or(None,|(face,dt)|{ + let time=relative_body.time+dt.into(); + if time<=state.time{None}else{Some((time,face,dt))}}) + .map(|(time,face,dt)| TimedInstruction{ time, instruction:PhysicsInternalInstruction::CollisionStart( - Collision::new(convex_mesh_id,face) + Collision::new(convex_mesh_id,face), + dt ) } ) @@ -1719,17 +1729,20 @@ fn collision_end_intersect( } fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedInstruction){ state.time=ins.time; - let should_advance_body=match ins.instruction{ - PhysicsInternalInstruction::CollisionStart(_) - |PhysicsInternalInstruction::CollisionEnd(_) - |PhysicsInternalInstruction::StrafeTick - |PhysicsInternalInstruction::ReachWalkTargetVelocity=>true, + let (should_advance_body,goober_time)=match ins.instruction{ + PhysicsInternalInstruction::CollisionStart(_,dt) + |PhysicsInternalInstruction::CollisionEnd(_,dt)=>(true,Some(dt)), + PhysicsInternalInstruction::StrafeTick + |PhysicsInternalInstruction::ReachWalkTargetVelocity=>(true,None), }; if should_advance_body{ - state.body.advance_time(state.time); + match goober_time{ + Some(dt)=>state.body.advance_time_ratio_dt(dt), + None=>state.body.advance_time(state.time), + } } match ins.instruction{ - PhysicsInternalInstruction::CollisionStart(collision)=>{ + PhysicsInternalInstruction::CollisionStart(collision,_)=>{ let mode=data.modes.get_mode(state.mode_state.get_mode_id()); match collision{ Collision::Contact(contact)=>collision_start_contact( @@ -1750,7 +1763,7 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim ), } }, - PhysicsInternalInstruction::CollisionEnd(collision)=>match collision{ + PhysicsInternalInstruction::CollisionEnd(collision,_)=>match collision{ Collision::Contact(contact)=>collision_end_contact( &mut state.move_state,&mut state.body,&mut state.touching,&data.models,&data.hitbox_mesh,&state.style,&state.camera,&state.input_state, data.models.contact_attr(contact.model_id), @@ -1967,7 +1980,7 @@ mod test{ let platform_mesh=h0.transformed_mesh(); let minkowski=model_physics::MinkowskiMesh::minkowski_sum(platform_mesh,hitbox_mesh); let collision=minkowski.predict_collision_in(&relative_body,Time::MAX); - assert_eq!(collision.map(|tup|tup.1),expected_collision_time,"Incorrect time of collision"); + assert_eq!(collision.map(|tup|tup.1.into()),expected_collision_time,"Incorrect time of collision"); } fn test_collision_rotated(relative_body:Body,expected_collision_time:Option