Crash on PhysicsSpace.removeAll() latest svn

Hi!



I got the latest svn and I am getting this crash:

[patch]

Caused by: java.lang.ClassCastException: com.jme3.terrain.geomipmap.TerrainPatch cannot be cast to com.jme3.scene.Node

at com.jme3.bullet.PhysicsSpace.removeAll(PhysicsSpace.java:530)

at com.jme3.bullet.PhysicsSpace.removeAll(PhysicsSpace.java:530)

at com.jme3.bullet.PhysicsSpace.removeAll(PhysicsSpace.java:530)

… 10 more

[/patch]



I did this change and it worked.

[patch]

Index: src/jbullet/com/jme3/bullet/PhysicsSpace.java

===================================================================

— src/jbullet/com/jme3/bullet/PhysicsSpace.java (revision 7502)

+++ src/jbullet/com/jme3/bullet/PhysicsSpace.java (working copy)

@@ -527,7 +527,7 @@

List<Spatial> children = ((Node) spatial).getChildren();

for (Iterator<Spatial> it = children.iterator(); it.hasNext():wink: {

Spatial spat = it.next();

  •            removeAll((Node) spat);<br />
    
  •            removeAll(spat);<br />
    

}

}

}

[/patch]



PS.: btw, this kind of simple report deserve a thread? or I could communicate it by other means?

Yeah, thanks.

teique said:
PS.: btw, this kind of simple report deserve a thread? or I could communicate it by other means?

It's fine, don't worry about that, thanks for your report

Just a side note: This just happened to me and I found out this crash also happens if you manually add anything to the TerrainQuad node, like a model or any other spatial. TerrainQuad nodes should be left manually unaltered, else the TerrainQuad.getHeightMap() function crashes with that error message above because one of the children spatial/node is not a TerrainPatch.

Hi,

I did some change in addAll()/removeAll() but nothing on recursive part. I try to reproduce the bug via the SDK :

  1. create terrain
  2. add a Box primitive on the first TerrainQuad
  3. add RigidBodyControl to Terrain

receive the following exception :

java.lang.ClassCastException: com.jme3.scene.Geometry cannot be cast to com.jme3.terrain.geomipmap.TerrainPatch
	at com.jme3.terrain.geomipmap.TerrainQuad.getHeightMap(TerrainQuad.java:1865)
	at com.jme3.terrain.geomipmap.TerrainQuad.getHeightMap(TerrainQuad.java:1876)
	at com.jme3.bullet.util.CollisionShapeFactory.createMeshShape(CollisionShapeFactory.java:166)
	at com.jme3.bullet.control.RigidBodyControl.createCollisionShape(RigidBodyControl.java:150)
	at com.jme3.bullet.control.RigidBodyControl.setSpatial(RigidBodyControl.java:125)
	at com.jme3.scene.Spatial.addControl(Spatial.java:602)
	at com.jme3.gde.core.sceneexplorer.nodes.actions.AbstractNewControlAction$1$1.call(AbstractNewControlAction.java:72)
	at com.jme3.gde.core.sceneexplorer.nodes.actions.AbstractNewControlAction$1$1.call(AbstractNewControlAction.java:67)
	at com.jme3.app.AppTask.invoke(AppTask.java:142)
	at com.jme3.app.Application.runQueuedTasks(Application.java:583)
	at com.jme3.app.Application.update(Application.java:596)
	at com.jme3.gde.core.scene.SceneApplication.update(SceneApplication.java:302)
	at com.jme3.system.awt.AwtPanelsContext.updateInThread(AwtPanelsContext.java:188)
	at com.jme3.system.awt.AwtPanelsContext.access$100(AwtPanelsContext.java:44)
	at com.jme3.system.awt.AwtPanelsContext$AwtPanelsListener.update(AwtPanelsContext.java:68)
	at com.jme3.system.lwjgl.LwjglOffscreenBuffer.runLoop(LwjglOffscreenBuffer.java:125)
	at com.jme3.system.lwjgl.LwjglOffscreenBuffer.run(LwjglOffscreenBuffer.java:152)
	at java.lang.Thread.run(Thread.java:745)

Is it the issue ? (I got the same issue with 3.0.10.)
I don’t see addAll() or removeAll() in the stacktrace.

From the source code. TerrainQuad only support TerrainPatch as children :

[java]
if (getChildren() != null && !getChildren().isEmpty()) {
float[] ul=null, ur=null, bl=null, br=null;
// get the child heightmaps
if (getChild(0) instanceof TerrainPatch) {
for (Spatial s : getChildren()) {
if ( ((TerrainPatch)s).getQuadrant() == 1)
ul = ((TerrainPatch)s).getHeightMap();
else if(((TerrainPatch) s).getQuadrant() == 2)
bl = ((TerrainPatch)s).getHeightMap();
else if(((TerrainPatch) s).getQuadrant() == 3)
ur = ((TerrainPatch)s).getHeightMap();
else if(((TerrainPatch) s).getQuadrant() == 4)
br = ((TerrainPatch)s).getHeightMap();
}
}

[/java]

You’re right, it does account for non TerrainPatch spatials, therefore it can’t be the issue, but yes, it was crashing on the getHeightMap() function, I do not recall the exact line tough, but after sleeping on it, I tried to reproduce the issue and it no longer was consistent in the stack trace. It turns out it was crashing randomly on almost any line that involved the scene graph because I was altering it from a thread! Damn me :stuck_out_tongue: So after moving those TerrainQuad updates to the appropriate render thread, there are no longer any crash. That was surprisingly misleading!

But how did YOU manage to get that crash too?

@.Ben. said: But how did YOU manage to get that crash too?

I follow the step 1.2.3. I listed previously (In trunk SDK, I can add primitives shape).

Are you sure the 3 steps are done within the render thread and not some other thread tough? And are your crash stack traces consistent?

@.Ben. said: Are you sure the 3 steps are done within the render thread and not some other thread tough?

I imagine, I do it throught the SDK.

@.Ben. And are your crash stack traces consistent?

Yes. (I tried twice). I only have the stacktrace when I add rigidbody AND the TerrainQuad has “Box” as children. If I remove the Box, I can add rigidbody without exception.

Well, if I may add: I had tried 5-6 times yesterday changing very little details like using add() instead of addAll() and stuff like that and it was always crashing in TerrainQuad.getHeightMap() and today, before I realize it was because I was altering the TerrainQuad’s heightMap in the wrong thread, it was much more random! I got crashes in like 4 different places simply by running and exiting the app multiple times in a row.

I explain this by the fact that since it was because of threads (my problem at least), the crash stack trace depends on where the threads execution are at when this code gets executed. I may be wrong about this, but that’s how I see it: Threads run in parrallel, therefore sometimes you execute the app and 1 thread runs before the other one or vice versa, therefore it’s pretty much random where the crash can occur.

Well well well… you got me wondering again so I just tested it. I added a node to the TerrainQuad and INDEED this causes this even if it is only altered in the appropriate thread. So there were really 2 issues and by fixing the first one (altering it outside of the thread) I fixed the second issue also. But the issue about attaching anything to a TerrainQuad is really still there as I stated in my OP yesterday. So I’m confirming also what you said @david.bernard.31

[java]
EXCEPTION: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.terrain.geomipmap.TerrainQuad.getHeightMap(TerrainQuad.java:1865)
mygame.Main.simpleUpdate(Main.java:2952)
com.jme3.app.SimpleApplication.update(SimpleApplication.java:242)
com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
java.lang.Thread.run(Thread.java:744)
[/java]

This is kind of an example why extending node and / or geometry isn’t a good idea, we were thinking about moving the terrain stuff completely into (a) Control(s), then again its true its just kind of a special Geometry… Bottom line is that you simply shouldn’t add anything to the TerrainNode and not regard them as a Node or Geometry at all but as a separate entity in the scenegraph the way it is now.

@normen said: Bottom line is that you simply shouldn't add anything to the TerrainNode and not regard them as a Node or Geometry at all but as a separate entity in the scenegraph the way it is now.

Precisely what I wrote yesterday in my OP.

@.Ben. said: TerrainQuad nodes should be left manually unaltered, else the TerrainQuad.getHeightMap() function crashes with that error message above because one of the children spatial/node is not a TerrainPatch.

Suggestion: Why not make it very clear in the documentation that even tough YOU TECHNICALLY CAN attach nodes and spatials under TerrainQuads, it will most probably crash?