Line meshes + terrain = bad sorting, also exceptions with TerrainLOD

Just messing with some 3.1 stuff, I’ve hit a couple of bugs. The first of the two is something I had problems with in 3.0 Stable as well, and even made a post about but never got help (see here: Inconsistant Comparison Function with primitive meshes). It seems that any time I have a Geometry using a Line mesh and a TerrainQuad in the same scene, I get this exception:

Oct 17, 2015 3:31:39 AM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.UnsupportedOperationException: Compare function result changed! Make sure you do not modify the scene from another thread!
at com.jme3.util.ListSort.mergeLow(ListSort.java:702)
at com.jme3.util.ListSort.mergeRuns(ListSort.java:474)
at com.jme3.util.ListSort.mergeForceCollapse(ListSort.java:423)
at com.jme3.util.ListSort.sort(ListSort.java:241)
at com.jme3.renderer.queue.GeometryList.sort(GeometryList.java:148)
at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:262)
at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:305)
at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:803)
at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:731)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1030)
at com.jme3.water.WaterFilter.preFrame(WaterFilter.java:170)
at com.jme3.post.FilterPostProcessor.preFrame(FilterPostProcessor.java:342)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1001)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1078)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:260)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:152)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:192)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:233)
at java.lang.Thread.run(Thread.java:745)

Previously I was told it was chalked up to a “user error due to bad multithreading” but both at that time and now there is 0 multithreading going on on my end; I’m just making some simple test shapes in the simpleInitApp method and getting these crashes…

…which brings me to the second problem I’ve found, which I believe might be related to the first. Often when flying over terrain (code copied straight from the Hello Terrain tutorial), I get an exception but the program doesn’t crash. Unfortunately it happens often sometimes, then rarely others, and at the time of writing the error isn’t happening. However, I do remember it having to do with FutureTask in the TerrainLODControl class… so I’m thinking some kind of problem between that multithreading and Line meshes is causing the above error. Might be me drawing conclusions where there are none, but I thought I’d mention it here just so it’s known. If I happen to get that exception again I’ll edit this post with it.

Pretty sure (99.9999%) that terrain quad internally uses threading… so that could be the issue with the sort.

It appears so, I ran across the problem again and here’s the exception:

Oct 17, 2015 4:57:35 AM com.jme3.terrain.geomipmap.TerrainLodControl updateQuadLODs
SEVERE: null
java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 0, Size: 1
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.jme3.terrain.geomipmap.TerrainLodControl.updateQuadLODs(TerrainLodControl.java:251)
at com.jme3.terrain.geomipmap.TerrainLodControl.updateLOD(TerrainLodControl.java:189)
at com.jme3.terrain.geomipmap.TerrainLodControl.controlUpdate(TerrainLodControl.java:168)
at com.jme3.scene.control.AbstractControl.update(AbstractControl.java:112)
at com.jme3.scene.Spatial.runControlUpdate(Spatial.java:661)
at com.jme3.scene.Spatial.updateLogicalState(Spatial.java:808)
at com.jme3.scene.Node.updateLogicalState(Node.java:220)
at com.jme3.scene.Node.updateLogicalState(Node.java:231)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:249)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:152)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:192)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:233)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator.calculateLod(DistanceLodCalculator.java:68)
at com.jme3.terrain.geomipmap.TerrainQuad.calculateLod(TerrainQuad.java:379)
at com.jme3.terrain.geomipmap.TerrainQuad.calculateLod(TerrainQuad.java:375)
at com.jme3.terrain.geomipmap.TerrainQuad.calculateLod(TerrainQuad.java:375)
at com.jme3.terrain.geomipmap.TerrainQuad.calculateLod(TerrainQuad.java:375)
at com.jme3.terrain.geomipmap.TerrainLodControl$UpdateLOD.call(TerrainLodControl.java:389)
at com.jme3.terrain.geomipmap.TerrainLodControl$UpdateLOD.call(TerrainLodControl.java:369)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
... 1 more

I seem to have bypassed the issue of crashing with Line meshes by just using Arrow meshes instead of Lines. Not as elegant but as long as I’m not crashing the instant the renderer kicks in it’s good enough.