How to add a shape after simpleInitApp has already been called?

Say the user clicks on something in the scene, which is handled by a method that creates a new spatial, like:



[java]

private void eventHandler(…)

{

Quad quad = new Quad(5f, 5f);

Geometry geom = new Geometry("quad", quad);

Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");

mat.setBoolean("UseMaterialColors", true);

mat.setColor("Ambient", ColorRGBA.Black);

mat.setColor("Diffuse", ColorRGBA.Blue);

mat.setColor("Specular", ColorRGBA.White);

mat.setFloat("Shininess", 12);

geom.setMaterial(mat);

rootNode.attachChild(geom);

}

[/java]



Problem is, such a method just causes the following exception:


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: quad
at com.jme3.scene.Spatial.checkCulling(Spatial.java:229)
at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:508)
at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:522)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:712)
at com.jme3.renderer.RenderManager.render(RenderManager.java:742)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:249)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:158)
at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:225)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:221)
at java.lang.Thread.run(Thread.java:662)


What am I missing?

Is simply adding:



[java]rootNode.updateGeometricState();[/java]



at the bottom of the method sufficient? Seems to work, but I’m not sure if it is appropriate.

  1. why does jme generate that error, you do something forbidden like calling updateGeometricState()?
  2. What does the user click mean ? raycasting ?
jacksmash said:
Is simply adding:

[java]rootNode.updateGeometricState();[/java]

at the bottom of the method sufficient? Seems to work, but I'm not sure if it is appropriate.


https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:intermediate:best_practices?s[]=update&s[]=geometric#don_t_mess_with_geometric_state
tralala said:
1) why does jme generate that error, you do something forbidden like calling updateGeometricState()?
2) What does the user click mean ? raycasting ?


According to the link on the post above this one, it is not illegal to call updateGeometricState on the root node.

So it sounds as if what I'm doing is OK then?

Excuse my ignorance but i dont understand what does that method do, that everyone is so desperate to call it ?

jacksmash said:
According to the link on the post above this one, it is not illegal to call updateGeometricState on the root node.

So it sounds as if what I'm doing is OK then?


Yeah. Only the rootNode and anything more. Also, don't override the updateGeometricState.
tralala said:
Excuse my ignorance but i dont understand what does that method do, that everyone is so desperate to call it ?


Spatial
updateGeometricState()
updateGeometricState updates the lightlist, computes the world transforms, and computes the world bounds for this Spatial.


As @normen said a few months ago in a topic i saw:

(something like this)
updateGeometricState is a powerfull bomb in bad hands

You cannot just change stuff from another thread! This is a symptom not a problem! Since your button press is called from the AWT thread i guess you are just changing the values at some time in the update loop, thus often times also after updategeometricstate…

[snippet id=“10”]



P.S. That “scene graph is not updated” error almost always results from incorrect threading

Thanks for that explanation. Makes sense. I’ve updated my code so that the object modification gets queued as explained.