Ok, Here is a test case.
It show really interesting things.
Let me describe how it works :
- a big Yellow box is there as a reference : it’s not part of the batch
- 2 small boxes at the center :
- The pink is a node containing a box
- The red is simply a box
=> both are batched at the init of the application
- 2 horizontal boxes activated/deactivated by keyboard arrows left/right
- these boxes are simple boxes
- 2 vertical boxes activated/deactivated by keyboard arrows up/down
- these boxes are nodes containing a box
- Enter key calls for the batch() method
Each box has a RigidBodyControl with mass 0.
What we can see a few things :
- Physics on boxes are lost during batching
- Physics on nodes are kept during batching
- Nodes cannot be removed from the batch
- Boxes can be removed from the batch
Additionally, when we remove a box, previously removed nodes are also removed on batching…
Here is the code :
[java]
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.BatchNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PhysicBatchTest extends SimpleApplication {
public static void main(String[] args) {
Logger.getLogger("").setLevel(Level.WARNING);
Logger.getLogger(“com.jme3.bullet.PhysicsSpace”).setLevel(Level.ALL);
Logger.getLogger(“com.jme3.scene.BatchNode”).setLevel(Level.ALL);
PhysicBatchTest app = new PhysicBatchTest();
app.start(); // start the game
}
public BatchNode batch;
public BulletAppState physics;
protected Box b2;
protected Spatial h,b,g,d;
@Override
public void simpleInitApp() {
stateManager.attach(physics = new BulletAppState());
physics.getPhysicsSpace().enableDebug(assetManager);
Box box = new Box(1, 1, 1);
rootNode.attachChild(buildBox(ColorRGBA.Yellow, 0, 0, -3, box, false));
batch = new BatchNode();
b2 = new Box(0.1f, 0.1f, 0.1f);
batch.attachChild(buildBox(ColorRGBA.Red,-0.11f,0,0, b2, false));
batch.attachChild(buildBox(ColorRGBA.Pink,0.11f,0,0, b2, true));
rootNode.attachChild(batch);
batch.batch();
flyCam.setMoveSpeed(60);
inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Enter", new KeyTrigger(KeyInput.KEY_RETURN));
inputManager.addListener(actionListener, new String[]{"Left", "Right", "Up", "Down", "Enter"});
}
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals(“Left”) && keyPressed) {
if (g == null)
batch.attachChild(g = buildBox(ColorRGBA.Red,-1.7f,0,0, b2, false));
else {
g.removeFromParent();
g = null;
}
}
if (name.equals(“Right”) && keyPressed) {
if (d == null)
batch.attachChild(d = buildBox(ColorRGBA.Red,+1.7f,0,0, b2, false));
else {
d.removeFromParent();
d = null;
}
}
if (name.equals(“Up”) && keyPressed) {
if (h == null)
batch.attachChild(h = buildBox(ColorRGBA.Red,0,+1.7f,0, b2, true));
else {
h.removeFromParent();
h = null;
}
}
if (name.equals(“Down”) && keyPressed) {
if (b == null)
batch.attachChild(b = buildBox(ColorRGBA.Red,0,-1.7f,0, b2, true));
else {
b.removeFromParent();
b = null;
}
}
if (name.equals(“Enter”) && keyPressed) {
batch.batch();
}
}
};
protected Spatial buildBox(ColorRGBA col, float x, float y, float z, Box shape, boolean dummy) {
RigidBodyControl phy;
Geometry geom = new Geometry(“Box”, shape);
Material mat2 = new Material(assetManager,“Common/MatDefs/Misc/Unshaded.j3md”);
mat2.setColor(“Color”, col);
geom.setMaterial(mat2);
geom.setLocalTranslation(x,y,z);
if (dummy) {
Node n = new Node(“dummy”);
n.attachChild(geom);
n.addControl(phy = new RigidBodyControl(0));
physics.getPhysicsSpace().add(phy);
return n;
} else {
geom.addControl(phy = new RigidBodyControl(0));
physics.getPhysicsSpace().add(phy);
return geom;
}
}
}
[/java]