Problem with GeometricState and appStates

I will try and quickly explain my setup. I wrote all my original code just inside one application class, I am now in the process of refactoring it to allow the use of states. In the process of doing this i have simply copied over most of my code and edited what i needed to allow it access to objects it once had rights to (viewport, settings etc); my error is this.

[java]SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,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: BS-geom-1

at com.jme3.scene.Spatial.checkCulling(Spatial.java:227)

at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:466)

at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:462)

at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:462)

at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:655)

at com.jme3.renderer.RenderManager.render(RenderManager.java:684)

at Wiiton.Game.update(Game.java:31)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:144)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:141)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:198)

at java.lang.Thread.run(Thread.java:619)[/java]





and this is said to be triggered at line 31 of my Game class: which is here:

[java]package Wiiton;



import com.jme3.app.Application;

import com.jme3.scene.Node;



public class Game extends Application {



Node rootNode = new Node();

MainMenuState mainMenu;

InGameState inGame;

int i = 1;



public void initialize() {

super.initialize();

}



public void update() {



super.update();



float tpf = timer.getTimePerFrame();





if (i == 1) {

inGame = new InGameState(this.getStateManager(), this, this.viewPort, this.settings);

inGame.setActive(true);



i = 2;

}





renderManager.render(tpf);// line 31



}



public void destroy() {

super.destroy();



System.out.println(“Destroy”);

}

}

[/java]





This Game class has one AbstractAppState initialized “InGameState” (had to do it a weird way, it i tried to initialize my state after i started the application, it was telling me my AppStateManager was still null :/) which has all my logic for in game actions. Inside my in game state i have a root node and everything is in one way or another attached to it. In the past i was able to fix this type of error by just changing around the location where i add models and the like to my scene node, but now i can’t seem to fix it at all. I’m really not sure what actually causes this error in the first place. I have provided here a simplified version of my IngameState (only irrelevant methods are missing)…



[java]package Wiiton;



public class InGameState extends AbstractAppState implements AnalogListener {



InputManager input;

private Node rootNode = new Node(“Root Node”);

Application theApp;

FilterPostProcessor fpp;

private BulletAppState bulletAppState;

Image GUI = new Image();

AssetManager appAssetManager;

public Node colNode = new Node();

Ent playerBoxShip;

Ent test;

ViewPort viewport;

AppSettings settings;

int i = 1;

Picture p = new Picture(“Picture”);

Geometry mark;

Camera cam;



public InGameState(AppStateManager stateManager, Application app, ViewPort viewPort, AppSettings settingsA) {

viewport = viewPort;

settings = settingsA;

initialize(stateManager, app);



}



public void initialize(AppStateManager stateManager, Application app) {



theApp = app;

input = app.getInputManager();

cam = app.getCamera();

appAssetManager = app.getAssetManager();



playerBoxShip = new PodBoxShip(0.0f, 5.0f, 0.0f);





bulletAppState = new BulletAppState();

stateManager.attach(bulletAppState);

addEnt(playerBoxShip);

rootNode.attachChild(colNode);

colNode.attachChild(makeFloor());

rootNode.attachChild(makeGasCloud());



((PodBoxShip) playerBoxShip).initDebug(rootNode, appAssetManager);

getPhysicsSpace().setGravity(Vector3f.ZERO);





CamSetup();

BloomSetup();

setupLighting();

((PodBoxShip) playerBoxShip).createFlame(appAssetManager);

((PodBoxShip) playerBoxShip).createShockwave(appAssetManager);

regsiterInput();

createStars();

viewport.attachScene(rootNode);



cam.setLocation(new Vector3f(0, 300, 60));

cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);

System.out.println(“Initialize”);





}



public void camUpdateFollow(Ent entFollow) {



cam.setLocation(new Vector3f(entFollow.entNode.getWorldTranslation().x, 320, entFollow.entNode.getWorldTranslation().z + 190));

cam.lookAt(new Vector3f(entFollow.entNode.getWorldTranslation().x, entFollow.entNode.getWorldTranslation().y, entFollow.entNode.getWorldTranslation().z), new Vector3f(0, 1, 0));



}













public void addEnt(Ent tempEnt) {



tempEnt.entNode = (Node) appAssetManager.loadModel(“Models/BS.mesh.xml”);

((PodBoxShip) tempEnt).physicsBox.move(tempEnt.pos);

rootNode.attachChild(tempEnt.entNode);

getPhysicsSpace().add(((PodBoxShip) tempEnt).physicsBox);

rootNode.attachChild(((PodBoxShip) tempEnt).physicsBox);

}







private PhysicsSpace getPhysicsSpace() {

return bulletAppState.getPhysicsSpace();

}







public void CamSetup() {

cam.setFrustumFar(2000);

cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));



}



public void render() {



}



public Node getRootNode() {

return rootNode;

}





public void update(float tpf) {

super.update(tpf);

rootNode.updateLogicalState(tpf);

this.rootNode.attachChild§;

camUpdateFollow(playerBoxShip);

((PodBoxShip) playerBoxShip).update(tpf);

getPhysicsSpace().update(tpf);

rootNode.updateGeometricState();





}

}

[/java]



sorry for the wall of text, I just want to make sure i provide all the information needed so i don’t waste anyones time.

thanks in advanced to anyone who can give me some guidance.

Look again at the source of Application and SimpleApplication, you dont update the rootnode properly. To avoid problems like these, just extend SimpleApplication.

1 Like

So you would suggest i just switch to a simple application setup? I was just worried that it might end up imposing limitations on my code.

Nonsense, apparently you limit your possibilities more by not using it :stuck_out_tongue:

Yeah, I was just tossing things around. However I have made some progress, my Game class now simply is this

[java]package Wiiton;





import com.jme3.app.SimpleApplication;



public class Game extends SimpleApplication {



MainMenuState mainMenu;

InGameState inGame;

int i = 1;





public void simpleInitApp() {

inGame = new InGameState(this.getStateManager(), this, this.viewPort, this.settings);

inGame.setActive(true);

}





public void destroy() {

super.destroy();



System.out.println(“Destroy”);

}

}

[/java]



However, now I am still getting the same error, Should i change something in my in Game state? I feel like I’m connecting everything to my root node improperly.

Haha, apparently. Please do pardon my misunderstanding, I have changed it over to a simpleApplication, but my error persists, mind telling me how i am updating incorrectly? Am i simply misunderstanding how these app States work?

If you still override the update() method in your application the states wont be updated, remove all updateXXX calls and use simpleUpdate()… Also dont call the stateManagers render() method in update()… what are you trying to do there??

If you still get the same error are you still calling render() yourself? You dont need to do that.

No sir, in my ingamestate this is my update method.



[java] public void Update(float tpf) {

super.update(tpf);



rootNode.updateLogicalState(tpf);



camUpdateFollow(playerBoxShip);



((PodBoxShip) playerBoxShip).update(tpf);

getPhysicsSpace().update(tpf);



rootNode.updateGeometricState();





}[/java]



Not calling any type of render. nor am i calling it anywhere else in the class.

dude, remove the updateGeometricState and updateLogicalState() calls.

Wow man, i am sorry about all my problems. There was a small aspect i had also forgotten, i don’t remember why, but i was attaching my root node from my in game state tot he view port of my game… i now have it attaching tot he root node of my game and it is working, again thank you for being so patient with my… problems… yeah lets call it that :). Last question, is what im doing right, IE: just attaching it the node of my ingamestate to my game class?

yep :slight_smile:

Alas, I came to the conclusion that i have not fixed my problem, bu simply made the illusion that i had. I attached my root node of my ingamestate to my game, which made it render, but my physics space was not updating. I looked around and realized i had never actually added my state to the state manager. Sadly upon doing this i brought my old problem back, that same geometricState error :(. I feel like such a fool, not being able to figure this out, but at this point,i feel like i have corrected my code to the point where this should no longer be an issue. Ill supply my current code.

game class:

[java]package Wiiton;





import com.jme3.app.SimpleApplication;



public class Game extends SimpleApplication {



MainMenuState mainMenu;

InGameState inGame;

int i = 1;





public void simpleInitApp() {

this.flyCam.setEnabled(false);

inGame = new InGameState(this.getStateManager(), this, this.viewPort, this.settings);

this.getStateManager().attach(inGame);

System.out.println(this.getStateManager().hasState(inGame));

inGame.setActive(true);

}





public void destroy() {

super.destroy();



System.out.println("Destroy");

}

}

[/java]



InGameState:

[java]package Wiiton;





public class InGameState extends AbstractAppState implements AnalogListener {



InputManager input;

private Node rootNode = new Node("Root Node");

SimpleApplication theApp;

FilterPostProcessor fpp;

private BulletAppState bulletAppState;

Image GUI = new Image();

AssetManager appAssetManager;

public Node colNode = new Node();

Ent playerBoxShip;

Ent test;

ViewPort viewport;

AppSettings settings;

int i = 1;

Picture p = new Picture("Picture");

Geometry mark;

Camera cam;



public InGameState(AppStateManager stateManager, Application app, ViewPort viewPort, AppSettings settingsA) {

viewport = viewPort;

settings = settingsA;



}



public void initialize(AppStateManager stateManager, Application app) {



theApp = ((SimpleApplication) app);

input = app.getInputManager();

cam = ((SimpleApplication) theApp).getCamera();

appAssetManager = theApp.getAssetManager();

playerBoxShip = new PodBoxShip(0.0f, 5.0f, 0.0f);



bulletAppState = new BulletAppState();



theApp.getStateManager().attach(bulletAppState);





addEnt(playerBoxShip);

rootNode.attachChild(colNode);

colNode.attachChild(makeFloor());





((PodBoxShip) playerBoxShip).initDebug(rootNode, appAssetManager);

getPhysicsSpace().setGravity(Vector3f.ZERO);





CamSetup();

BloomSetup();

setupLighting();

((PodBoxShip) playerBoxShip).createFlame(appAssetManager);

((PodBoxShip) playerBoxShip).createShockwave(appAssetManager);

regsiterInput();

createStars();

((SimpleApplication) theApp).getRootNode().attachChild(rootNode);





cam.setLocation(new Vector3f(0, 300, 60));

cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);

System.out.println("Initialize");





}



public void camUpdateFollow(Ent entFollow) {



cam.setLocation(new Vector3f(entFollow.entNode.getWorldTranslation().x, 320, entFollow.entNode.getWorldTranslation().z + 190));

cam.lookAt(new Vector3f(entFollow.entNode.getWorldTranslation().x, entFollow.entNode.getWorldTranslation().y, entFollow.entNode.getWorldTranslation().z), new Vector3f(0, 1, 0));



}







public void regsiterInput() {

theApp.getInputManager().addMapping("Exit", new KeyTrigger(KeyInput.KEY_ESCAPE));

theApp.getInputManager().addListener(this, "Exit", "shoot");

theApp.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

}



public void addEnt(Ent tempEnt) {



tempEnt.entNode = (Node) appAssetManager.loadModel("Models/BS.mesh.xml");

((PodBoxShip) tempEnt).physicsBox.move(tempEnt.pos);

rootNode.attachChild(tempEnt.entNode);

getPhysicsSpace().add(((PodBoxShip) tempEnt).physicsBox);

rootNode.attachChild(((PodBoxShip) tempEnt).physicsBox);



}







private PhysicsSpace getPhysicsSpace() {

return bulletAppState.getPhysicsSpace();

}







public void CamSetup() {

cam.setFrustumFar(2000);

cam.lookAt(Vector3f.ZERO, new Vector3f(0, 1, 0));



}







public void render() {

}



public Node getRootNode() {

return rootNode;

}



public void onAnalog(String name, float value, float tpf) {



if (name.equals("shoot")) {



Vector3f origin = cam.getWorldCoordinates(theApp.getInputManager().getCursorPosition(), 0.0f);

Vector3f direction = cam.getWorldCoordinates(theApp.getInputManager().getCursorPosition(), 0.3f);

direction.subtractLocal(origin).normalizeLocal();





Ray ray = new Ray(origin, direction);

CollisionResults results = new CollisionResults();

int numCollisions = colNode.collideWith(ray, results);

if (numCollisions > 0) {

CollisionResult hit = results.getClosestCollision();

if (mark == null) {

initMark();

}

System.out.println("collide " + hit.getContactPoint());

mark.setLocalTranslation(hit.getContactPoint());

((PodBoxShip) playerBoxShip).setMoveTo(mark.getLocalTranslation().x, mark.getLocalTranslation().z);

}

}







}



public void update(float tpf) {



super.update(tpf);







camUpdateFollow(playerBoxShip);

((PodBoxShip) playerBoxShip).update(tpf);

getPhysicsSpace().update(tpf);





}

}[/java]

What I see is that you falsely call physicsSpace.update()… Also make sure you dont call any methods for adding stuff etc. from outside the render thread!

I see what you are saying, physics space should update because it is a state already attached to my state manager. However i am confused, why on earth would i want to run my methods for doing something like adding a model IN the render method?

Nobody said you should do. But you have to modify the scenegraph on the OpenGL thread (the update() method or use a callable).

Imagine this: the update loop is running, the OpenGL thread renders the scene and suddenly you remove an object from the scenegraph → you get an error.

I’m such a fool, Man thank you for all your help, i was right in thinking it had to be something with the double initialization, so i went and looked over the source. Because i was overwriting the initialization class, i had to also manually tell it to set initialized to true ;).Thanks again man, you helped alot, and in the process i finally understand how the whole setup works.