First round deleting the component sets.
This commit is contained in:
committed by
Sébastien Crozet
parent
ee679427cd
commit
2b1374c596
@@ -3,15 +3,14 @@ use super::{
|
||||
};
|
||||
use crate::geometry::broad_phase_multi_sap::SAPProxyIndex;
|
||||
use crate::geometry::{
|
||||
ColliderBroadPhaseData, ColliderChanges, ColliderHandle, ColliderPosition, ColliderShape,
|
||||
ColliderBroadPhaseData, ColliderChanges, ColliderHandle, ColliderPosition, ColliderSet,
|
||||
ColliderShape,
|
||||
};
|
||||
use crate::math::Real;
|
||||
use crate::utils::IndexMut2;
|
||||
use parry::bounding_volume::BoundingVolume;
|
||||
use parry::utils::hashmap::HashMap;
|
||||
|
||||
use crate::data::{BundleSet, ComponentSet, ComponentSetMut};
|
||||
|
||||
/// A broad-phase combining a Hierarchical Grid and Sweep-and-Prune.
|
||||
///
|
||||
/// The basic Sweep-and-Prune (SAP) algorithm has one significant flaws:
|
||||
@@ -435,19 +434,14 @@ impl BroadPhase {
|
||||
}
|
||||
|
||||
/// Updates the broad-phase, taking into account the new collider positions.
|
||||
pub fn update<Colliders>(
|
||||
pub fn update(
|
||||
&mut self,
|
||||
prediction_distance: Real,
|
||||
colliders: &mut Colliders,
|
||||
colliders: &mut ColliderSet,
|
||||
modified_colliders: &[ColliderHandle],
|
||||
removed_colliders: &[ColliderHandle],
|
||||
events: &mut Vec<BroadPhasePairEvent>,
|
||||
) where
|
||||
Colliders: ComponentSetMut<ColliderBroadPhaseData>
|
||||
+ ComponentSet<ColliderChanges>
|
||||
+ ComponentSet<ColliderPosition>
|
||||
+ ComponentSet<ColliderShape>,
|
||||
{
|
||||
) {
|
||||
// Phase 1: pre-delete the collisions that have been deleted.
|
||||
self.handle_removed_colliders(removed_colliders);
|
||||
|
||||
@@ -457,30 +451,22 @@ impl BroadPhase {
|
||||
for handle in modified_colliders {
|
||||
// NOTE: we use `get` because the collider may no longer
|
||||
// exist if it has been removed.
|
||||
let co_changes: Option<&ColliderChanges> = colliders.get(handle.0);
|
||||
|
||||
if let Some(co_changes) = co_changes {
|
||||
let (co_bf_data, co_pos, co_shape): (
|
||||
&ColliderBroadPhaseData,
|
||||
&ColliderPosition,
|
||||
&ColliderShape,
|
||||
) = colliders.index_bundle(handle.0);
|
||||
|
||||
if !co_changes.needs_broad_phase_update() {
|
||||
if let Some(co) = colliders.get(*handle) {
|
||||
if !co.changes.needs_broad_phase_update() {
|
||||
continue;
|
||||
}
|
||||
let mut new_proxy_id = co_bf_data.proxy_index;
|
||||
let mut new_proxy_id = co.bf_data.proxy_index;
|
||||
|
||||
if self.handle_modified_collider(
|
||||
prediction_distance,
|
||||
*handle,
|
||||
&mut new_proxy_id,
|
||||
(co_pos, co_shape, co_changes),
|
||||
(&co.pos, &co.shape, &co.changes),
|
||||
) {
|
||||
need_region_propagation = true;
|
||||
}
|
||||
|
||||
if co_bf_data.proxy_index != new_proxy_id {
|
||||
if co.bf_data.proxy_index != new_proxy_id {
|
||||
self.colliders_proxy_ids.insert(*handle, new_proxy_id);
|
||||
|
||||
// Make sure we have the new proxy index in case
|
||||
|
||||
@@ -17,118 +17,118 @@ use parry::shape::Shape;
|
||||
///
|
||||
/// To build a new collider, use the `ColliderBuilder` structure.
|
||||
pub struct Collider {
|
||||
pub(crate) co_type: ColliderType,
|
||||
pub(crate) co_shape: ColliderShape,
|
||||
pub(crate) co_mprops: ColliderMassProps,
|
||||
pub(crate) co_changes: ColliderChanges,
|
||||
pub(crate) co_parent: Option<ColliderParent>,
|
||||
pub(crate) co_pos: ColliderPosition,
|
||||
pub(crate) co_material: ColliderMaterial,
|
||||
pub(crate) co_flags: ColliderFlags,
|
||||
pub(crate) co_bf_data: ColliderBroadPhaseData,
|
||||
pub(crate) coll_type: ColliderType,
|
||||
pub(crate) shape: ColliderShape,
|
||||
pub(crate) mprops: ColliderMassProps,
|
||||
pub(crate) changes: ColliderChanges,
|
||||
pub(crate) parent: Option<ColliderParent>,
|
||||
pub(crate) pos: ColliderPosition,
|
||||
pub(crate) material: ColliderMaterial,
|
||||
pub(crate) flags: ColliderFlags,
|
||||
pub(crate) bf_data: ColliderBroadPhaseData,
|
||||
/// User-defined data associated to this collider.
|
||||
pub user_data: u128,
|
||||
}
|
||||
|
||||
impl Collider {
|
||||
pub(crate) fn reset_internal_references(&mut self) {
|
||||
self.co_bf_data.proxy_index = crate::INVALID_U32;
|
||||
self.co_changes = ColliderChanges::all();
|
||||
self.bf_data.proxy_index = crate::INVALID_U32;
|
||||
self.changes = ColliderChanges::all();
|
||||
}
|
||||
|
||||
/// The rigid body this collider is attached to.
|
||||
pub fn parent(&self) -> Option<RigidBodyHandle> {
|
||||
self.co_parent.map(|parent| parent.handle)
|
||||
self.parent.map(|parent| parent.handle)
|
||||
}
|
||||
|
||||
/// Is this collider a sensor?
|
||||
pub fn is_sensor(&self) -> bool {
|
||||
self.co_type.is_sensor()
|
||||
self.coll_type.is_sensor()
|
||||
}
|
||||
|
||||
/// The physics hooks enabled for this collider.
|
||||
pub fn active_hooks(&self) -> ActiveHooks {
|
||||
self.co_flags.active_hooks
|
||||
self.flags.active_hooks
|
||||
}
|
||||
|
||||
/// Sets the physics hooks enabled for this collider.
|
||||
pub fn set_active_hooks(&mut self, active_hooks: ActiveHooks) {
|
||||
self.co_flags.active_hooks = active_hooks;
|
||||
self.flags.active_hooks = active_hooks;
|
||||
}
|
||||
|
||||
/// The events enabled for this collider.
|
||||
pub fn active_events(&self) -> ActiveEvents {
|
||||
self.co_flags.active_events
|
||||
self.flags.active_events
|
||||
}
|
||||
|
||||
/// Sets the events enabled for this collider.
|
||||
pub fn set_active_events(&mut self, active_events: ActiveEvents) {
|
||||
self.co_flags.active_events = active_events;
|
||||
self.flags.active_events = active_events;
|
||||
}
|
||||
|
||||
/// The collision types enabled for this collider.
|
||||
pub fn active_collision_types(&self) -> ActiveCollisionTypes {
|
||||
self.co_flags.active_collision_types
|
||||
self.flags.active_collision_types
|
||||
}
|
||||
|
||||
/// Sets the collision types enabled for this collider.
|
||||
pub fn set_active_collision_types(&mut self, active_collision_types: ActiveCollisionTypes) {
|
||||
self.co_flags.active_collision_types = active_collision_types;
|
||||
self.flags.active_collision_types = active_collision_types;
|
||||
}
|
||||
|
||||
/// The friction coefficient of this collider.
|
||||
pub fn friction(&self) -> Real {
|
||||
self.co_material.friction
|
||||
self.material.friction
|
||||
}
|
||||
|
||||
/// Sets the friction coefficient of this collider.
|
||||
pub fn set_friction(&mut self, coefficient: Real) {
|
||||
self.co_material.friction = coefficient
|
||||
self.material.friction = coefficient
|
||||
}
|
||||
|
||||
/// The combine rule used by this collider to combine its friction
|
||||
/// coefficient with the friction coefficient of the other collider it
|
||||
/// is in contact with.
|
||||
pub fn friction_combine_rule(&self) -> CoefficientCombineRule {
|
||||
self.co_material.friction_combine_rule
|
||||
self.material.friction_combine_rule
|
||||
}
|
||||
|
||||
/// Sets the combine rule used by this collider to combine its friction
|
||||
/// coefficient with the friction coefficient of the other collider it
|
||||
/// is in contact with.
|
||||
pub fn set_friction_combine_rule(&mut self, rule: CoefficientCombineRule) {
|
||||
self.co_material.friction_combine_rule = rule;
|
||||
self.material.friction_combine_rule = rule;
|
||||
}
|
||||
|
||||
/// The restitution coefficient of this collider.
|
||||
pub fn restitution(&self) -> Real {
|
||||
self.co_material.restitution
|
||||
self.material.restitution
|
||||
}
|
||||
|
||||
/// Sets the restitution coefficient of this collider.
|
||||
pub fn set_restitution(&mut self, coefficient: Real) {
|
||||
self.co_material.restitution = coefficient
|
||||
self.material.restitution = coefficient
|
||||
}
|
||||
|
||||
/// The combine rule used by this collider to combine its restitution
|
||||
/// coefficient with the restitution coefficient of the other collider it
|
||||
/// is in contact with.
|
||||
pub fn restitution_combine_rule(&self) -> CoefficientCombineRule {
|
||||
self.co_material.restitution_combine_rule
|
||||
self.material.restitution_combine_rule
|
||||
}
|
||||
|
||||
/// Sets the combine rule used by this collider to combine its restitution
|
||||
/// coefficient with the restitution coefficient of the other collider it
|
||||
/// is in contact with.
|
||||
pub fn set_restitution_combine_rule(&mut self, rule: CoefficientCombineRule) {
|
||||
self.co_material.restitution_combine_rule = rule;
|
||||
self.material.restitution_combine_rule = rule;
|
||||
}
|
||||
|
||||
/// Sets whether or not this is a sensor collider.
|
||||
pub fn set_sensor(&mut self, is_sensor: bool) {
|
||||
if is_sensor != self.is_sensor() {
|
||||
self.co_changes.insert(ColliderChanges::TYPE);
|
||||
self.co_type = if is_sensor {
|
||||
self.changes.insert(ColliderChanges::TYPE);
|
||||
self.coll_type = if is_sensor {
|
||||
ColliderType::Sensor
|
||||
} else {
|
||||
ColliderType::Solid
|
||||
@@ -138,55 +138,55 @@ impl Collider {
|
||||
|
||||
/// Sets the translational part of this collider's position.
|
||||
pub fn set_translation(&mut self, translation: Vector<Real>) {
|
||||
self.co_changes.insert(ColliderChanges::POSITION);
|
||||
self.co_pos.0.translation.vector = translation;
|
||||
self.changes.insert(ColliderChanges::POSITION);
|
||||
self.pos.0.translation.vector = translation;
|
||||
}
|
||||
|
||||
/// Sets the rotational part of this collider's position.
|
||||
pub fn set_rotation(&mut self, rotation: AngVector<Real>) {
|
||||
self.co_changes.insert(ColliderChanges::POSITION);
|
||||
self.co_pos.0.rotation = Rotation::new(rotation);
|
||||
self.changes.insert(ColliderChanges::POSITION);
|
||||
self.pos.0.rotation = Rotation::new(rotation);
|
||||
}
|
||||
|
||||
/// Sets the position of this collider.
|
||||
pub fn set_position(&mut self, position: Isometry<Real>) {
|
||||
self.co_changes.insert(ColliderChanges::POSITION);
|
||||
self.co_pos.0 = position;
|
||||
self.changes.insert(ColliderChanges::POSITION);
|
||||
self.pos.0 = position;
|
||||
}
|
||||
|
||||
/// The world-space position of this collider.
|
||||
pub fn position(&self) -> &Isometry<Real> {
|
||||
&self.co_pos
|
||||
&self.pos
|
||||
}
|
||||
|
||||
/// The translational part of this collider's position.
|
||||
pub fn translation(&self) -> &Vector<Real> {
|
||||
&self.co_pos.0.translation.vector
|
||||
&self.pos.0.translation.vector
|
||||
}
|
||||
|
||||
/// The rotational part of this collider's position.
|
||||
pub fn rotation(&self) -> &Rotation<Real> {
|
||||
&self.co_pos.0.rotation
|
||||
&self.pos.0.rotation
|
||||
}
|
||||
|
||||
/// The position of this collider wrt the body it is attached to.
|
||||
pub fn position_wrt_parent(&self) -> Option<&Isometry<Real>> {
|
||||
self.co_parent.as_ref().map(|p| &p.pos_wrt_parent)
|
||||
self.parent.as_ref().map(|p| &p.pos_wrt_parent)
|
||||
}
|
||||
|
||||
/// Sets the translational part of this collider's translation relative to its parent rigid-body.
|
||||
pub fn set_translation_wrt_parent(&mut self, translation: Vector<Real>) {
|
||||
if let Some(co_parent) = self.co_parent.as_mut() {
|
||||
self.co_changes.insert(ColliderChanges::PARENT);
|
||||
co_parent.pos_wrt_parent.translation.vector = translation;
|
||||
if let Some(parent) = self.parent.as_mut() {
|
||||
self.changes.insert(ColliderChanges::PARENT);
|
||||
parent.pos_wrt_parent.translation.vector = translation;
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the rotational part of this collider's rotaiton relative to its parent rigid-body.
|
||||
pub fn set_rotation_wrt_parent(&mut self, rotation: AngVector<Real>) {
|
||||
if let Some(co_parent) = self.co_parent.as_mut() {
|
||||
self.co_changes.insert(ColliderChanges::PARENT);
|
||||
co_parent.pos_wrt_parent.rotation = Rotation::new(rotation);
|
||||
if let Some(parent) = self.parent.as_mut() {
|
||||
self.changes.insert(ColliderChanges::PARENT);
|
||||
parent.pos_wrt_parent.rotation = Rotation::new(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,46 +194,46 @@ impl Collider {
|
||||
///
|
||||
/// Does nothing if the collider is not attached to a rigid-body.
|
||||
pub fn set_position_wrt_parent(&mut self, pos_wrt_parent: Isometry<Real>) {
|
||||
if let Some(co_parent) = self.co_parent.as_mut() {
|
||||
self.co_changes.insert(ColliderChanges::PARENT);
|
||||
co_parent.pos_wrt_parent = pos_wrt_parent;
|
||||
if let Some(parent) = self.parent.as_mut() {
|
||||
self.changes.insert(ColliderChanges::PARENT);
|
||||
parent.pos_wrt_parent = pos_wrt_parent;
|
||||
}
|
||||
}
|
||||
|
||||
/// The collision groups used by this collider.
|
||||
pub fn collision_groups(&self) -> InteractionGroups {
|
||||
self.co_flags.collision_groups
|
||||
self.flags.collision_groups
|
||||
}
|
||||
|
||||
/// Sets the collision groups of this collider.
|
||||
pub fn set_collision_groups(&mut self, groups: InteractionGroups) {
|
||||
if self.co_flags.collision_groups != groups {
|
||||
self.co_changes.insert(ColliderChanges::GROUPS);
|
||||
self.co_flags.collision_groups = groups;
|
||||
if self.flags.collision_groups != groups {
|
||||
self.changes.insert(ColliderChanges::GROUPS);
|
||||
self.flags.collision_groups = groups;
|
||||
}
|
||||
}
|
||||
|
||||
/// The solver groups used by this collider.
|
||||
pub fn solver_groups(&self) -> InteractionGroups {
|
||||
self.co_flags.solver_groups
|
||||
self.flags.solver_groups
|
||||
}
|
||||
|
||||
/// Sets the solver groups of this collider.
|
||||
pub fn set_solver_groups(&mut self, groups: InteractionGroups) {
|
||||
if self.co_flags.solver_groups != groups {
|
||||
self.co_changes.insert(ColliderChanges::GROUPS);
|
||||
self.co_flags.solver_groups = groups;
|
||||
if self.flags.solver_groups != groups {
|
||||
self.changes.insert(ColliderChanges::GROUPS);
|
||||
self.flags.solver_groups = groups;
|
||||
}
|
||||
}
|
||||
|
||||
/// The material (friction and restitution properties) of this collider.
|
||||
pub fn material(&self) -> &ColliderMaterial {
|
||||
&self.co_material
|
||||
&self.material
|
||||
}
|
||||
|
||||
/// The density of this collider, if set.
|
||||
pub fn density(&self) -> Option<Real> {
|
||||
match &self.co_mprops {
|
||||
match &self.mprops {
|
||||
ColliderMassProps::Density(density) => Some(*density),
|
||||
ColliderMassProps::MassProperties(_) => None,
|
||||
}
|
||||
@@ -241,7 +241,7 @@ impl Collider {
|
||||
|
||||
/// The geometric shape of this collider.
|
||||
pub fn shape(&self) -> &dyn Shape {
|
||||
self.co_shape.as_ref()
|
||||
self.shape.as_ref()
|
||||
}
|
||||
|
||||
/// A mutable reference to the geometric shape of this collider.
|
||||
@@ -250,37 +250,36 @@ impl Collider {
|
||||
/// cloned first so that `self` contains a unique copy of that
|
||||
/// shape that you can modify.
|
||||
pub fn shape_mut(&mut self) -> &mut dyn Shape {
|
||||
self.co_changes.insert(ColliderChanges::SHAPE);
|
||||
self.co_shape.make_mut()
|
||||
self.changes.insert(ColliderChanges::SHAPE);
|
||||
self.shape.make_mut()
|
||||
}
|
||||
|
||||
/// Sets the shape of this collider.
|
||||
pub fn set_shape(&mut self, shape: SharedShape) {
|
||||
self.co_changes.insert(ColliderChanges::SHAPE);
|
||||
self.co_shape = shape;
|
||||
self.changes.insert(ColliderChanges::SHAPE);
|
||||
self.shape = shape;
|
||||
}
|
||||
|
||||
/// Retrieve the SharedShape. Also see the `shape()` function
|
||||
pub fn shared_shape(&self) -> &SharedShape {
|
||||
&self.co_shape
|
||||
&self.shape
|
||||
}
|
||||
|
||||
/// Compute the axis-aligned bounding box of this collider.
|
||||
pub fn compute_aabb(&self) -> AABB {
|
||||
self.co_shape.compute_aabb(&self.co_pos)
|
||||
self.shape.compute_aabb(&self.pos)
|
||||
}
|
||||
|
||||
/// Compute the axis-aligned bounding box of this collider moving from its current position
|
||||
/// to the given `next_position`
|
||||
pub fn compute_swept_aabb(&self, next_position: &Isometry<Real>) -> AABB {
|
||||
self.co_shape
|
||||
.compute_swept_aabb(&self.co_pos, next_position)
|
||||
self.shape.compute_swept_aabb(&self.pos, next_position)
|
||||
}
|
||||
|
||||
/// Compute the local-space mass properties of this collider.
|
||||
pub fn mass_properties(&self) -> MassProperties {
|
||||
match &self.co_mprops {
|
||||
ColliderMassProps::Density(density) => self.co_shape.mass_properties(*density),
|
||||
match &self.mprops {
|
||||
ColliderMassProps::Density(density) => self.shape.mass_properties(*density),
|
||||
ColliderMassProps::MassProperties(mass_properties) => **mass_properties,
|
||||
}
|
||||
}
|
||||
@@ -726,18 +725,17 @@ impl ColliderBuilder {
|
||||
|
||||
/// Builds a new collider attached to the given rigid-body.
|
||||
pub fn build(&self) -> Collider {
|
||||
let (co_changes, co_pos, co_bf_data, co_shape, co_type, co_material, co_flags, co_mprops) =
|
||||
self.components();
|
||||
let (changes, pos, bf_data, shape, coll_type, material, flags, mprops) = self.components();
|
||||
Collider {
|
||||
co_shape,
|
||||
co_mprops,
|
||||
co_material,
|
||||
co_parent: None,
|
||||
co_changes,
|
||||
co_pos,
|
||||
co_bf_data,
|
||||
co_flags,
|
||||
co_type,
|
||||
shape,
|
||||
mprops,
|
||||
material,
|
||||
parent: None,
|
||||
changes,
|
||||
pos,
|
||||
bf_data,
|
||||
flags,
|
||||
coll_type,
|
||||
user_data: self.user_data,
|
||||
}
|
||||
}
|
||||
@@ -763,39 +761,32 @@ impl ColliderBuilder {
|
||||
ColliderMassProps::Density(density)
|
||||
};
|
||||
|
||||
let co_shape = self.shape.clone();
|
||||
let co_mprops = mass_info;
|
||||
let co_material = ColliderMaterial {
|
||||
let shape = self.shape.clone();
|
||||
let mprops = mass_info;
|
||||
let material = ColliderMaterial {
|
||||
friction: self.friction,
|
||||
restitution: self.restitution,
|
||||
friction_combine_rule: self.friction_combine_rule,
|
||||
restitution_combine_rule: self.restitution_combine_rule,
|
||||
};
|
||||
let co_flags = ColliderFlags {
|
||||
let flags = ColliderFlags {
|
||||
collision_groups: self.collision_groups,
|
||||
solver_groups: self.solver_groups,
|
||||
active_collision_types: self.active_collision_types,
|
||||
active_hooks: self.active_hooks,
|
||||
active_events: self.active_events,
|
||||
};
|
||||
let co_changes = ColliderChanges::all();
|
||||
let co_pos = ColliderPosition(self.position);
|
||||
let co_bf_data = ColliderBroadPhaseData::default();
|
||||
let co_type = if self.is_sensor {
|
||||
let changes = ColliderChanges::all();
|
||||
let pos = ColliderPosition(self.position);
|
||||
let bf_data = ColliderBroadPhaseData::default();
|
||||
let coll_type = if self.is_sensor {
|
||||
ColliderType::Sensor
|
||||
} else {
|
||||
ColliderType::Solid
|
||||
};
|
||||
|
||||
(
|
||||
co_changes,
|
||||
co_pos,
|
||||
co_bf_data,
|
||||
co_shape,
|
||||
co_type,
|
||||
co_material,
|
||||
co_flags,
|
||||
co_mprops,
|
||||
changes, pos, bf_data, shape, coll_type, material, flags, mprops,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
use crate::data::arena::Arena;
|
||||
use crate::data::{ComponentSet, ComponentSetMut, ComponentSetOption};
|
||||
use crate::dynamics::{IslandManager, RigidBodyHandle, RigidBodySet};
|
||||
use crate::geometry::{
|
||||
Collider, ColliderBroadPhaseData, ColliderFlags, ColliderMassProps, ColliderMaterial,
|
||||
ColliderParent, ColliderPosition, ColliderShape, ColliderType,
|
||||
};
|
||||
use crate::geometry::{ColliderChanges, ColliderHandle};
|
||||
use crate::geometry::{Collider, ColliderChanges, ColliderHandle, ColliderParent};
|
||||
use crate::math::Isometry;
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
@@ -18,63 +13,6 @@ pub struct ColliderSet {
|
||||
pub(crate) removed_colliders: Vec<ColliderHandle>,
|
||||
}
|
||||
|
||||
macro_rules! impl_field_component_set(
|
||||
($T: ty, $field: ident) => {
|
||||
impl ComponentSetOption<$T> for ColliderSet {
|
||||
fn get(&self, handle: crate::data::Index) -> Option<&$T> {
|
||||
self.get(ColliderHandle(handle)).map(|b| &b.$field)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSet<$T> for ColliderSet {
|
||||
fn size_hint(&self) -> usize {
|
||||
self.len()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn for_each(&self, mut f: impl FnMut(crate::data::Index, &$T)) {
|
||||
for (handle, body) in self.colliders.iter() {
|
||||
f(handle, &body.$field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentSetMut<$T> for ColliderSet {
|
||||
fn set_internal(&mut self, handle: crate::data::Index, val: $T) {
|
||||
if let Some(rb) = self.get_mut_internal(ColliderHandle(handle)) {
|
||||
rb.$field = val;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn map_mut_internal<Result>(
|
||||
&mut self,
|
||||
handle: crate::data::Index,
|
||||
f: impl FnOnce(&mut $T) -> Result,
|
||||
) -> Option<Result> {
|
||||
self.get_mut_internal(ColliderHandle(handle)).map(|rb| f(&mut rb.$field))
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl_field_component_set!(ColliderType, co_type);
|
||||
impl_field_component_set!(ColliderShape, co_shape);
|
||||
impl_field_component_set!(ColliderMassProps, co_mprops);
|
||||
impl_field_component_set!(ColliderChanges, co_changes);
|
||||
impl_field_component_set!(ColliderPosition, co_pos);
|
||||
impl_field_component_set!(ColliderMaterial, co_material);
|
||||
impl_field_component_set!(ColliderFlags, co_flags);
|
||||
impl_field_component_set!(ColliderBroadPhaseData, co_bf_data);
|
||||
|
||||
impl ComponentSetOption<ColliderParent> for ColliderSet {
|
||||
#[inline(always)]
|
||||
fn get(&self, handle: crate::data::Index) -> Option<&ColliderParent> {
|
||||
self.get(ColliderHandle(handle))
|
||||
.and_then(|b| b.co_parent.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl ColliderSet {
|
||||
/// Create a new empty set of colliders.
|
||||
pub fn new() -> Self {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#[cfg(feature = "parallel")]
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::data::{BundleSet, Coarena, ComponentSet, ComponentSetMut, ComponentSetOption};
|
||||
use crate::dynamics::CoefficientCombineRule;
|
||||
use crate::data::Coarena;
|
||||
use crate::dynamics::{
|
||||
IslandManager, RigidBodyActivation, RigidBodyDominance, RigidBodyIds, RigidBodyType,
|
||||
CoefficientCombineRule, IslandManager, RigidBodyActivation, RigidBodyDominance, RigidBodyIds,
|
||||
RigidBodySet, RigidBodyType,
|
||||
};
|
||||
use crate::geometry::{
|
||||
BroadPhasePairEvent, ColliderChanges, ColliderGraphIndex, ColliderHandle, ColliderMaterial,
|
||||
ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType, CollisionEvent,
|
||||
ContactData, ContactManifold, ContactManifoldData, ContactPair, InteractionGraph,
|
||||
IntersectionPair, SolverContact, SolverFlags,
|
||||
ColliderPair, ColliderParent, ColliderPosition, ColliderSet, ColliderShape, ColliderType,
|
||||
CollisionEvent, ContactData, ContactManifold, ContactManifoldData, ContactPair,
|
||||
InteractionGraph, IntersectionPair, SolverContact, SolverFlags,
|
||||
};
|
||||
use crate::math::{Real, Vector};
|
||||
use crate::pipeline::{
|
||||
@@ -250,23 +250,15 @@ impl NarrowPhase {
|
||||
// }
|
||||
|
||||
/// Maintain the narrow-phase internal state by taking collider removal into account.
|
||||
pub fn handle_user_changes<Bodies, Colliders>(
|
||||
pub fn handle_user_changes(
|
||||
&mut self,
|
||||
mut islands: Option<&mut IslandManager>,
|
||||
modified_colliders: &[ColliderHandle],
|
||||
removed_colliders: &[ColliderHandle],
|
||||
colliders: &mut Colliders,
|
||||
bodies: &mut Bodies,
|
||||
colliders: &mut ColliderSet,
|
||||
bodies: &mut RigidBodySet,
|
||||
events: &dyn EventHandler,
|
||||
) where
|
||||
Bodies: ComponentSetMut<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSetMut<RigidBodyIds>,
|
||||
Colliders: ComponentSet<ColliderChanges>
|
||||
+ ComponentSet<ColliderType>
|
||||
+ ComponentSet<ColliderFlags>
|
||||
+ ComponentSetOption<ColliderParent>,
|
||||
{
|
||||
) {
|
||||
// TODO: avoid these hash-maps.
|
||||
// They are necessary to handle the swap-remove done internally
|
||||
// by the contact/intersection graphs when a node is removed.
|
||||
@@ -305,22 +297,17 @@ impl NarrowPhase {
|
||||
self.handle_modified_colliders(islands, modified_colliders, colliders, bodies, events);
|
||||
}
|
||||
|
||||
pub(crate) fn remove_collider<Bodies, Colliders>(
|
||||
pub(crate) fn remove_collider(
|
||||
&mut self,
|
||||
intersection_graph_id: ColliderGraphIndex,
|
||||
contact_graph_id: ColliderGraphIndex,
|
||||
mut islands: Option<&mut IslandManager>,
|
||||
colliders: &mut Colliders,
|
||||
bodies: &mut Bodies,
|
||||
colliders: &mut ColliderSet,
|
||||
bodies: &mut RigidBodySet,
|
||||
prox_id_remap: &mut HashMap<ColliderHandle, ColliderGraphIndex>,
|
||||
contact_id_remap: &mut HashMap<ColliderHandle, ColliderGraphIndex>,
|
||||
events: &dyn EventHandler,
|
||||
) where
|
||||
Bodies: ComponentSetMut<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSetMut<RigidBodyIds>,
|
||||
Colliders: ComponentSetOption<ColliderParent>,
|
||||
{
|
||||
) {
|
||||
// Wake up every body in contact with the deleted collider and generate Stopped collision events.
|
||||
if let Some(islands) = islands.as_deref_mut() {
|
||||
for (a, b, pair) in self.contact_graph.interactions_with(contact_graph_id) {
|
||||
@@ -379,22 +366,14 @@ impl NarrowPhase {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn handle_modified_colliders<Bodies, Colliders>(
|
||||
pub(crate) fn handle_modified_colliders(
|
||||
&mut self,
|
||||
mut islands: Option<&mut IslandManager>,
|
||||
modified_colliders: &[ColliderHandle],
|
||||
colliders: &Colliders,
|
||||
bodies: &mut Bodies,
|
||||
colliders: &ColliderSet,
|
||||
bodies: &mut RigidBodySet,
|
||||
events: &dyn EventHandler,
|
||||
) where
|
||||
Bodies: ComponentSetMut<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSetMut<RigidBodyIds>,
|
||||
Colliders: ComponentSet<ColliderChanges>
|
||||
+ ComponentSet<ColliderType>
|
||||
+ ComponentSet<ColliderFlags>
|
||||
+ ComponentSetOption<ColliderParent>,
|
||||
{
|
||||
) {
|
||||
let mut pairs_to_remove = vec![];
|
||||
|
||||
for handle in modified_colliders {
|
||||
@@ -496,22 +475,15 @@ impl NarrowPhase {
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_pair<Bodies, Colliders>(
|
||||
fn remove_pair(
|
||||
&mut self,
|
||||
islands: Option<&mut IslandManager>,
|
||||
colliders: &Colliders,
|
||||
bodies: &mut Bodies,
|
||||
colliders: &ColliderSet,
|
||||
bodies: &mut RigidBodySet,
|
||||
pair: &ColliderPair,
|
||||
events: &dyn EventHandler,
|
||||
mode: PairRemovalMode,
|
||||
) where
|
||||
Bodies: ComponentSetMut<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSetMut<RigidBodyIds>,
|
||||
Colliders: ComponentSet<ColliderType>
|
||||
+ ComponentSet<ColliderFlags>
|
||||
+ ComponentSetOption<ColliderParent>,
|
||||
{
|
||||
) {
|
||||
let co_type1: Option<&ColliderType> = colliders.get(pair.collider1.0);
|
||||
let co_type2: Option<&ColliderType> = colliders.get(pair.collider2.0);
|
||||
|
||||
@@ -582,10 +554,7 @@ impl NarrowPhase {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_pair<Colliders>(&mut self, colliders: &Colliders, pair: &ColliderPair)
|
||||
where
|
||||
Colliders: ComponentSet<ColliderType> + ComponentSetOption<ColliderParent>,
|
||||
{
|
||||
fn add_pair(&mut self, colliders: &ColliderSet, pair: &ColliderPair) {
|
||||
let co_type1: Option<&ColliderType> = colliders.get(pair.collider1.0);
|
||||
let co_type2: Option<&ColliderType> = colliders.get(pair.collider2.0);
|
||||
|
||||
@@ -666,21 +635,14 @@ impl NarrowPhase {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn register_pairs<Bodies, Colliders>(
|
||||
pub(crate) fn register_pairs(
|
||||
&mut self,
|
||||
mut islands: Option<&mut IslandManager>,
|
||||
colliders: &Colliders,
|
||||
bodies: &mut Bodies,
|
||||
colliders: &ColliderSet,
|
||||
bodies: &mut RigidBodySet,
|
||||
broad_phase_events: &[BroadPhasePairEvent],
|
||||
events: &dyn EventHandler,
|
||||
) where
|
||||
Bodies: ComponentSetMut<RigidBodyActivation>
|
||||
+ ComponentSetMut<RigidBodyIds>
|
||||
+ ComponentSet<RigidBodyType>,
|
||||
Colliders: ComponentSet<ColliderType>
|
||||
+ ComponentSet<ColliderFlags>
|
||||
+ ComponentSetOption<ColliderParent>,
|
||||
{
|
||||
) {
|
||||
for event in broad_phase_events {
|
||||
match event {
|
||||
BroadPhasePairEvent::AddPair(pair) => {
|
||||
@@ -700,24 +662,14 @@ impl NarrowPhase {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compute_intersections<Bodies, Colliders>(
|
||||
pub(crate) fn compute_intersections(
|
||||
&mut self,
|
||||
bodies: &Bodies,
|
||||
colliders: &Colliders,
|
||||
bodies: &RigidBodySet,
|
||||
colliders: &ColliderSet,
|
||||
modified_colliders: &[ColliderHandle],
|
||||
hooks: &dyn PhysicsHooks<Bodies, Colliders>,
|
||||
hooks: &dyn PhysicsHooks,
|
||||
events: &dyn EventHandler,
|
||||
) where
|
||||
Bodies: ComponentSet<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSet<RigidBodyDominance>,
|
||||
Colliders: ComponentSet<ColliderChanges>
|
||||
+ ComponentSetOption<ColliderParent>
|
||||
+ ComponentSet<ColliderShape>
|
||||
+ ComponentSet<ColliderPosition>
|
||||
+ ComponentSet<ColliderMaterial>
|
||||
+ ComponentSet<ColliderFlags>,
|
||||
{
|
||||
) {
|
||||
if modified_colliders.is_empty() {
|
||||
return;
|
||||
}
|
||||
@@ -824,25 +776,15 @@ impl NarrowPhase {
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn compute_contacts<Bodies, Colliders>(
|
||||
pub(crate) fn compute_contacts(
|
||||
&mut self,
|
||||
prediction_distance: Real,
|
||||
bodies: &Bodies,
|
||||
colliders: &Colliders,
|
||||
bodies: &RigidBodySet,
|
||||
colliders: &ColliderSet,
|
||||
modified_colliders: &[ColliderHandle],
|
||||
hooks: &dyn PhysicsHooks<Bodies, Colliders>,
|
||||
hooks: &dyn PhysicsHooks,
|
||||
events: &dyn EventHandler,
|
||||
) where
|
||||
Bodies: ComponentSet<RigidBodyActivation>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSet<RigidBodyDominance>,
|
||||
Colliders: ComponentSet<ColliderChanges>
|
||||
+ ComponentSetOption<ColliderParent>
|
||||
+ ComponentSet<ColliderShape>
|
||||
+ ComponentSet<ColliderPosition>
|
||||
+ ComponentSet<ColliderMaterial>
|
||||
+ ComponentSet<ColliderFlags>,
|
||||
{
|
||||
) {
|
||||
if modified_colliders.is_empty() {
|
||||
return;
|
||||
}
|
||||
@@ -1057,17 +999,13 @@ impl NarrowPhase {
|
||||
|
||||
/// Retrieve all the interactions with at least one contact point, happening between two active bodies.
|
||||
// NOTE: this is very similar to the code from ImpulseJointSet::select_active_interactions.
|
||||
pub(crate) fn select_active_contacts<'a, Bodies>(
|
||||
pub(crate) fn select_active_contacts<'a>(
|
||||
&'a mut self,
|
||||
islands: &IslandManager,
|
||||
bodies: &Bodies,
|
||||
bodies: &RigidBodySet,
|
||||
out_manifolds: &mut Vec<&'a mut ContactManifold>,
|
||||
out: &mut Vec<Vec<ContactManifoldIndex>>,
|
||||
) where
|
||||
Bodies: ComponentSet<RigidBodyIds>
|
||||
+ ComponentSet<RigidBodyType>
|
||||
+ ComponentSet<RigidBodyActivation>,
|
||||
{
|
||||
) {
|
||||
for out_island in &mut out[..islands.num_islands()] {
|
||||
out_island.clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user