MovingBlocks / Terasology

Terasology - open source voxel world
http://terasology.org
Apache License 2.0
3.67k stars 1.34k forks source link

ArrayIndexOutOfBoundsException during world creation #881

Closed MarcinSc closed 10 years ago

MarcinSc commented 10 years ago

20:22:18.654 [main] ERROR o.terasology.engine.TerasologyEngine - Uncaught exception java.lang.ArrayIndexOutOfBoundsException: -2 at com.bulletphysics.$Stack.pop$javax$vecmath$Quat4f(Unknown Source) ~[tera-bullet-1.0.0.jar:na] at com.bulletphysics.linearmath.QuaternionUtil.quatRotate(QuaternionUtil.java:87) ~[tera-bullet-1.0.0.jar:na] at org.terasology.logic.location.LocationComponent.getWorldPosition(LocationComponent.java:104) ~[classes/:na] at org.terasology.logic.location.LocationComponent.getWorldPosition(LocationComponent.java:96) ~[classes/:na] at org.terasology.world.chunks.internal.ChunkRelevanceRegion.calculateCenter(ChunkRelevanceRegion.java:130) ~[classes/:na] at org.terasology.world.chunks.internal.ChunkRelevanceRegion.update(ChunkRelevanceRegion.java:108) ~[classes/:na] at org.terasology.world.chunks.localChunkProvider.LocalChunkProvider.updateRelevance(LocalChunkProvider.java:341) ~[classes/:na] at org.terasology.world.chunks.localChunkProvider.LocalChunkProvider.update(LocalChunkProvider.java:249) ~[classes/:na] at org.terasology.rendering.world.WorldRenderer.pregenerateChunks(WorldRenderer.java:1145) ~[classes/:na] at org.terasology.engine.modes.loadProcesses.PrepareWorld.step(PrepareWorld.java:42) ~[classes/:na] at org.terasology.engine.modes.StateLoading.update(StateLoading.java:211) ~[classes/:na] at org.terasology.engine.TerasologyEngine.mainLoop(TerasologyEngine.java:734) ~[classes/:na] at org.terasology.engine.TerasologyEngine.run(TerasologyEngine.java:310) ~[classes/:na] at org.terasology.engine.Terasology.main(Terasology.java:55) [classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_21] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_21] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_21] at java.lang.reflect.Method.invoke(Method.java:601) ~[na:1.7.0_21] at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) [idea_rt.jar:na]

Cervator commented 10 years ago

This doesn't seem to happen any longer, although in part I think that's from a code workaround. Still, a tweak was made to TeraBullet to maybe clean up something related to this - don't want to forget that as we haven't actually tried using the updated TeraBullet

Josharias commented 10 years ago

I got this recently when messing around with rendering items in an inventory. Mine looked like this: java.lang.IndexOutOfBoundsException: Index: 4, Size: 4 at java.util.ArrayList.rangeCheck(ArrayList.java:604) ~[na:1.7.0_17] at java.util.ArrayList.get(ArrayList.java:382) ~[na:1.7.0_17] at com.bulletphysics.$Stack.get$javax$vecmath$Quat4f(Unknown Source) ~[tera-bullet-1.0.0.jar:na] at com.bulletphysics.linearmath.QuaternionUtil.quatRotate(QuaternionUtil.java:82) ~[tera-bullet-1.0.0.jar:na] at org.terasology.logic.location.LocationComponent.getWorldPosition(LocationComponent.java:104) ~[classes/:na] at org.terasology.rendering.logic.MeshRenderer.renderOpaque(MeshRenderer.java:256) ~[classes/:na] at org.terasology.rendering.logic.MeshRenderer.renderOpaque(MeshRenderer.java:216) ~[classes/:na] at org.terasology.rendering.world.WorldRendererLwjgl.renderWorld(WorldRendererLwjgl.java:616) ~[classes/:na] at org.terasology.rendering.world.WorldRendererLwjgl.render(WorldRendererLwjgl.java:555) ~[classes/:na] at org.terasology.engine.modes.StateIngame.render(StateIngame.java:178) ~[classes/:na] at org.terasology.engine.subsystem.lwjgl.LwjglGraphics.postUpdate(LwjglGraphics.java:119) ~[classes/:na] at org.terasology.engine.TerasologyEngine.mainLoop(TerasologyEngine.java:502) ~[classes/:na] at org.terasology.engine.TerasologyEngine.run(TerasologyEngine.java:236) ~[classes/:na] at org.terasology.engine.Terasology.main(Terasology.java:82) [classes/:na]

And subsequently when I loaded that world after it would crash with this: java.lang.ArrayIndexOutOfBoundsException: -2 at com.bulletphysics.$Stack.pop$javax$vecmath$Quat4f(Unknown Source) ~[tera-bullet-1.0.0.jar:na] at com.bulletphysics.linearmath.QuaternionUtil.quatRotate(QuaternionUtil.java:87) ~[tera-bullet-1.0.0.jar:na] at org.terasology.logic.location.LocationComponent.getWorldPosition(LocationComponent.java:104) ~[classes/:na] at org.terasology.logic.location.LocationComponent.getWorldPosition(LocationComponent.java:96) ~[classes/:na] at org.terasology.world.chunks.internal.ChunkRelevanceRegion.calculateCenter(ChunkRelevanceRegion.java:130) ~[classes/:na] at org.terasology.world.chunks.internal.ChunkRelevanceRegion.update(ChunkRelevanceRegion.java:108) ~[classes/:na] at org.terasology.world.chunks.localChunkProvider.LocalChunkProvider.updateRelevance(LocalChunkProvider.java:341) ~[classes/:na] at org.terasology.world.chunks.localChunkProvider.LocalChunkProvider.update(LocalChunkProvider.java:249) ~[classes/:na] at org.terasology.rendering.world.WorldRendererLwjgl.pregenerateChunks(WorldRendererLwjgl.java:1142) ~[classes/:na] at org.terasology.engine.modes.loadProcesses.PrepareWorld.step(PrepareWorld.java:43) ~[classes/:na] at org.terasology.engine.modes.StateLoading.update(StateLoading.java:213) ~[classes/:na] at org.terasology.engine.TerasologyEngine.mainLoop(TerasologyEngine.java:486) ~[classes/:na] at org.terasology.engine.TerasologyEngine.run(TerasologyEngine.java:236) ~[classes/:na] at org.terasology.engine.Terasology.main(Terasology.java:82) [classes/:na]

Josharias commented 10 years ago

Anyone know how to start investigation of this? I looked through the bullet physics stuff and didnt find anything obvious. Is an error with "$Stack.get$javax$" an internal error with the jvm? Hoping maybe @immortius has a hint. :)

immortius commented 10 years ago

tl;dr version - try grabbing the latest TeraBullet and see if that helps or provides a more sensible error.

Longer version: JBullet, and thus TeraBullet, use a post-compile bytecode manipulation process called JStackAlloc to allow certain object to be kept on the stack, rather than on the heap. This predates Java 7, and potentially has bugs (obviously, I guess?). I've updated the code for TeraBullet to strip out the use of JStackAlloc - if this doesn't introduce significant performance hits then I suggest we switch to this version. Alternatively, using it may provide more easily interpreted errors. If the issue is specific to the QuaternionUtils.quatRotate() method an intermediate may be simply removing the use by that method.

Josharias commented 10 years ago

I could not get the error to reproduce using the updated TeraBullet jar. So it appears that this is indeed the way to resolve this.

Cervator commented 10 years ago

Excellent! Thanks @Josharias :-)

Could you do some rough performance testing? Blast or drop a bunch of blocks before and after and see if there's a noticeable difference? That's not very scientific and it would be nice to have a valid repeatable benchmark test, but ...

Cervator commented 10 years ago

Closing as fixed / old. Later performance testing would probably come across this if it is still an issue then.