Bullet physics updating problem

Hi. I’m trying to remove a cube spatial from the rootNode and from my bullet physics as well so that not only will it not be displayed but my player node will be able to travel through it. The cube correctly disappears from sight for 5 seconds. I did not have any luck with updating the physics or removing the spatial from the physics however - not sure if I’m failing at both or just one. This is how I’m doing the physics:

[java]

if (stateManager.hasState(bulletAppState)) {

stateManager.detach(bulletAppState);

}

bulletAppState = new BulletAppState();

bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);

stateManager.attach(bulletAppState);



CompoundCollisionShape sceneShape =

(CompoundCollisionShape) CollisionShapeFactory.createMeshShape(shootables);

landscape = new PhysicsNode(shootables, sceneShape, 0);



player = new PhysicsCharacterNode(new CapsuleCollisionShape(0.8f, 2f, 1), .1f);

player.setJumpSpeed(15);

player.setFallSpeed(30);

player.setGravity(30);

player.setLocalTranslation(startLoc);

// attach to root node

rootNode.attachChild(landscape);

rootNode.attachChild(player);

bulletAppState.getPhysicsSpace().add(landscape);

bulletAppState.getPhysicsSpace().add(player);

[/java]

shootables is the node that contains all the objects that I do picking on when I shoot. Now my problem is that I don’t know what I’m supposed to do to remove the cube spatial and be able to pass through it. This is what I’m currently doing to remove it - which obviously doesn’t work



[java]

private void makeRespawnThread(Geometry geom) {

final Geometry g = geom;

new Thread(new Runnable() {

public void run() {

shootablesAttach(g);

smashed.attachChild(g);

try { // sleep

Thread.currentThread().sleep(5000);

} catch (Exception e) {

System.out.println(“Sleeping failed!”);

}

shootablesAttach(g);

smashed.detachChild(g);

rootNode.updateGeometricState();

}

}).start();

}

[/java]

Smashed is just a node I’m using to keep track of all the cubes that are removed from the game at a given time. The cube should disappear and then reappear after 5 seconds. The multithreading is the reason I set ThreadingType to PARALLEL - I hope this is correct.

To Update the bullet physics I tried

[java]bulletAppState.update(tpf);[/java]

in my simpleUpdate(float tpf) loop but that didn’t do the trick.

Any help would be greatly appreciated - be it pertaining to my question or some other mistakes I’ve made in the code above.

You have to call bulletAppState.getPhysicsSpace().remove(box); somewhere to remove the physics control from the physics space. the appstate is already updated automatically, so doing the update thing is not good.

Thanks normen!

I’ll give it a try.

When I try that, this is what I get:

[java]

java.lang.UnsupportedOperationException: Cannot remove this kind of object from the physics space.

at com.jme3.bullet.PhysicsSpace.remove(PhysicsSpace.java:498)

at mygame.Engine$3.run(Engine.java:682)

at java.lang.Thread.run(Thread.java:662)

[/java]

I’m trying to remove a Geometry object that I obtain by picking.

So you are trying to remove the wrong object, it has to be the PhysicsNode (or the spatial with the physics control in the current svn version).

I see. Is there any way to find the original spatial from the geometry that is returned by picking?

EDIT:

I guess I could remove the entire physicsNode, then make a new one without the object I wanted to remove and add the new physicsNode to bulletAppState again. Something like this:

[java]

bulletAppState.getPhysicsSpace().remove(landscape);

shootablesDetach(g);

smashed.attachChild(g);

landscape = new PhysicsNode(shootables, sceneShape, 0);

bulletAppState.getPhysicsSpace().add(landscape);

[/java]

This gives me a NP from the PostRenderer:

[java]

29-01-2011 02:11:07 com.jme3.bullet.BulletAppState postRender

SEVERE: null

java.util.concurrent.ExecutionException: java.lang.NullPointerException

[/java]

Its easy to get geometry info from physics collisions but not vice versa as the geometry system doesnt know anything about physics controls.

In that case I’m not sure what I’m supposed to remove. I guess I could make some internal datastructure to keep track of which spatials are where. I was hoping however that it was natively possible to remove something that was obtained by picking (A CollisionResult) from the physics.

I can’t find any resources that explains how this is done.

I hope you’re not fed up with me just yet :slight_smile:

You can move your way up through the scenegraph from the geometry with getParent() and check if thats a PhysicsNode

Thanks normen. I think I get it now - Never thought about traversing the scenegraph like that :slight_smile:

I can find the right PhysicsNode but when I remove it from bulletAppState’s PhysicsSpace I fall through all spatials. Maybe I’m doing it wrong. Here’s the code:

[java]

private void makeRespawnThread(Geometry geom) {

final Geometry g = geom;

//find PhysicsNode

Node n = g.getParent();

while (!(n instanceof PhysicsNode)) {

n = n.getParent();

if (n == null) {

return;

}

}

final Node finalNode = n;

new Thread(new Runnable() {

public void run() {

shootablesDetach(g);

bulletAppState.getPhysicsSpace().remove(finalNode);

smashedTxt.setText(“SMASHES nLEFT: n” + --smashesLeft);

try { // sleep

Thread.currentThread().sleep(blockRespawnTime);

} catch (Exception e) {

System.out.println(“Sleeping failed!”);

}

shootablesAttach(g);

bulletAppState.getPhysicsSpace().add(finalNode);

smashedTxt.setText(“SMASHES nLEFT: n” + ++smashesLeft);

}

}).start();

}

[/java]

Oh my god! You are spawning a thread and modify stuff on the scenegraph and physics space on it! Thats baaaaaaaad.

It was the only way I could think of to get cubes to disappear for 5 seconds and then respawn. Is there a smarter way?

And yeah, I kinda figured it was bad because I’ve been having a hell of a time trying to update everything because I didn’t know when something would be changed.

When you shoot and the collision happens, just do this on the geometry:

[java]

Node n = g.getParent();

while (!(n instanceof PhysicsNode)) {

n = n.getParent();

if (n == null) {

return;

}

}

//maybe check if its not the floor

if(!"Floor".equals(n.getName())){

physicsSpace.remove(n);

)

n.detachFromParent();

[/java]

The reason I introduced more threads was to add the node to the rootNode and physics again after 5 seconds. I really don’t see how to do that without more threads.

To have some kind of timer just increment some float with the tpf and then when its above 5000, execute your task:

[java]

float timer=0;

public void simpleUpdate(float tpf){

timer+=tpf;

if(timer>5000){

addNodes();

timer=0;

}

}

[/java]



If you want to use threads, do everything thats modifying objects on the live scenegraph or the physics system like this:

[snippet id=“10”]

I think I’ll try the first example. I’m not really interested in using multithreading, I just wanted it to work and the first example seems the simplest.

Thanks for a very detailed answer normen.

Hey nomen. Everything works now :slight_smile:

I got rid of all the threads which means I could get rid of all the updates as well. It all runs much smoother now.

Great idea using simpleUpdate’s tpf as a timer.

Thanks a lot man.