Exception: Scene graph is not properly updated for rendering

Every now and then, I get the following exception. It seems to happen when I’m interacting with the display during a repaint.


Dec 17, 2010 5:05:40 PM com.jme3.scene.Node attachChild
INFO: Child (x) attached to this node (QueueObjects)
Dec 17, 2010 5:05:40 PM com.jme3.scene.Node attachChild
INFO: Child (x) attached to this node (QueueObjects)
Dec 17, 2010 5:05:40 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,6,main]
java.lang.IllegalStateException: Scene graph is not properly updated for rendering.
Make sure scene graph state was not changed after rootNode.updateGeometricState() call.
Problem spatial name: x
at com.jme3.scene.Spatial.checkCulling(Spatial.java:227)
at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:470)
at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:466)
at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:466)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:659)
at com.jme3.renderer.RenderManager.render(RenderManager.java:688)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:216)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:145)
at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:226)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:199)
at java.lang.Thread.run(Thread.java:662)


I have taken the lazy way out and named all my spatials "x". Could that mean something? I suspect not, since this is so intermittent.

Also, I have been doing
[java] jME.rootNode.updateGeometricState()
[/java]
but I read somewhere in the forum recently that that's a no-no. Again, this call is executed all the time, but the exception and freeze only happen occasionally.

Any ideas?

Thanks,
Lee

It usually happens if you’re modifying the scene graph outside the render thread. Make sure all modifications are done in the render thread.

That could be tricky. I’m using jME embedded within a Swing app, and the whole thing is written in Griffon (http://griffon.codehaus.org). Any thoughts on how I might get on the render thread?

[snippet id=“10”]

As far as I know, Griffon development came to a halt years ago. Why go through the trouble of using it?

Griffon is alive and kicking. In fact, Manning is about to publish the print version of Griffon in Action, and Andres Almiray even recently updated the jMonkeyEngine plugin, per my request. :slight_smile:

@normen:

I’m not sure how the code snippet fits into the grand scheme of things. Are there any samples that demonstrate the use of this technique?



In your sample, where does application come from? Is it the instantiation of SimpleApplication? In order to get onto the render thread, it seems like it has to be associated somehow.



Is the call to modifyObject() just pseudocode representing the modifications I want to make to my scenegraph, or is that a real call that needs to be made? What might I do with a return value?



Can the call to fut.get() occur anywhere?



Sorry for all the rookie questions, but this is unfamiliar territory.



Thanks!

  1. Just google “java concurrency” to get more information about threading in general
  2. Yes, but your association of threads with “different parts of code” is not exactly precise, why should it be more complicated to get access to an object in the code when theres threads?
  3. Yes, pseudocode. Anything in that method (or in the call method actually) will run on the other thread and should thus use only immutable data. The return value might be something that you want to compute using scenegraph objects, like you read the location of two objects, set another objects position based on that info and return the Vector3f where you put the new object. To be sure that nothing bad is happening (other threads modify the data/locations) all of that should be done on the render thread.
  4. Yes, it will however block the thread that is running until the Callable has been executed, so if you use the get() method on the render thread you might cause a deadlock because the render thread is waiting for the Callable to execute but it has to execute it itself…
gargleblaster said:
Griffon is alive and kicking. In fact, Manning is about to publish the print version of Griffon in Action, and Andres Almiray even recently updated the jMonkeyEngine plugin, per my request. :)
Oh! Well in that case I am happily mistaken :) I never quite saw the merit in Griffon (read: I just don't understand what it adds), but hopefully through projects such as this one we'll all see things a little more clearly. I really wonder what would make an ideal case to apply Griffon.

If I’m running a SimpleApplication, can I call application.enqueue()? I don’t think I can.



What type does the variable, application, have to be in your example?

gargleblaster said:
If I'm running a SimpleApplication, can I call application.enqueue()? I don't think I can.

Yes you can

Cool, that’s resolved my crash problems. BTW, shouldn’t enqueue() be added to https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:intermediate:simpleapplication?



I’m still getting an occasional error on a call to collideWith() from inside simpleUpdate(). I’m catching the exception, so it’s not fatal, and it doesn’t happen often, but I don’t understand why it occurs. Isn’t that a legal call to make from inside simpleUpdate()? Here is the stacktrace:


Collision exception bypassed: Scene graph must be updated before checking collisionjava.lang.IllegalStateException: Scene graph must be updated before checking collision

at com.jme3.scene.Geometry.collideWith(Geometry.java:225)
at com.jme3.scene.Node.collideWith(Node.java:498)
at sun.reflect.GeneratedMethodAccessor136.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:229)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callSafe(AbstractCallSite.java:97)
at Viewer.simpleUpdate(Viewer.groovy:134)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:208)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:145)
at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:226)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:199)
at java.lang.Thread.run(Thread.java:662)


Thanks,
Lee