Skip to main content

SoftBody

Struct SoftBody 

Source
pub struct SoftBody {
    pub user_data: u128,
    /* private fields */
}
Expand description

A deformable body: SoftBodyParticles linked by elastic elements (SoftBodyEdges, bending, SoftBodyCells, volume preservation, shape matching). Its hidden root rigid body (tagged by crate::dynamics::RigidBody::soft_body) must never be moved, removed or attached to joints.

Fields§

§user_data: u128

User-defined data associated to this soft body.

Implementations§

Source§

impl SoftBody

Source

pub fn topology_version(&self) -> u32

A counter bumped whenever the topology changes (a tear removed elements or duplicated particles): a renderer keying its mesh on the particles and elements rebuilds it when this value changes.

Source

pub fn particles(&self) -> &[SoftBodyParticle]

The particles of this soft body.

Source

pub fn num_particles(&self) -> usize

The number of particles of this soft body.

Source

pub fn particle_position(&self, i: usize) -> Vector

The world-space position of the i-th particle.

Source

pub fn particle_positions(&self) -> impl ExactSizeIterator<Item = Vector> + '_

The world-space positions of every particle.

Source

pub fn particle_velocity(&self, i: usize) -> Vector

The world-space velocity of the i-th particle.

Source

pub fn particle_velocities(&self) -> impl ExactSizeIterator<Item = Vector> + '_

The world-space velocities of every particle.

Source

pub fn set_particle_position(&mut self, i: usize, position: Vector)

Teleports the i-th particle to position (no velocity change). For a pinned particle moving along a path, prefer Self::set_particle_kinematic_target, which gives it the matching velocity so friction and contacts see the motion.

Source

pub fn set_particle_velocity(&mut self, i: usize, velocity: Vector)

Sets the velocity of the i-th particle. A pinned particle keeps moving at that velocity (a velocity-driven kinematic particle) until it is set again or given a kinematic target.

Source

pub fn set_particle_kinematic_target(&mut self, i: usize, position: Vector)

Moves the pinned i-th particle to position over the next step (with the matching velocity, so dragged cloth and friction see the motion), then holds it there until the next target or velocity is set. Ignored for a free particle.

Source

pub fn edges(&self) -> &[SoftBodyEdge]

The distance constraints of this soft body.

Source

pub fn dihedrals(&self) -> &[SoftBodyDihedral]

The dihedral bending constraints of this soft body.

Source

pub fn cells(&self) -> &[SoftBodyCell]

The simplex cells (triangles in 2D, tetrahedra in 3D) of this soft body.

Source

pub fn boundary(&self) -> &[[u32; 3]]

The boundary of this soft body’s computational mesh: segments in 2D, triangles in 3D (particle indices), oriented outward. This is what the volume constraint integrates over; the geometry the body collides through is its crate::dynamics::SoftCollisionMesh.

Source

pub fn material(&self) -> &SoftBodyMaterial

The material (per-family stiffness and damping) of this soft body.

Source

pub fn set_material(&mut self, material: SoftBodyMaterial)

Sets the material of this soft body.

Source

pub fn material_mut(&mut self) -> &mut SoftBodyMaterial

Mutable access to the material of this soft body.

Source

pub fn cell_model(&self) -> SoftBodyCellModel

The constitutive model of this soft body’s cells.

Source

pub fn volume_preservation_enabled(&self) -> bool

Whether the area/volume preservation constraints are enabled (see Self::volume_pieces).

Source

pub fn enable_volume_preservation(&mut self, enabled: bool)

Enables or disables area/volume preservation: one constraint per volume piece (see Self::volume_pieces); it stays disabled for a body without any.

Source

pub fn volume_pieces(&self) -> &[SoftVolumePiece]

The pieces of material enclosed by a closed boundary, each with its own volume constraint so squeezing one does not inflate another. Pieces joined by no element (appended bodies, torn-apart halves) are separate; the holes or cavities of a piece belong to it.

Source

pub fn rest_volume(&self) -> f32

The signed area (2D) or volume (3D) enclosed by the volume pieces at rest (0.0 for a body without a closed boundary).

Source

pub fn volume(&self) -> f32

The signed area (2D) or volume (3D) currently enclosed by the volume pieces.

Source

pub fn volume_factor(&self) -> f32

The multiplier applied to each volume piece’s rest volume to obtain its volume-preservation target (> 1 inflates the body).

Source

pub fn set_volume_factor(&mut self, factor: f32)

Sets the multiplier applied to each volume piece’s rest volume to obtain its volume-preservation target (> 1 inflates the body).

Source

pub fn particle_radius(&self) -> f32

The particle spacing of this soft body: what the impact-adaptive substeps bound the travel per substep by, and the default contact skin of its collision meshes’ colliders.

Source

pub fn root_body(&self) -> RigidBodyHandle

The rigid body standing for this soft body in the islands and holding the colliders of its surface (invalid until inserted in a set): joints, forces and impulses applied to it act on the body as a whole. A tear splitting the body moves each of its joints to the piece closest to its anchor in the rest shape (see crate::dynamics::SoftBodyTearEvent::moved_joints). Its pose is recomputed from the particles at every step, so moving it has no effect, and removing it dissolves its whole-body cluster like any cluster proxy.

Source

pub fn origin(&self) -> Option<SoftBodyHandle>

The soft body this one was split off from by a tear or a cut (None for a user-inserted body): the piece that kept the handle (see crate::dynamics::SoftBodyTearEvent::pieces). Informational only; the handle dangles once that body is removed.

Source

pub fn pieces(&self) -> &[SoftBodyHandle]

The soft bodies split off from this one by tears and cuts, in creation order (a piece torn off a piece is listed by that piece, not here). Informational: the engine never reads it, and a handle dangles once that body is removed.

Source

pub fn particle_settings(&self) -> &SoftBodyParticleSettings

The dynamics settings of the particles (damping, gravity scale, sleeping…).

Source

pub fn set_additional_pgs_iterations(&mut self, iterations: usize)

Sets the extra internal PGS iterations per substep requested for this body’s island component (see super::SoftBodyParticleSettings::additional_pgs_iterations); takes effect at the next step.

Source

pub fn num_solver_colors(&self) -> usize

The number of parallel solver colors used by this soft body’s elements (informational: elements of a same color share no particle and are solved concurrently).

Source

pub fn center_of_mass(&self) -> Vector

The mass-weighted center of the particles (from the cached positions).

Source

pub fn mass(&self) -> f32

The total nominal mass of the particles.

Source

pub fn is_sleeping(&self) -> bool

Whether this soft body is currently sleeping (a soft body sleeps and wakes as a unit, with the island of the rigid bodies it touches). Updated at the end of every step, and by Self::wake_up.

Source

pub fn wake_up(&mut self)

Wakes this soft body up (effective at the start of the next step, together with the island of the bodies it touches).

Source

pub fn is_enabled(&self) -> bool

Whether this soft body takes part in the simulation. A disabled soft body (by Self::set_enabled, or by the NaN quarantine: PhysicsPipeline::quarantine) is left where it is, without colliders or constraints, until it is enabled again.

Source

pub fn set_enabled(&mut self, enabled: bool)

Enables or disables this soft body (effective at the start of the next step). Re-enabling a quarantined body: set its non-finite particles right first (Self::set_particle_position), they are not repaired.

Source§

impl SoftBody

Source

pub fn clusters(&self) -> &[SoftBodyCluster]

The clusters of this soft body (index 0 is the whole-body cluster created at insertion). Removed cluster slots stay as dead entries (SoftBodyCluster::is_live); indices are stable.

Source

pub fn cluster(&self, i: u32) -> Option<&SoftBodyCluster>

The i-th cluster, if it exists and is live.

Source

pub fn cluster_mut(&mut self, i: u32) -> Option<&mut SoftBodyCluster>

The i-th cluster, if it exists and is live.

Source

pub fn cluster_proxy(&self, i: u32) -> Option<RigidBodyHandle>

The proxy rigid body of the i-th cluster, if it is live.

Source

pub fn live_clusters(&self) -> impl Iterator<Item = (u32, &SoftBodyCluster)>

Iterates over the live clusters as (index, cluster).

Source

pub fn num_live_clusters(&self) -> usize

Number of live clusters.

Source

pub fn enable_cluster_shape_matching(&mut self, i: u32, enabled: bool)

Enables or disables shape matching of the i-th cluster’s particles toward the cluster’s frame (independent from the whole-body crate::dynamics::SoftBodyBuilder::shape_matching).

Source

pub fn set_cluster_stiffness_scale(&mut self, i: u32, scale: f32)

Scales the material stiffness (Young modulus) of every cell fully contained in the i-th cluster: regional materials without a separate body. Cells straddling the cluster’s boundary are left as they are.

Source

pub fn set_cluster_edge_softness( &mut self, i: u32, softness: Option<SpringCoefficients<f32>>, )

Overrides the softness of every structural or bending edge fully contained in the i-th cluster (None restores the body material’s): regional stiffness for cloth and ropes.

Source

pub fn set_cluster_tear_resistance(&mut self, i: u32, resistance: f32)

Sets the tear-threshold multiplier of every edge and cell fully contained in the i-th cluster (see super::SoftBodyEdge::tear_resistance): a tough region, or a perforation line; 1.0 restores the material’s thresholds.

Source

pub fn set_cluster_pinned(&mut self, i: u32, pinned: bool)

Pins (or releases) every particle of the i-th cluster at once: the cluster becomes a fixed (kinematic) region dragging the rest of the body, driven along a path with Self::set_cluster_kinematic_target; particles keep their individual pinned semantics.

Source

pub fn set_cluster_kinematic_target(&mut self, i: u32, pose: Pose)

Moves the pinned particles of the i-th cluster rigidly toward pose over the next step: each pinned particle’s target is the cluster’s rest shape placed at pose, with matching velocities; free particles are unaffected (pin them with Self::set_cluster_pinned).

Source§

impl SoftBody

Source

pub fn edge_contact_segments<'a>( &'a self, soft_bodies: &'a SoftBodySet, ) -> impl Iterator<Item = (Vector, Vector)> + 'a

The edge-vs-edge contacts this soft body’s collision meshes owned at the last step (self contacts and contacts with other soft bodies’ meshes), as world segments joining the two edges’ closest points, i.e. the contact’s witness points (for debug rendering).

Source

pub fn volume_contacts(&self) -> impl Iterator<Item = &SoftVolumeContact> + '_

The volume constraints this soft body’s collision meshes assembled at the last step (see SoftVolumeContact; the pair’s owner mesh keeps them), for debug rendering.

Source

pub fn vertex_contact_segments<'a>( &'a self, soft_bodies: &'a SoftBodySet, ) -> impl Iterator<Item = (Vector, Vector)> + 'a

The vertex-vs-surface contacts against this soft body’s collision meshes at the last step (self contacts and other soft bodies’ vertices), as world segments joining the vertex to its projection on the element, i.e. the contact’s witness points (for debug rendering).

Source§

impl SoftBody

Source

pub fn meshes(&self) -> impl Iterator<Item = &SoftCollisionMesh>

The meshes this soft body meets the world through, over all its clusters (and the ones it is only drawn as: a mesh whose collision is disabled has no collider).

Source

pub fn mesh(&self, id: SoftMeshId) -> Option<&SoftCollisionMesh>

The mesh with the given id, if it is live.

Source

pub fn mesh_of(&self, collider: ColliderHandle) -> Option<&SoftCollisionMesh>

The mesh held by collider, if this body owns it.

Source

pub fn collision_mesh(&self) -> Option<&SoftCollisionMesh>

The first mesh this soft body collides through, if any.

Source§

impl SoftBody

Source

pub fn set_particle_pinned(&mut self, i: usize, pinned: bool)

Pins (pinned = true) or releases (pinned = false) the i-th particle: a pinned one is kinematic, holding its position or following Self::set_particle_kinematic_target or Self::set_particle_velocity; release restores its nominal mass and keeps its velocity.

Source

pub fn attach_particle( &mut self, i: usize, body: RigidBodyHandle, bodies: &RigidBodySet, )

Attaches the i-th particle to a rigid body by a two-way point-to-point constraint (unlike pinning), undone by Self::detach_particle; the anchor is its current position in body’s local frame, and a twice-attached particle keeps both attachments.

Source

pub fn detach_particle(&mut self, i: usize) -> bool

Detaches the i-th particle from every rigid body it was attached to with Self::attach_particle. Returns whether it was attached at all.

Source

pub fn particle_attachments(&self) -> &[SoftParticleAttachment]

The particles of this soft body attached to rigid bodies.

Source

pub fn add_force(&mut self, force: Vector, wake_up: bool)

Adds force to the user force of every particle (persistent until Self::reset_forces, like a rigid body’s forces). Pinned particles ignore it.

Source

pub fn add_particle_force(&mut self, i: usize, force: Vector, wake_up: bool)

Adds force to the user force of the i-th particle (persistent until Self::reset_forces).

Source

pub fn reset_forces(&mut self, wake_up: bool)

Clears the user forces of every particle.

Source

pub fn apply_impulse(&mut self, impulse: Vector, wake_up: bool)

Applies a linear velocity change (impulse per unit of mass) to every free particle of this soft body: the whole body is kicked at the same velocity.

Source

pub fn apply_particle_impulse( &mut self, i: usize, impulse: Vector, wake_up: bool, )

Applies an impulse to the i-th particle (its velocity changes by impulse / mass; pinned particles ignore it).

Source

pub fn apply_impulse_at_point( &mut self, impulse: Vector, point: Vector, falloff_radius: f32, wake_up: bool, )

Applies impulse to every free particle within falloff_radius of world point point, scaled linearly to zero at that radius and divided by the particle’s mass; a falloff_radius of zero or less gives every particle the whole impulse.

Source

pub fn apply_radial_impulse( &mut self, center: Vector, magnitude: f32, falloff_radius: f32, wake_up: bool, )

Applies an impulse of magnitude pointing away from world point center to every free particle within falloff_radius, scaled linearly to zero at that radius (a particle on the center gets nothing); a falloff_radius of zero or less pushes every particle fully.

Source§

impl SoftBody

Source

pub fn reset_plasticity(&mut self)

Resets every plastic flow (edge rest lengths, dihedral rest angles, cell rest shapes, particle rest positions) to the creation state; the particles stay put and spring back elastically from there.

Source§

impl SoftBody

Source

pub fn tear_edge(&mut self, i: usize)

Marks the i-th edge as torn: the tear is applied at the end of the next step (use crate::dynamics::SoftBodySet::tear to tear immediately). A tear loses no material (see Self::rest_measure); pieces it disconnects become their own bodies (Self::origin).

Source

pub fn tear_cell(&mut self, i: usize)

Marks the i-th cell as torn: the tear is applied at the end of the next step. No cell is removed: one particle (nearest the centroid first) splits along the plane perpendicular to the cell’s principal rest stretch direction (see Self::tear_edge).

Source

pub fn has_pending_tears(&self) -> bool

Whether some element has a pending tear mark.

Source

pub fn crossing_elements(&self, blade: &[Vector; 3]) -> (Vec<u32>, Vec<u32>)

The elements a blade (world segment in 2D, triangle in 3D) meets, as (edge indices, cell indices): an edge when they intersect (endpoints included), a cell when one of its edges does. A preview of crate::dynamics::SoftBodySet::cut, which removes none of them.

Source§

impl SoftBody

Source

pub fn connected_pieces(&self) -> Vec<Vec<u32>>

The connected pieces of this soft body (particles joined by its elements), each sorted and ordered by first particle; linear in the elements. Tears split pieces off as soft bodies (Self::tear_edge), so only a body inserted as disconnected parts has more than one.

Source

pub fn seeded_components( &self, members: Option<&[u32]>, seeds: &[[u32; 2]], ) -> Vec<Vec<u32>>

The components of the body’s element graph restricted to members (all particles when None) that contain a particle of some seeds pair (the pairs a tear or cut separated, see crate::dynamics::SoftBodyTearEvent::split_particles), sorted; empty unless at least two.

Source

pub fn mass_of(&self, particles: &[u32]) -> f32

The summed nominal mass of the given particles (out-of-range indices ignored).

Source

pub fn set_edge_tear_resistance(&mut self, i: usize, resistance: f32)

Sets the tear-threshold multiplier of the i-th edge (see crate::dynamics::SoftBodyEdge::tear_resistance); 1.0 restores the material’s threshold.

Source

pub fn set_cell_tear_resistance(&mut self, i: usize, resistance: f32)

Sets the tear-threshold multiplier of the i-th cell (see crate::dynamics::SoftBodyCell::tear_resistance); 1.0 restores the material’s threshold.

Source

pub fn set_particle_damaged(&mut self, i: usize, damaged: bool)

Marks the i-th particle as damaged, or repairs it (see crate::dynamics::SoftBodyParticle::is_damaged): a way to seed a weak spot where a tear should start.

Source§

impl SoftBody

Source

pub fn rest_measure(&self) -> f32

The total rest measure of this body’s measure elements, by priority: the rest area (2D) or volume (3D) of its cells, else (3D) of its surface triangles, else the rest length of its structural edges, before plastic flow; 0.0 without any, and no tear or cut changes it.

Source

pub fn rest_measure_of(&self, particles: &[u32]) -> f32

The rest measure of the measure elements whose vertices all belong to the given sorted particle set (see Self::rest_measure): the measure of a piece of the body.

Source§

impl SoftBody

Source

pub fn validate_topology(&self) -> Result<(), String>

Checks the topology and its derived tables (element indices, every particle in a measure element (see Self::rest_measure), surface rings and incidence, owning cells, the 3D edge table, the coloring) for consistency; returns the first inconsistency found.

Trait Implementations§

Source§

impl Clone for SoftBody

Source§

fn clone(&self) -> SoftBody

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SoftBody

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<SoftBodyBuilder> for SoftBody

Source§

fn from(builder: SoftBodyBuilder) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &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)

Converts &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> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> MaybeSync for T
where T: Sync + ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.