mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Use previous position caches for airship collision detection
This commit is contained in:
parent
9cc70e6d22
commit
a76496c339
@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
|
||||
- The menu map now properly handles dragging the map, zooming, and setting the waypoint when hovering icons
|
||||
- Falling through an airship in flight should no longer be possible (although many issues with airship physics remain)
|
||||
|
||||
## [0.11.0] - 2021-09-11
|
||||
|
||||
|
@ -60,6 +60,7 @@ pub struct PreviousPhysCache {
|
||||
pub neighborhood_radius: f32,
|
||||
/// relative p0 and p1 of collider's statium, None if cylinder.
|
||||
pub origins: Option<(Vec2<f32>, Vec2<f32>)>,
|
||||
pub pos: Option<Pos>,
|
||||
pub ori: Quaternion<f32>,
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,7 @@ impl<'a> PhysicsData<'a> {
|
||||
scaled_radius: 0.0,
|
||||
neighborhood_radius: 0.0,
|
||||
origins: None,
|
||||
pos: None,
|
||||
ori: Quaternion::identity(),
|
||||
});
|
||||
}
|
||||
@ -691,7 +692,8 @@ impl<'a> PhysicsData<'a> {
|
||||
// Update cached 'old' physics values to the current values ready for the next
|
||||
// tick
|
||||
prof_span!(guard, "record ori into phys_cache");
|
||||
for (ori, previous_phys_cache, _) in (
|
||||
for (pos, ori, previous_phys_cache, _) in (
|
||||
&write.positions,
|
||||
&write.orientations,
|
||||
&mut write.previous_phys_cache,
|
||||
&read.colliders,
|
||||
@ -700,6 +702,7 @@ impl<'a> PhysicsData<'a> {
|
||||
{
|
||||
// Note: updating ori with the rest of the cache values above was attempted but
|
||||
// it did not work (investigate root cause?)
|
||||
previous_phys_cache.pos = Some(*pos);
|
||||
previous_phys_cache.ori = ori.to_quat();
|
||||
}
|
||||
drop(guard);
|
||||
@ -755,7 +758,7 @@ impl<'a> PhysicsData<'a> {
|
||||
character_state,
|
||||
mut physics_state,
|
||||
pos_vel_ori_defer,
|
||||
_previous_cache,
|
||||
previous_cache,
|
||||
_,
|
||||
)| {
|
||||
let mut land_on_ground = None;
|
||||
@ -1077,6 +1080,16 @@ impl<'a> PhysicsData<'a> {
|
||||
|
||||
// TODO: Cache the matrices here to avoid recomputing
|
||||
|
||||
let transform_last_from = Mat4::<f32>::translation_3d(
|
||||
previous_cache_other.pos.unwrap_or(*pos_other).0
|
||||
- previous_cache.pos.unwrap_or(Pos(wpos)).0,
|
||||
) * Mat4::from(
|
||||
previous_cache_other.ori,
|
||||
) * Mat4::<f32>::translation_3d(
|
||||
voxel_collider.translation,
|
||||
);
|
||||
let transform_last_to = transform_last_from.inverted();
|
||||
|
||||
let transform_from =
|
||||
Mat4::<f32>::translation_3d(pos_other.0 - wpos)
|
||||
* Mat4::from(ori_other.to_quat())
|
||||
@ -1084,8 +1097,11 @@ impl<'a> PhysicsData<'a> {
|
||||
voxel_collider.translation,
|
||||
);
|
||||
let transform_to = transform_from.inverted();
|
||||
|
||||
let ori_last_from = Mat4::from(previous_cache_other.ori);
|
||||
let ori_last_to = ori_last_from.inverted();
|
||||
|
||||
let ori_from = Mat4::from(ori_other.to_quat());
|
||||
let ori_to = ori_from.inverted();
|
||||
|
||||
// The velocity of the collider, taking into account
|
||||
// orientation.
|
||||
@ -1101,8 +1117,8 @@ impl<'a> PhysicsData<'a> {
|
||||
let vel_other = vel_other.0
|
||||
+ (wpos - (pos_other.0 + rpos_last)) / read.dt.0;
|
||||
|
||||
cpos.0 = transform_to.mul_point(Vec3::zero());
|
||||
vel.0 = ori_to.mul_direction(vel.0 - vel_other);
|
||||
cpos.0 = transform_last_to.mul_point(Vec3::zero());
|
||||
vel.0 = ori_last_to.mul_direction(vel.0 - vel_other);
|
||||
let cylinder = (radius, z_min, z_max);
|
||||
box_voxel_collision(
|
||||
cylinder,
|
||||
@ -1112,7 +1128,7 @@ impl<'a> PhysicsData<'a> {
|
||||
transform_to.mul_point(tgt_pos - wpos),
|
||||
&mut vel,
|
||||
&mut physics_state_delta,
|
||||
ori_to.mul_direction(vel_other),
|
||||
ori_last_to.mul_direction(vel_other),
|
||||
&read.dt,
|
||||
was_on_ground,
|
||||
block_snap,
|
||||
@ -1303,7 +1319,6 @@ impl<'a> System<'a> for Sys {
|
||||
}
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
#[allow(clippy::too_many_arguments, clippy::too_many_lines)]
|
||||
fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
||||
cylinder: (f32, f32, f32), // effective collision cylinder
|
||||
@ -1432,14 +1447,13 @@ fn box_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
|
||||
let mut pos_delta = tgt_pos - pos.0;
|
||||
|
||||
// Don't jump too far at once
|
||||
let increments = (pos_delta.map(|e| e.abs()).reduce_partial_max() / 0.3)
|
||||
.ceil()
|
||||
.max(1.0);
|
||||
const MAX_INCREMENTS: usize = 100; // The maximum number of collision tests per tick
|
||||
let increments = ((pos_delta.map(|e| e.abs()).reduce_partial_max() / 0.3).ceil() as usize)
|
||||
.clamped(1, MAX_INCREMENTS);
|
||||
let old_pos = pos.0;
|
||||
|
||||
for _ in 0..increments as usize {
|
||||
for _ in 0..increments {
|
||||
const MAX_ATTEMPTS: usize = 16;
|
||||
pos.0 += pos_delta / increments;
|
||||
pos.0 += pos_delta / increments as f32;
|
||||
|
||||
let try_colliding_block = |pos: &Pos| {
|
||||
// Calculate the player's AABB
|
||||
|
Loading…
Reference in New Issue
Block a user