Left-over physics bodies not getting removed?

I’ve read the topics on how to remove physical bodies, and have the following code:

for (int i = 0; i < rootNode.getChildren().size(); i++) {
Spatial b = rootNode.getChild(i);
if(b.getName().equals(“cannon ball”)){
RigidBodyControl myBody = b.getControl(RigidBodyControl.class);
getPhysicsSpace().remove(myBody);
b.removeFromParent();
}
}

I have a “maze” and you can shoot balls into the maze. When a ball hits the finish line, the above code happens so I can clear all the balls from the board and reload the maze.

What is happening is that not all the balls always get removed. Sometimes they do, but sometimes like 1 or 2 balls will still be there after the maze is reloaded.

What’s really odd is that if TWO balls are still remaining, those two balls interacts and collide with each other, but any NEW balls I shoot into the maze go right THRU those left-over balls. It’s like they lost their physical bodies for NEW balls, but yet they still collide with each other.

Either way, I want to remove ALL balls from my maze. What am I doing wrong? Should I put all my balls into their own node (not rootNode) to make it easier to remove them? why would some balls be randomly left over with some sort of different-plane body presense? hehe.

thanks!

Thought experiment…

First pass through the loop i is 0.

Let’s say you remove the first (0th) element and at the end of the loop i gets incremented.

Which child do you think you are pointing to now?

2 Likes

oh, i’m screwing up the list by removing it! d’oh… I tested your idea by changing my code to do this:

myBody.setEnabled(false);
b.setCullHint(CullHint.Always);

that effectively hid all the balls correctly and never missed any of them, cuz I am now not removing anything from the rootNode. This isn’t my solution, I just wanted to see if I understood you correctly as to what my problem was.

Ok, thanks for explaining it to me, I’ll work on a better solution. maybe putting all the balls on their own node and then using getChildren() to get a list of all the spatials to remove. I know I can do detachAllChildren but that doesn’t remove all the physical bodies. I’ll work on it, thanks for the insight!

Ah, this seems to work nice and quick and well and looks much cleaner!

for(Spatial child : ballNode.getChildren()) {
RigidBodyControl myBody = child.getControl(RigidBodyControl.class);
getPhysicsSpace().remove(myBody);
child.removeFromParent();
}

Thanks!

@feelie75 said: Ah, this seems to work nice and quick and well and looks much cleaner!

for(Spatial child : ballNode.getChildren()) {
RigidBodyControl myBody = child.getControl(RigidBodyControl.class);
getPhysicsSpace().remove(myBody);
child.removeFromParent();
}

Thanks!

Yep! Great pains were taking to make sure that the iterator would still work if items were removed while iterating. :slight_smile: (Well, not that great.)

1 Like

Annother often seen solution for this problem is, to create a list for ToRemove, make the loop and collect everything there, then in the second phase you only loop trough the toRemove List and kill everything in there.

Eg
[java]
final LightList lList = model.getLocalLightList();
final ArrayList<Light> toRemove = new ArrayList<Light>();
for (final Light l : lList) {
toRemove.add(l);
}
for (final Light l : toRemove) {
model.removeLight(l);
}
[/java]

As at lieat at the point of writing this the llist iterator only threw a ConcurrentModifictationException when trying to remove directly.

@Empire Phoenix said: Annother often seen solution for this problem is, to create a list for ToRemove, make the loop and collect everything there, then in the second phase you only loop trough the toRemove List and kill everything in there.

Eg
[java]
final LightList lList = model.getLocalLightList();
final ArrayList<Light> toRemove = new ArrayList<Light>();
for (final Light l : lList) {
toRemove.add(l);
}
for (final Light l : toRemove) {
model.removeLight(l);
}
[/java]

As at lieat at the point of writing this the llist iterator only threw a ConcurrentModifictationException when trying to remove directly.

Yeah, I don’t think lights have been changed to SafeArrayList yet.