Skip to content

Commit

Permalink
feat: add RigidBody::copy_from and Collider::copy_from
Browse files Browse the repository at this point in the history
Closes #595
  • Loading branch information
sebcrozet committed Mar 23, 2024
1 parent 6886f8f commit cd9fb83
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

- Add `RigidBody::predict_position_using_velocity` to predict the next position of the rigid-body
based only on its current velocity.
- Add `Collider::copy_from` to copy most collider attributes to an existing collider.
- Add `RigidBody::copy_from` to copy most rigid-body attributes to an existing rigid-body.

## v0.18.0 (24 Jan. 2024)

Expand Down
55 changes: 55 additions & 0 deletions src/dynamics/rigid_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,61 @@ impl RigidBody {
self.ids = Default::default();
}

/// Copy all the characteristics from `other` to `self`.
///
/// If you have a mutable reference to a rigid-body `rigid_body: &mut RigidBody`, attempting to
/// assign it a whole new rigid-body instance, e.g., `*rigid_body = RigidBodyBuilder::dynamic().build()`,
/// will crash due to some internal indices being overwritten. Instead, use
/// `rigid_body.copy_from(&RigidBodyBuilder::dynamic().build())`.
///
/// This method will allow you to set most characteristics of this rigid-body from another
/// rigid-body instance without causing any breakage.
///
/// This method **cannot** be used for editing the list of colliders attached to this rigid-body.
/// Therefore, the list of colliders attached to `self` won’t be replaced by the one attached
/// to `other`.
///
/// The pose of `other` will only copied into `self` if `self` doesn’t have a parent (if it has
/// a parent, its position is directly controlled by the parent rigid-body).
pub fn copy_from(&mut self, other: &RigidBody) {
// NOTE: we deconstruct the rigid-body struct to be sure we don’t forget to
// add some copies here if we add more field to RigidBody in the future.
let RigidBody {
pos,
mprops,
integrated_vels,
vels,
damping,
forces,
ccd,
ids: _ids, // Internal ids must not be overwritten.
colliders: _colliders, // This function cannot be used to edit collider sets.
activation,
changes: _changes, // Will be set to ALL.
body_type,
dominance,
enabled,
additional_solver_iterations,
user_data,
} = other;

self.pos = *pos;
self.mprops = mprops.clone();
self.integrated_vels = *integrated_vels;
self.vels = *vels;
self.damping = *damping;
self.forces = *forces;
self.ccd = *ccd;
self.activation = *activation;
self.body_type = *body_type;
self.dominance = *dominance;
self.enabled = *enabled;
self.additional_solver_iterations = *additional_solver_iterations;
self.user_data = *user_data;

self.changes = RigidBodyChanges::all();
}

/// Set the additional number of solver iterations run for this rigid-body and
/// everything interacting with it.
///
Expand Down
47 changes: 47 additions & 0 deletions src/geometry/collider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,53 @@ impl Collider {
self.coll_type.is_sensor()
}

/// Copy all the characteristics from `other` to `self`.
///
/// If you have a mutable reference to a collider `collider: &mut Collider`, attempting to
/// assign it a whole new collider instance, e.g., `*collider = ColliderBuilder::ball(0.5).build()`,
/// will crash due to some internal indices being overwritten. Instead, use
/// `collider.copy_from(&ColliderBuilder::ball(0.5).build())`.
///
/// This method will allow you to set most characteristics of this collider from another
/// collider instance without causing any breakage.
///
/// This method **cannot** be used for reparenting a collider. Therefore, the parent of the
/// `other` (if any), as well as its relative position to that parent will not be copied into
/// `self`.
///
/// The pose of `other` will only copied into `self` if `self` doesn’t have a parent (if it has
/// a parent, its position is directly controlled by the parent rigid-body).
pub fn copy_from(&mut self, other: &Collider) {
// NOTE: we deconstruct the collider struct to be sure we don’t forget to
// add some copies here if we add more field to Collider in the future.
let Collider {
coll_type,
shape,
mprops,
changes: _changes, // Will be set to ALL.
parent: _parent, // This function cannot be used to reparent the collider.
pos,
material,
flags,
bf_data: _bf_data, // Internal ids must not be overwritten.
contact_force_event_threshold,
user_data,
} = other;

if self.parent.is_none() {
self.pos = *pos;
}

self.coll_type = *coll_type;
self.shape = shape.clone();
self.mprops = mprops.clone();
self.material = *material;
self.contact_force_event_threshold = *contact_force_event_threshold;
self.user_data = *user_data;
self.flags = *flags;
self.changes = ColliderChanges::all();
}

/// The physics hooks enabled for this collider.
pub fn active_hooks(&self) -> ActiveHooks {
self.flags.active_hooks
Expand Down

0 comments on commit cd9fb83

Please sign in to comment.