I just updated, and my CLODed meshes that worked fine before now cause this exception:
java.lang.IndexOutOfBoundsException: 128
at java.nio.DirectFloatBufferU.get(DirectFloatBufferU.java:209)
at com.jme.scene.lod.ClodCreator.reorder(ClodCreator.java:522)
at com.jme.scene.lod.ClodCreator.<init>(ClodCreator.java:208)
at com.jme.scene.lod.ClodMesh.create(ClodMesh.java:146)
at com.jme.scene.lod.ClodMesh.<init>(ClodMesh.java:127)
at com.jme.scene.lod.ClodMesh.<init>(ClodMesh.java:101)
at com.jme.scene.lod.AreaClodMesh.<init>(AreaClodMesh.java:98)
at net.java.dev.aircarrier.planes.SimplePlaneModel.clodinate(SimplePlaneModel.java:228)
at net.java.dev.aircarrier.planes.SimplePlaneModel.clodinate(SimplePlaneModel.java:226)
at net.java.dev.aircarrier.planes.SimplePlaneModel.<init>(SimplePlaneModel.java:64)
at net.java.dev.aircarrier.planes.HammerheadModel.<init>(HammerheadModel.java:39)
at net.java.dev.aircarrier.CarrierSimpleLevelManagers.simpleInitGame(CarrierSimpleLevelManagers.java:565)
at net.java.dev.aircarrier.CarrierGame.initGame(CarrierGame.java:560)
at com.jme.app.BaseGame.start(BaseGame.java:56)
at net.java.dev.aircarrier.CarrierSimpleLevelManagers.main(CarrierSimpleLevelManagers.java:179)
The "clodinate" code looks like this, and is called on the root of a loaded mesh tree:
public void clodinate(Node model) {
List<Spatial> children = model.getChildren();
if (children != null) {
for (Spatial c : children) {
if (c instanceof Node) {
clodinate((Node)c);
} else if (c instanceof TriMesh) {
AreaClodMesh clodMesh = new AreaClodMesh(c.getName(), (TriMesh)c, null);
clodMesh.setTrisPerPixel(0.05f);
model.detachChild(c);
model.attachChild(clodMesh);
}
}
}
}
I haven't had a chance to look at this in detail, because I have to go to work :| I thought I would post it anyway since I ran exactly the same code just before and after the update so it seems likely to be a bug. I think it must be something pretty recent as well, since I was nearly up to date before I updated.
As the clod creator would crash on TriMeshes that has neither a color or texture buffer. I look at the ClodCreator itself and didn't see anything that had changed radically between latest and previous revisions, so potentially its something that is farther down in the engine?
Ah right… yup that is definitely where the problem is. In fact… if I don't use clod at all, it still gets an exception.
So, it turns out the problem is with JmeBinaryReader, which creates zero length buffers as "default" when loading. Some of these are then left over, and ClodCreator doesn't like this, since it only checks for null buffers, not zero length buffers. Even if you don't use ClodCreator, you get an exception at com.jme.renderer.lwjgl.LWJGLRenderer.predrawGeometry(LWJGLRenderer.java:1313) when the code tries to use the color buffer, assuming it is big enough, and of course it isn't
So… as a quick fix, I altered JmeBinaryReader to recursively strip away any zero length color and texture buffers after loading a node (replacing them with null), and this fixes everything
I'm just going to have a look through to see if there is a neater way of fixing JBR, I think there must be
Yup I think I found the right way to fix it, but I could be wrong. This fixes the problem for me, without any obvious side effects anyway
The following is (hopefully) a patch to fix JmeBinaryReader. Basically just set null color and texture buffers instead of zero-length buffers, at two places in method readBegining().
More than likely the clod stuff is related to changes made in using limit(), remaining() and capacity(), etc. If I get a chance this weekend, I'll take a look at that.