Hi everyone,
I have encountered an IndexOutOfBoundsException from BatchNode, which I think is the same issue others have seen - but this time I’ve been able to reproduce it with a SSCE.
Exception:
java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkBounds(Buffer.java:567)
at java.nio.DirectFloatBufferU.get(DirectFloatBufferU.java:265)
at com.jme3.scene.BatchNode.doTransforms(BatchNode.java:548)
at com.jme3.scene.BatchNode.updateSubBatch(BatchNode.java:152)
at com.jme3.scene.BatchNode.onTransformChange(BatchNode.java:104)
at com.jme3.scene.Geometry.updateWorldTransforms(Geometry.java:326)
at com.jme3.scene.Spatial.updateGeometricState(Spatial.java:911)
at com.jme3.scene.Node.updateGeometricState(Node.java:269)
at com.jme3.scene.Node.updateGeometricState(Node.java:269)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:265)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:153)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:193)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:234)
at java.lang.Thread.run(Thread.java:745)
SSCE:
import com.jme3.app.SimpleApplication;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.BatchNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
public class TestBatchNodeDifferentShapes extends SimpleApplication {
public static void main(String[] args){
TestBatchNodeDifferentShapes app = new TestBatchNodeDifferentShapes();
app.setShowSettings(false); // disable the initial settings dialog window
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(30);
addAmbientLight();
addDirectionalLight();
addFloor();
BatchNode theBatchNode = new BatchNode("theBatchNode");
rootNode.attachChild(theBatchNode);
Material boxMat = createLightingMaterial(ColorRGBA.Yellow);
Material sphereMat = createLightingMaterial(ColorRGBA.Pink);
Mesh boxMesh = new Box(0.7f, 0.7f, 0.7f);
Mesh sphereMesh = new Sphere(32, 32, 1f);
// 1) add spheres
for (int z = 0; z < 10; z++) {
Geometry sphere = new Geometry("sphere", sphereMesh);
sphere.setMaterial(sphereMat);
sphere.setLocalTranslation(new Vector3f(-2, -3, -(z * 4)));
theBatchNode.attachChild(sphere);
}
theBatchNode.batch();
// 2) add boxes
for (int z = 0; z < 10; z++) {
Geometry box = new Geometry("box", boxMesh);
box.setMaterial(boxMat);
box.setLocalTranslation(new Vector3f(+2, -3, -(z * 4)));
theBatchNode.attachChild(box);
}
theBatchNode.batch();
}
private Material createLightingMaterial(ColorRGBA color) {
Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
material.setBoolean("UseMaterialColors", true);
material.setColor("Ambient", color);
material.setColor("Diffuse", color);
material.setColor("Specular", color);
material.setFloat("Shininess", 1.0f);
return material;
}
private void addFloor() {
Geometry floor = new Geometry("floor", new Box(20, 0.1f, 40));
floor.setMaterial(createLightingMaterial(ColorRGBA.Gray));
floor.setLocalTranslation(5, -5, 0);
floor.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
rootNode.attachChild(floor);
}
private void addAmbientLight() {
AmbientLight ambientLight = new AmbientLight(new ColorRGBA(0.1f, 0.1f, 0.1f, 1.0f));
rootNode.addLight(ambientLight);
}
private void addDirectionalLight() {
DirectionalLight light = new DirectionalLight();
light.setColor(ColorRGBA.White);
light.setDirection(new Vector3f(-1, -2, -0.5f));
rootNode.addLight(light);
}
}
The problem only happens if I batch the spheres, then the boxes. If I do it the other way around then the exception does not occur. I thought BatchNode ought to be able to handle this case, even though you might reasonably suggest that I don’t call batch() until all the spatials are added.
I get the same results from 3.3.2-stable and from master.
Probably related topics: