pub struct SweptCcd {
pub mode: SweepMode,
pub include_dynamic: bool,
pub linear_threshold: Scalar,
pub angular_threshold: Scalar,
}
Expand description
A component that enables sweep-based Continuous Collision Detection (CCD)
for a RigidBody
. This helps prevent missed collisions for small and fast-moving objects.
By default, swept CCD considers both translational and rotational motion, and is used
against all types of rigid bodies and colliders. This behavior can be modified
by changing SweptCcd::mode
and other properties.
CCD is generally not useful for large or slow objects, as they are less likely to miss collisions. It is recommended to only use swept CCD when necessary, as it is more expensive than speculative collision and discrete collision detection.
Read the module-level documentation for more information about what CCD is, what it is used for, and what limitations and tradeoffs it can have.
§Example
use avian3d::prelude::*;
use bevy::prelude::*;
fn setup(mut commands: Commands) {
// Spawn a dynamic rigid body with swept CCD, travelling towards the right at a high speed.
// The default CCD configuration considers both translational and rotational motion.
commands.spawn((
RigidBody::Dynamic,
SweptCcd::default(),
LinearVelocity(Vec3::X * 100.0),
Collider::sphere(0.1),
TransformBundle::from_transform(Transform::from_xyz(-10.0, 3.0, 0.0)),
));
// Spawn another dynamic rigid body with swept CCD, but this time only considering
// linear motion and not rotation.
commands.spawn((
RigidBody::Dynamic,
SweptCcd::LINEAR, // or `SweptCcd::new_with_mode(SweepMode::Linear)`
LinearVelocity(Vec3::X * 100.0),
Collider::sphere(0.1),
TransformBundle::from_transform(Transform::from_xyz(-10.0, -3.0, 0.0)),
));
// Spawn a thin, long object rotating at a high speed.
// The first ball should hit it, but the second one does not consider
// rotational motion, and most likely passes through.
commands.spawn((
RigidBody::Dynamic,
LockedAxes::TRANSLATION_LOCKED,
AngularVelocity(Vec3::Z * 100.0),
Collider::cuboid(0.2, 10.0, 10.0),
));
// Spawn another thin, long object, this time not rotating.
// The second ball should now hit this.
commands.spawn((
RigidBody::Static,
Collider::cuboid(0.2, 10.0, 10.0),
TransformBundle::from_transform(Transform::from_xyz(15.0, 0.0, 0.0)),
));
}
Fields§
§mode: SweepMode
The type of sweep used for swept CCD.
If two entities with different sweep modes collide, SweepMode::NonLinear
is preferred.
The default is SweepMode::NonLinear
, which considers both translational
and rotational motion.
include_dynamic: bool
If true
, swept CCD is performed against dynamic rigid bodies.
Otherwise, it is only performed against static geometry and kinematic bodies.
The default is true
.
linear_threshold: Scalar
Determines how fast two bodies must be moving relative to each other for swept CCD to be activated for them.
If the linear velocity is below this threshold, CCD is skipped,
unless the angular velocity exceeds the angular_threshold
.
The default is 0.0
, meaning that CCD is performed regardless of the relative velocity.
angular_threshold: Scalar
Determines how fast two bodies must be rotating relative to each other for swept CCD to be activated for them.
If the angular velocity is below this threshold, CCD is skipped,
unless the linear velocity exceeds the linear_threshold
.
The default is 0.0
, meaning that CCD is performed regardless of the relative velocity.
Implementations§
source§impl SweptCcd
impl SweptCcd
sourcepub const LINEAR: Self = _
pub const LINEAR: Self = _
Continuous Collision Detection with SweepMode::Linear
.
This only takes into account translational motion, and can lead to tunneling against thin, fast-spinning objects.
sourcepub const NON_LINEAR: Self = _
pub const NON_LINEAR: Self = _
Continuous Collision Detection with SweepMode::NonLinear
.
This takes into account both translational and rotational motion.
sourcepub const fn new_with_mode(mode: SweepMode) -> Self
pub const fn new_with_mode(mode: SweepMode) -> Self
sourcepub const fn with_velocity_threshold(
self,
linear: Scalar,
angular: Scalar
) -> Self
pub const fn with_velocity_threshold( self, linear: Scalar, angular: Scalar ) -> Self
Sets the linear and angular velocity thresholds in self
,
determining how fast two bodies must be moving relative to each other
for swept CCD to be activated for them.
CCD will be active if either of the two thresholds is exceeded.
sourcepub const fn include_dynamic(self, should_include: bool) -> Self
pub const fn include_dynamic(self, should_include: bool) -> Self
Sets whether swept CCD is performed against dynamic rigid bodies.
If false
, it is only performed against static geometry and kinematic bodies.
Trait Implementations§
source§impl Component for SweptCcd
impl Component for SweptCcd
source§const STORAGE_TYPE: StorageType = bevy::ecs::component::StorageType::Table
const STORAGE_TYPE: StorageType = bevy::ecs::component::StorageType::Table
source§fn register_component_hooks(_hooks: &mut ComponentHooks)
fn register_component_hooks(_hooks: &mut ComponentHooks)
ComponentHooks
.source§impl FromReflect for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
impl FromReflect for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
source§fn from_reflect(reflect: &dyn Reflect) -> Option<Self>
fn from_reflect(reflect: &dyn Reflect) -> Option<Self>
Self
from a reflected value.source§fn take_from_reflect(
reflect: Box<dyn Reflect>
) -> Result<Self, Box<dyn Reflect>>
fn take_from_reflect( reflect: Box<dyn Reflect> ) -> Result<Self, Box<dyn Reflect>>
Self
using,
constructing the value using from_reflect
if that fails. Read moresource§impl GetTypeRegistration for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
impl GetTypeRegistration for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
source§fn get_type_registration() -> TypeRegistration
fn get_type_registration() -> TypeRegistration
TypeRegistration
for this type.source§fn register_type_dependencies(registry: &mut TypeRegistry)
fn register_type_dependencies(registry: &mut TypeRegistry)
source§impl PartialEq for SweptCcd
impl PartialEq for SweptCcd
source§impl Reflect for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
impl Reflect for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
source§fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
source§fn as_any_mut(&mut self) -> &mut dyn Any
fn as_any_mut(&mut self) -> &mut dyn Any
&mut dyn Any
.source§fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
source§fn as_reflect(&self) -> &dyn Reflect
fn as_reflect(&self) -> &dyn Reflect
source§fn as_reflect_mut(&mut self) -> &mut dyn Reflect
fn as_reflect_mut(&mut self) -> &mut dyn Reflect
source§fn clone_value(&self) -> Box<dyn Reflect>
fn clone_value(&self) -> Box<dyn Reflect>
Reflect
trait object. Read moresource§fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>
source§fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
source§fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
source§fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
source§fn reflect_owned(self: Box<Self>) -> ReflectOwned
fn reflect_owned(self: Box<Self>) -> ReflectOwned
source§fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool>
fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool>
source§fn apply(&mut self, value: &(dyn Reflect + 'static))
fn apply(&mut self, value: &(dyn Reflect + 'static))
source§fn reflect_hash(&self) -> Option<u64>
fn reflect_hash(&self) -> Option<u64>
source§fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error>
source§fn serializable(&self) -> Option<Serializable<'_>>
fn serializable(&self) -> Option<Serializable<'_>>
source§fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
source§impl Struct for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
impl Struct for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
source§fn field(&self, name: &str) -> Option<&dyn Reflect>
fn field(&self, name: &str) -> Option<&dyn Reflect>
name
as a &dyn Reflect
.source§fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>
fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>
name
as a
&mut dyn Reflect
.source§fn field_at(&self, index: usize) -> Option<&dyn Reflect>
fn field_at(&self, index: usize) -> Option<&dyn Reflect>
index
as a
&dyn Reflect
.source§fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>
fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>
index
as a &mut dyn Reflect
.source§fn name_at(&self, index: usize) -> Option<&str>
fn name_at(&self, index: usize) -> Option<&str>
index
.source§fn iter_fields(&self) -> FieldIter<'_>
fn iter_fields(&self) -> FieldIter<'_>
source§fn clone_dynamic(&self) -> DynamicStruct
fn clone_dynamic(&self) -> DynamicStruct
DynamicStruct
.source§impl TypePath for SweptCcd
impl TypePath for SweptCcd
source§fn type_path() -> &'static str
fn type_path() -> &'static str
source§fn short_type_path() -> &'static str
fn short_type_path() -> &'static str
source§fn type_ident() -> Option<&'static str>
fn type_ident() -> Option<&'static str>
source§fn crate_name() -> Option<&'static str>
fn crate_name() -> Option<&'static str>
source§impl Typed for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
impl Typed for SweptCcdwhere
Self: Any + Send + Sync,
SweepMode: FromReflect + TypePath + RegisterForReflection,
bool: FromReflect + TypePath + RegisterForReflection,
Scalar: FromReflect + TypePath + RegisterForReflection,
impl Copy for SweptCcd
impl StructuralPartialEq for SweptCcd
Auto Trait Implementations§
impl Freeze for SweptCcd
impl RefUnwindSafe for SweptCcd
impl Send for SweptCcd
impl Sync for SweptCcd
impl Unpin for SweptCcd
impl UnwindSafe for SweptCcd
Blanket Implementations§
source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<C> Bundle for Cwhere
C: Component,
impl<C> Bundle for Cwhere
C: Component,
fn component_ids( components: &mut Components, storages: &mut Storages, ids: &mut impl FnMut(ComponentId) )
unsafe fn from_components<T, F>(ctx: &mut T, func: &mut F) -> C
source§fn get_component_ids(
components: &Components,
ids: &mut impl FnMut(Option<ComponentId>)
)
fn get_component_ids( components: &Components, ids: &mut impl FnMut(Option<ComponentId>) )
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
source§impl<C> DynamicBundle for Cwhere
C: Component,
impl<C> DynamicBundle for Cwhere
C: Component,
fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>))
source§impl<T> DynamicTypePath for Twhere
T: TypePath,
impl<T> DynamicTypePath for Twhere
T: TypePath,
source§fn reflect_type_path(&self) -> &str
fn reflect_type_path(&self) -> &str
TypePath::type_path
.source§fn reflect_short_type_path(&self) -> &str
fn reflect_short_type_path(&self) -> &str
source§fn reflect_type_ident(&self) -> Option<&str>
fn reflect_type_ident(&self) -> Option<&str>
TypePath::type_ident
.source§fn reflect_crate_name(&self) -> Option<&str>
fn reflect_crate_name(&self) -> Option<&str>
TypePath::crate_name
.source§fn reflect_module_path(&self) -> Option<&str>
fn reflect_module_path(&self) -> Option<&str>
source§impl<T> FromWorld for Twhere
T: Default,
impl<T> FromWorld for Twhere
T: Default,
source§fn from_world(_world: &mut World) -> T
fn from_world(_world: &mut World) -> T
Self
using data from the given World
.source§impl<S> GetField for Swhere
S: Struct,
impl<S> GetField for Swhere
S: Struct,
source§impl<T> GetPath for T
impl<T> GetPath for T
source§fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>
) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p> ) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>
path
. Read moresource§fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p> ) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>
path
. Read moresource§fn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moresource§fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
path
. Read moresource§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moresource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.