Merge branch 'xMAC94x/physics_followup' into 'master'

physics followup, fix arrow problems

See merge request veloren/veloren!1811
This commit is contained in:
Marcel 2021-02-23 02:00:40 +00:00
commit 2fbd382c91
2 changed files with 54 additions and 38 deletions

View File

@ -25,11 +25,12 @@ impl Component for Vel {
/// no need to send it via network /// no need to send it via network
#[derive(Copy, Clone, Default, Debug, PartialEq)] #[derive(Copy, Clone, Default, Debug, PartialEq)]
pub struct PreviousPhysCache { pub struct PreviousPhysCache {
pub velocity: Vec3<f32>, pub velocity_dt: Vec3<f32>,
pub middle: Vec3<f32>, pub center: Vec3<f32>,
///calculates a Sphere over the Entity for quick boundry checking /// Calculates a Sphere over the Entity for quick boundary checking
pub radius: f32, pub collision_boundary: f32,
pub scale: f32, pub scale: f32,
pub scaled_radius: f32,
} }
impl Component for PreviousPhysCache { impl Component for PreviousPhysCache {

View File

@ -46,8 +46,23 @@ fn integrate_forces(dt: f32, mut lv: Vec3<f32>, grav: f32, damp: f32) -> Vec3<f3
lv * linear_damp lv * linear_damp
} }
fn calc_z_limit(
char_state_maybe: Option<&CharacterState>,
collider: Option<&Collider>,
) -> (f32, f32) {
let modifier = if char_state_maybe.map_or(false, |c_s| c_s.is_dodge()) {
0.5
} else {
1.0
};
collider
.map(|c| c.get_z_limits(modifier))
.unwrap_or((-0.5 * modifier, 0.5 * modifier))
}
/// This system applies forces and calculates new positions and velocities. /// This system applies forces and calculates new positions and velocities.
pub struct Sys; pub struct Sys;
impl<'a> System<'a> for Sys { impl<'a> System<'a> for Sys {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
type SystemData = ( type SystemData = (
@ -154,37 +169,48 @@ impl<'a> System<'a> for Sys {
.collect::<Vec<_>>() .collect::<Vec<_>>()
{ {
let _ = previous_phys_cache.insert(entity, PreviousPhysCache { let _ = previous_phys_cache.insert(entity, PreviousPhysCache {
velocity: Vec3::zero(), velocity_dt: Vec3::zero(),
middle: Vec3::zero(), center: Vec3::zero(),
radius: 0.0, collision_boundary: 0.0,
scale: 0.0, scale: 0.0,
scaled_radius: 0.0,
}); });
} }
//Update PreviousPhysCache //Update PreviousPhysCache
for (_, vel, position, mut phys_cache, collider, scale, _, _, _) in ( for (_, vel, position, mut phys_cache, collider, scale, cs, _, _, _) in (
&entities, &entities,
&velocities, &velocities,
&positions, &positions,
&mut previous_phys_cache, &mut previous_phys_cache,
colliders.maybe(), colliders.maybe(),
scales.maybe(), scales.maybe(),
char_states.maybe(),
!&mountings, !&mountings,
!&beams, !&beams,
!&shockwaves, !&shockwaves,
) )
.join() .join()
{ {
phys_cache.velocity = vel.0 * dt.0; let scale = scale.map(|s| s.0).unwrap_or(1.0);
phys_cache.middle = position.0; let z_limits = calc_z_limit(cs, collider);
let z_limits = (z_limits.0 * scale, z_limits.1 * scale);
let half_height = (z_limits.1 - z_limits.0) / 2.0;
let scale_find = scale.map(|s| s.0).unwrap_or(1.0); phys_cache.velocity_dt = vel.0 * dt.0;
let radius_find = collider.map(|c| c.get_radius()).unwrap_or(0.5); let entity_center = position.0 + Vec3::new(0.0, z_limits.0 + half_height, 0.0);
let flat_radius = collider.map(|c| c.get_radius()).unwrap_or(0.5) * scale;
let radius = (flat_radius.powi(2) + half_height.powi(2)).sqrt();
phys_cache.radius = radius_find * scale_find; // Move center to the middle between OLD and OLD+VEL_DT so that we can reduce
phys_cache.scale = scale_find; // the collision_boundary
phys_cache.center = entity_center + phys_cache.velocity_dt / 2.0;
phys_cache.collision_boundary = radius + (phys_cache.velocity_dt / 2.0).magnitude();
phys_cache.scale = scale;
phys_cache.scaled_radius = flat_radius;
} }
drop(guard); drop(guard);
span!(guard, "Apply pushback"); span!(guard, "Apply pushback");
let metrics = ( let metrics = (
&entities, &entities,
@ -220,14 +246,7 @@ impl<'a> System<'a> for Sys {
projectile, projectile,
char_state_maybe, char_state_maybe,
)| { )| {
let modifier = if char_state_maybe.map_or(false, |c_s| c_s.is_dodge()) { let z_limits = calc_z_limit(char_state_maybe, collider);
0.5
} else {
1.0
};
let z_limits = collider
.map(|c| c.get_z_limits(modifier))
.unwrap_or((-0.5 * modifier, 0.5 * modifier));
let mass = mass.map(|m| m.0).unwrap_or(previous_cache.scale); let mass = mass.map(|m| m.0).unwrap_or(previous_cache.scale);
// Resets touch_entities in physics // Resets touch_entities in physics
@ -264,26 +283,21 @@ impl<'a> System<'a> for Sys {
) )
.join() .join()
{ {
let collision_dist = previous_cache.radius + previous_cache_other.radius; let collision_boundary = previous_cache.collision_boundary
+ previous_cache_other.collision_boundary;
if previous_cache if previous_cache
.middle .center
.distance_squared(previous_cache_other.middle) .distance_squared(previous_cache_other.center)
> collision_dist.powi(2) > collision_boundary.powi(2)
|| entity == entity_other || entity == entity_other
{ {
continue; continue;
} }
let modifier_other = let collision_dist =
if char_state_other_maybe.map_or(false, |c_s| c_s.is_dodge()) { previous_cache.scaled_radius + previous_cache_other.scaled_radius;
0.5 let z_limits_other = calc_z_limit(char_state_other_maybe, collider_other);
} else {
1.0
};
let z_limits_other = collider_other
.map(|c| c.get_z_limits(modifier_other))
.unwrap_or((-0.5 * modifier_other, 0.5 * modifier_other));
let mass_other = mass_other let mass_other = mass_other
.map(|m| m.0) .map(|m| m.0)
.unwrap_or(previous_cache_other.scale); .unwrap_or(previous_cache_other.scale);
@ -296,7 +310,8 @@ impl<'a> System<'a> for Sys {
metrics.entity_entity_collision_checks += 1; metrics.entity_entity_collision_checks += 1;
const MIN_COLLISION_DIST: f32 = 0.3; const MIN_COLLISION_DIST: f32 = 0.3;
let increments = ((previous_cache.velocity - previous_cache_other.velocity) let increments = ((previous_cache.velocity_dt
- previous_cache_other.velocity_dt)
.magnitude() .magnitude()
/ MIN_COLLISION_DIST) / MIN_COLLISION_DIST)
.max(1.0) .max(1.0)
@ -306,8 +321,8 @@ impl<'a> System<'a> for Sys {
for i in 0..increments { for i in 0..increments {
let factor = i as f32 * step_delta; let factor = i as f32 * step_delta;
let pos = pos.0 + previous_cache.velocity * factor; let pos = pos.0 + previous_cache.velocity_dt * factor;
let pos_other = pos_other.0 + previous_cache_other.velocity * factor; let pos_other = pos_other.0 + previous_cache_other.velocity_dt * factor;
let diff = pos.xy() - pos_other.xy(); let diff = pos.xy() - pos_other.xy();