From 198cc7e75a94cef722c2a2212be23ab1199c4c3f Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 16 Mar 2021 23:34:49 -0400 Subject: [PATCH] Remove extra instrumentation and the old voxel collider loop --- Cargo.lock | 1 - common/sys/Cargo.toml | 2 +- common/sys/src/phys.rs | 469 ++++++++++++++--------------------------- 3 files changed, 162 insertions(+), 310 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d24ecafc5..bf32258ed6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5634,7 +5634,6 @@ dependencies = [ "bincode", "hashbrown", "indexmap", - "inline_tweak", "rand 0.8.3", "rayon", "scopeguard", diff --git a/common/sys/Cargo.toml b/common/sys/Cargo.toml index 4bdf3863e3..79433316c1 100644 --- a/common/sys/Cargo.toml +++ b/common/sys/Cargo.toml @@ -42,4 +42,4 @@ bincode = { version = "1.3.1", optional = true } plugin-api = { package = "veloren-plugin-api", path = "../../plugin/api", optional = true } # Tweak running code - inline_tweak = { version = "1.0.8", features = ["release_tweak"] } +#inline_tweak = { version = "1.0.8", features = ["release_tweak"] } diff --git a/common/sys/src/phys.rs b/common/sys/src/phys.rs index a84400050a..e36d545e4f 100644 --- a/common/sys/src/phys.rs +++ b/common/sys/src/phys.rs @@ -451,8 +451,6 @@ impl<'a> PhysicsData<'a> { ref read, ref write, } = self; - // NOTE: assumes that entity max radius * 2 + max velocity per tick is less than - // half a chunk (16 blocks) // NOTE: i32 places certain constraints on how far out collision works // NOTE: uses the radius of the entity and their current position rather than // the radius of their bounding sphere for the current frame of movement @@ -624,7 +622,6 @@ impl<'a> PhysicsData<'a> { _previous_cache, _, )| { - prof_span!(_guard, "entity"); let mut land_on_ground = None; // Defer the writes of positions and velocities to allow an inner loop over // terrain-like entities @@ -784,329 +781,185 @@ impl<'a> PhysicsData<'a> { }, } - let use_grid = inline_tweak::release_tweak!(true); - common_base::plot!("use new version", if use_grid { 1.0 } else { 0.0 }); - if use_grid { - // Compute center and radius of tick path bounding sphere for the entity - // for broad checks of whether it will collide with a voxel collider - let path_sphere = { - // TODO: duplicated with maintain_pushback_cache, make a common function - // to call to compute all this info? - let z_limits = calc_z_limit(character_state, Some(collider)); - let z_limits = (z_limits.0 * scale, z_limits.1 * scale); - let half_height = (z_limits.1 - z_limits.0) / 2.0; + // Compute center and radius of tick path bounding sphere for the entity + // for broad checks of whether it will collide with a voxel collider + let path_sphere = { + // TODO: duplicated with maintain_pushback_cache, make a common function + // to call to compute all this info? + let z_limits = calc_z_limit(character_state, Some(collider)); + let z_limits = (z_limits.0 * scale, z_limits.1 * scale); + let half_height = (z_limits.1 - z_limits.0) / 2.0; - let entity_center = pos.0 + (z_limits.0 + half_height) * Vec3::unit_z(); - let path_center = entity_center + pos_delta / 2.0; + let entity_center = pos.0 + (z_limits.0 + half_height) * Vec3::unit_z(); + let path_center = entity_center + pos_delta / 2.0; - let flat_radius = collider.get_radius() * scale; - let radius = (flat_radius.powi(2) + half_height.powi(2)).sqrt(); - let path_bounding_radius = radius + (pos_delta / 2.0).magnitude(); + let flat_radius = collider.get_radius() * scale; + let radius = (flat_radius.powi(2) + half_height.powi(2)).sqrt(); + let path_bounding_radius = radius + (pos_delta / 2.0).magnitude(); - Sphere { - center: path_center, - radius: path_bounding_radius, - } - }; - // Collide with terrain-like entities - let aabr = { - let center = path_sphere.center.xy().map(|e| e as i32); - let radius = path_sphere.radius.ceil() as i32; - // From conversion of center above - const CENTER_TRUNCATION_ERROR: i32 = 1; - let max_dist = radius + CENTER_TRUNCATION_ERROR; + Sphere { + center: path_center, + radius: path_bounding_radius, + } + }; + // Collide with terrain-like entities + let aabr = { + let center = path_sphere.center.xy().map(|e| e as i32); + let radius = path_sphere.radius.ceil() as i32; + // From conversion of center above + const CENTER_TRUNCATION_ERROR: i32 = 1; + let max_dist = radius + CENTER_TRUNCATION_ERROR; - Aabr { - min: center - max_dist, - max: center + max_dist, - } - }; - voxel_collider_spatial_grid - .in_aabr(aabr) - .filter_map(|entity| { - positions - .get(entity) - .zip(velocities.get(entity)) - .zip(previous_phys_cache.get(entity)) - .zip(read.colliders.get(entity)) - .zip(orientations.get(entity)) - .map(|((((pos, vel), previous_cache), collider), ori)| { - (entity, pos, vel, previous_cache, collider, ori) - }) - }) - .for_each( - |( - entity_other, - pos_other, - vel_other, - previous_cache_other, - collider_other, - ori_other, - )| { - if entity == entity_other { + Aabr { + min: center - max_dist, + max: center + max_dist, + } + }; + voxel_collider_spatial_grid + .in_aabr(aabr) + .filter_map(|entity| { + positions + .get(entity) + .zip(velocities.get(entity)) + .zip(previous_phys_cache.get(entity)) + .zip(read.colliders.get(entity)) + .zip(orientations.get(entity)) + .map(|((((pos, vel), previous_cache), collider), ori)| { + (entity, pos, vel, previous_cache, collider, ori) + }) + }) + .for_each( + |( + entity_other, + pos_other, + vel_other, + previous_cache_other, + collider_other, + ori_other, + )| { + if entity == entity_other { + return; + } + + let voxel_id = if let Collider::Voxel { id } = collider_other { + id + } else { + return; + }; + + // use bounding cylinder regardless of our collider + // TODO: extract point-terrain collision above to its own + // function + let radius = collider.get_radius(); + let (z_min, z_max) = collider.get_z_limits(1.0); + + let radius = radius.min(0.45) * scale; + let z_min = z_min * scale; + let z_max = z_max.clamped(1.2, 1.95) * scale; + + if let Some(voxel_collider) = + VOXEL_COLLIDER_MANIFEST.read().colliders.get(voxel_id) + { + // TODO: cache/precompute sphere? + let voxel_sphere = voxel_collider_bounding_sphere( + voxel_collider, + pos_other, + ori_other, + ); + // Early check + if voxel_sphere.center.distance_squared(path_sphere.center) + > (voxel_sphere.radius + path_sphere.radius).powi(2) + { return; } - let voxel_id = if let Collider::Voxel { id } = collider_other { - id - } else { - return; - }; + let mut physics_state_delta = physics_state.clone(); + // deliberately don't use scale yet here, because the + // 11.0/0.8 thing is + // in the comp::Scale for visual reasons + let mut cpos = *pos; + let wpos = cpos.0; - // use bounding cylinder regardless of our collider - // TODO: extract point-terrain collision above to its own - // function - let radius = collider.get_radius(); - let (z_min, z_max) = collider.get_z_limits(1.0); + // TODO: Cache the matrices here to avoid recomputing - let radius = radius.min(0.45) * scale; - let z_min = z_min * scale; - let z_max = z_max.clamped(1.2, 1.95) * scale; - - if let Some(voxel_collider) = - VOXEL_COLLIDER_MANIFEST.read().colliders.get(voxel_id) - { - prof_span!(_guard, "collide with voxel"); - // TODO: cache/precompute sphere? - let voxel_sphere = voxel_collider_bounding_sphere( - voxel_collider, - pos_other, - ori_other, - ); - // Early check - if voxel_sphere.center.distance_squared(path_sphere.center) - > (voxel_sphere.radius + path_sphere.radius).powi(2) - { - return; - } - - let mut physics_state_delta = physics_state.clone(); - // deliberately don't use scale yet here, because the - // 11.0/0.8 thing is - // in the comp::Scale for visual reasons - let mut cpos = *pos; - let wpos = cpos.0; - - // TODO: Cache the matrices here to avoid recomputing - - let transform_from = - Mat4::::translation_3d(pos_other.0 - wpos) - * Mat4::from(ori_other.to_quat()) - * Mat4::::translation_3d( - voxel_collider.translation, - ); - let transform_to = transform_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. - let wpos_rel = (Mat4::::translation_3d(pos_other.0) + let transform_from = + Mat4::::translation_3d(pos_other.0 - wpos) * Mat4::from(ori_other.to_quat()) * Mat4::::translation_3d( voxel_collider.translation, - )) - .inverted() - .mul_point(wpos); - let wpos_last = (Mat4::::translation_3d(pos_other.0) - * Mat4::from(previous_cache_other.ori) - * Mat4::::translation_3d( - voxel_collider.translation, - )) - .mul_point(wpos_rel); - let vel_other = - vel_other.0 + (wpos - wpos_last) / read.dt.0; + ); + let transform_to = transform_from.inverted(); + let ori_from = Mat4::from(ori_other.to_quat()); + let ori_to = ori_from.inverted(); - cpos.0 = transform_to.mul_point(Vec3::zero()); - vel.0 = ori_to.mul_direction(vel.0 - vel_other); - let cylinder = (radius, z_min, z_max); - box_voxel_collision( - cylinder, - &voxel_collider.dyna, - entity, - &mut cpos, - transform_to.mul_point(tgt_pos - wpos), - &mut vel, - &mut physics_state_delta, - ori_to.mul_direction(vel_other), - &read.dt, - was_on_ground, - block_snap, - climbing, - |entity, vel| { - land_on_ground = Some(( - entity, - Vel(ori_from.mul_direction(vel.0)), - )); - }, - ); - - cpos.0 = transform_from.mul_point(cpos.0) + wpos; - vel.0 = ori_from.mul_direction(vel.0) + vel_other; - tgt_pos = cpos.0; - - // union in the state updates, so that the state isn't just - // based on the most - // recent terrain that collision was attempted with - if physics_state_delta.on_ground { - physics_state.ground_vel = vel_other; - } - physics_state.on_ground |= physics_state_delta.on_ground; - physics_state.on_ceiling |= physics_state_delta.on_ceiling; - physics_state.on_wall = - physics_state.on_wall.or_else(|| { - physics_state_delta - .on_wall - .map(|dir| ori_from.mul_direction(dir)) - }); - physics_state - .touch_entities - .append(&mut physics_state_delta.touch_entities); - physics_state.in_liquid = match ( - physics_state.in_liquid, - physics_state_delta.in_liquid, - ) { - // this match computes `x <|> y <|> liftA2 max x y` - (Some(x), Some(y)) => Some(x.max(y)), - (x @ Some(_), _) => x, - (_, y @ Some(_)) => y, - _ => None, - }; - } - }, - ); - } else { - for ( - entity_other, - pos_other, - vel_other, - previous_cache_other, - collider_other, - ori_other, - ) in ( - &read.entities, - positions, - velocities, - previous_phys_cache, - &read.colliders, - orientations, - ) - .join() - { - // TODO: terrain-collider-size aware broadphase - /*let collision_boundary = previous_cache.collision_boundary - + previous_cache_other.collision_boundary; - if previous_cache - .center - .distance_squared(previous_cache_other.center) - > collision_boundary.powi(2) - { - continue; - }*/ - if entity == entity_other { - continue; - } - - let voxel_id = if let Collider::Voxel { id } = collider_other { - id - } else { - continue; - }; - - // use bounding cylinder regardless of our collider - // TODO: extract point-terrain collision above to its own function - let radius = collider.get_radius(); - let (z_min, z_max) = collider.get_z_limits(1.0); - - let radius = radius.min(0.45) * scale; - let z_min = z_min * scale; - let z_max = z_max.clamped(1.2, 1.95) * scale; - - if let Some(voxel_collider) = - VOXEL_COLLIDER_MANIFEST.read().colliders.get(voxel_id) - { - let mut physics_state_delta = physics_state.clone(); - // deliberately don't use scale yet here, because the 11.0/0.8 - // thing is in the comp::Scale for visual reasons - let mut cpos = *pos; - let wpos = cpos.0; - - // TODO: Cache the matrices here to avoid recomputing - - let transform_from = - Mat4::::translation_3d(pos_other.0 - wpos) + // The velocity of the collider, taking into account + // orientation. + let wpos_rel = (Mat4::::translation_3d(pos_other.0) * Mat4::from(ori_other.to_quat()) - * Mat4::::translation_3d(voxel_collider.translation); - let transform_to = transform_from.inverted(); - let ori_from = Mat4::from(ori_other.to_quat()); - let ori_to = ori_from.inverted(); + * Mat4::::translation_3d(voxel_collider.translation)) + .inverted() + .mul_point(wpos); + let wpos_last = (Mat4::::translation_3d(pos_other.0) + * Mat4::from(previous_cache_other.ori) + * Mat4::::translation_3d(voxel_collider.translation)) + .mul_point(wpos_rel); + let vel_other = vel_other.0 + (wpos - wpos_last) / read.dt.0; - // The velocity of the collider, taking into account orientation. - let wpos_rel = (Mat4::::translation_3d(pos_other.0) - * Mat4::from(ori_other.to_quat()) - * Mat4::::translation_3d(voxel_collider.translation)) - .inverted() - .mul_point(wpos); - let wpos_last = (Mat4::::translation_3d(pos_other.0) - * Mat4::from(previous_cache_other.ori) - * Mat4::::translation_3d(voxel_collider.translation)) - .mul_point(wpos_rel); - let vel_other = vel_other.0 + (wpos - wpos_last) / read.dt.0; + cpos.0 = transform_to.mul_point(Vec3::zero()); + vel.0 = ori_to.mul_direction(vel.0 - vel_other); + let cylinder = (radius, z_min, z_max); + box_voxel_collision( + cylinder, + &voxel_collider.dyna, + entity, + &mut cpos, + transform_to.mul_point(tgt_pos - wpos), + &mut vel, + &mut physics_state_delta, + ori_to.mul_direction(vel_other), + &read.dt, + was_on_ground, + block_snap, + climbing, + |entity, vel| { + land_on_ground = + Some((entity, Vel(ori_from.mul_direction(vel.0)))); + }, + ); - cpos.0 = transform_to.mul_point(Vec3::zero()); - vel.0 = ori_to.mul_direction(vel.0 - vel_other); - let cylinder = (radius, z_min, z_max); - box_voxel_collision( - cylinder, - &voxel_collider.dyna, - entity, - &mut cpos, - transform_to.mul_point(tgt_pos - wpos), - &mut vel, - &mut physics_state_delta, - ori_to.mul_direction(vel_other), - &read.dt, - was_on_ground, - block_snap, - climbing, - |entity, vel| { - land_on_ground = - Some((entity, Vel(ori_from.mul_direction(vel.0)))); - }, - ); + cpos.0 = transform_from.mul_point(cpos.0) + wpos; + vel.0 = ori_from.mul_direction(vel.0) + vel_other; + tgt_pos = cpos.0; - cpos.0 = transform_from.mul_point(cpos.0) + wpos; - vel.0 = ori_from.mul_direction(vel.0) + vel_other; - tgt_pos = cpos.0; - - // union in the state updates, so that the state isn't just based on - // the most recent terrain that collision was attempted with - if physics_state_delta.on_ground { - physics_state.ground_vel = vel_other; + // union in the state updates, so that the state isn't just + // based on the most + // recent terrain that collision was attempted with + if physics_state_delta.on_ground { + physics_state.ground_vel = vel_other; + } + physics_state.on_ground |= physics_state_delta.on_ground; + physics_state.on_ceiling |= physics_state_delta.on_ceiling; + physics_state.on_wall = physics_state.on_wall.or_else(|| { + physics_state_delta + .on_wall + .map(|dir| ori_from.mul_direction(dir)) + }); + physics_state + .touch_entities + .append(&mut physics_state_delta.touch_entities); + physics_state.in_liquid = match ( + physics_state.in_liquid, + physics_state_delta.in_liquid, + ) { + // this match computes `x <|> y <|> liftA2 max x y` + (Some(x), Some(y)) => Some(x.max(y)), + (x @ Some(_), _) => x, + (_, y @ Some(_)) => y, + _ => None, + }; } - physics_state.on_ground |= physics_state_delta.on_ground; - physics_state.on_ceiling |= physics_state_delta.on_ceiling; - physics_state.on_wall = physics_state.on_wall.or_else(|| { - physics_state_delta - .on_wall - .map(|dir| ori_from.mul_direction(dir)) - }); - physics_state - .touch_entities - .append(&mut physics_state_delta.touch_entities); - physics_state.in_liquid = match ( - physics_state.in_liquid, - physics_state_delta.in_liquid, - ) { - // this match computes `x <|> y <|> liftA2 max x y` - (Some(x), Some(y)) => Some(x.max(y)), - (x @ Some(_), _) => x, - (_, y @ Some(_)) => y, - _ => None, - }; - } - } - } + }, + ); if tgt_pos != pos.0 { pos_vel_defer.pos = Some(Pos(tgt_pos));