Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix shape modification not updating graphics in testbed #708

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
}
8 changes: 6 additions & 2 deletions src_testbed/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,18 @@ impl GraphicsManager {
collider: ColliderHandle,
) {
let body = body.unwrap_or(RigidBodyHandle::invalid());
if let Some(sns) = self.b2sn.get_mut(&body) {
for sn in sns.iter_mut() {
if let Some(sns) = self.b2sn.remove(&body) {
let mut new_sns = vec![];
for sn in sns.into_iter() {
if let Some(sn_c) = sn.collider {
if sn_c == collider {
commands.entity(sn.entity).despawn();
} else {
new_sns.push(sn);
}
}
}
self.b2sn.insert(body, new_sns);
Comment on lines +81 to +92
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if let Some(sns) = self.b2sn.remove(&body) {
let mut new_sns = vec![];
for sn in sns.into_iter() {
if let Some(sn_c) = sn.collider {
if sn_c == collider {
commands.entity(sn.entity).despawn();
} else {
new_sns.push(sn);
}
}
}
self.b2sn.insert(body, new_sns);
if let Some(mut sns) = self.b2sn.remove(&body) {
sns = sns
.into_iter()
.filter(|sn| {
let Some(sn_c) = sn.collider else {
return false;
};
if sn_c == collider {
commands.entity(sn.entity).despawn();
return false;
} else {
return true;
}
})
.collect();
self.b2sn.insert(body, sns);
}

Small nitpick, I did that just to help me understand the change, not sure if which is better, don´t worry about it I'll merge one or the other after discussion with seb.

}
}

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

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 @@ -507,6 +500,18 @@ impl<'a, 'b, 'c, 'd, 'e, 'f> TestbedGraphics<'a, 'b, 'c, 'd, 'e, 'f> {
)
}

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