Skip to content

Commit

Permalink
Fix shape modification not updating graphics in testbed (#708)
Browse files Browse the repository at this point in the history
* Fix shape modification not updating graphics in testbed

* Add update collider to Testbed

* chore: lint shape_modifications3

* chore: simplify GraphicsManager::remove_collider_nodes

---------

Co-authored-by: Sébastien Crozet <[email protected]>
  • Loading branch information
agarret7 and sebcrozet authored Jan 8, 2025
1 parent 2ed1934 commit 552cfeb
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 11 deletions.
37 changes: 35 additions & 2 deletions examples3d/debug_shape_modification3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,32 @@ pub fn init_world(testbed: &mut Testbed) {
let collider = ColliderBuilder::ball(ball_rad).density(100.0);
let ball_coll_handle = colliders.insert_with_parent(collider, ball_handle, &mut bodies);

/*
* Colliders without bodies
*/
let shape_size = 3.0;
let static_collider =
ColliderBuilder::ball(shape_size).translation(vector![-15.0, shape_size, 18.0]);
colliders.insert(static_collider);

let shapes = [
SharedShape::ball(shape_size),
SharedShape::cuboid(shape_size, shape_size, shape_size),
SharedShape::cone(shape_size, shape_size),
SharedShape::cylinder(shape_size, shape_size),
];
let mut shape_idx = 0;
let shapeshifting_collider = ColliderBuilder::new(shapes[shape_idx].clone())
.translation(vector![-15.0, shape_size, 9.0]);
let shapeshifting_coll_handle = colliders.insert(shapeshifting_collider);

let mut linvel = Vector::zeros();
let mut angvel = Vector::zeros();
let mut pos = Isometry::identity();
let mut step = 0;
let snapped_frame = 51;

testbed.add_callback(move |_, physics, _, _| {
testbed.add_callback(move |mut gfx, physics, _, _| {
step += 1;

// Snap the ball velocity or restore it.
Expand All @@ -53,6 +72,15 @@ pub fn init_world(testbed: &mut Testbed) {
pos = *ball.position();
}

let shapeshifting_coll = physics
.colliders
.get_mut(shapeshifting_coll_handle)
.unwrap();
if step % 50 == 0 {
shape_idx = (shape_idx + 1) % 4;
shapeshifting_coll.set_shape(shapes[shape_idx].clone())
}

if step == 100 {
ball.set_linvel(linvel, true);
ball.set_angvel(angvel, true);
Expand All @@ -62,6 +90,11 @@ pub fn init_world(testbed: &mut Testbed) {

let ball_coll = physics.colliders.get_mut(ball_coll_handle).unwrap();
ball_coll.set_shape(SharedShape::ball(ball_rad * step as f32 * 2.0));

if let Some(gfx) = &mut gfx {
gfx.update_collider(ball_coll_handle, &physics.colliders);
gfx.update_collider(shapeshifting_coll_handle, &physics.colliders);
}
});

/*
Expand Down Expand Up @@ -111,5 +144,5 @@ pub fn init_world(testbed: &mut Testbed) {
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
testbed.look_at(point![10.0, 10.0, 10.0], Point::origin());
testbed.look_at(point![40.0, 40.0, 40.0], Point::origin());
}
7 changes: 5 additions & 2 deletions src_testbed/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,16 @@ impl GraphicsManager {
) {
let body = body.unwrap_or(RigidBodyHandle::invalid());
if let Some(sns) = self.b2sn.get_mut(&body) {
for sn in sns.iter_mut() {
sns.retain(|sn| {
if let Some(sn_c) = sn.collider {
if sn_c == collider {
commands.entity(sn.entity).despawn();
return false;
}
}
}

true
});
}
}

Expand Down
19 changes: 12 additions & 7 deletions src_testbed/testbed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,13 +492,6 @@ impl TestbedGraphics<'_, '_, '_, '_, '_, '_> {
)
}

pub fn remove_collider(&mut self, handle: ColliderHandle, colliders: &ColliderSet) {
if let Some(parent_handle) = colliders.get(handle).map(|c| c.parent()) {
self.graphics
.remove_collider_nodes(&mut *self.commands, parent_handle, handle)
}
}

pub fn remove_body(&mut self, handle: RigidBodyHandle) {
self.graphics.remove_body_nodes(&mut *self.commands, handle)
}
Expand All @@ -513,6 +506,18 @@ impl TestbedGraphics<'_, '_, '_, '_, '_, '_> {
)
}

pub fn remove_collider(&mut self, handle: ColliderHandle, colliders: &ColliderSet) {
if let Some(parent_handle) = colliders.get(handle).map(|c| c.parent()) {
self.graphics
.remove_collider_nodes(&mut *self.commands, parent_handle, handle)
}
}

pub fn update_collider(&mut self, handle: ColliderHandle, colliders: &ColliderSet) {
self.remove_collider(handle, colliders);
self.add_collider(handle, colliders);
}

pub fn keys(&self) -> &ButtonInput<KeyCode> {
self.keys
}
Expand Down

0 comments on commit 552cfeb

Please sign in to comment.