Beginner Question: Several Problems mixing GUI and Scene

Hey!



As I have some Ideas in mind, that I want to try out without building it up myself again, I started looking into jm3 2 days ago. After some trial and error I found out how the gui is handled, that states seem to share the same nifty and so on. As I had some problems on my way I decided to start from the tutorial just to address the problems.



The first problems I have is:

  • As soon as I display the GUI, the cube is not rendered anymore.
  • Somehow in this test, the setCursorVisible has no effect



    [java]public void simpleInitApp() {

    Box b = new Box(Vector3f.ZERO, 1, 1, 1);

    Geometry geom = new Geometry("Box", b);



    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    mat.setColor("Color", ColorRGBA.Red);

    geom.setMaterial(mat);

    rootNode.attachChild(geom);



    NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay( assetManager, inputManager, audioRenderer, viewPort);

    Nifty nifty = niftyDisplay.getNifty();

    nifty.fromXml( "Interface/Interface.xml", "start", this);

    inputManager.setCursorVisible( true);

    guiViewPort.addProcessor( niftyDisplay);



    nifty.gotoScreen( "start");

    }

    [/java]

setCursorVisible() will be overridden by fly cam when it is initialized after simpleInitApp(). You can remove the fly cam if you don’t want it. Search the forums for how.

1 Like

Paul if the code was in the state attached and not initialized, then would these issues be prevented? Because it does cause quite a few, especially for newcomers, and is just annoying in general :stuck_out_tongue: (i would debug through it, but I’m on my phone). Similarly if I wanna move the fpsText I have to do it in the update loop after simpleInit.



I don’t think people should have to implement hacks just to do stuff which should be intuitive (i.e setting stuff in simpleInitApp, which did work fine before). If the state attached doesn’t/can’t work, then perhaps methods to add/remove the flycam, stats etc may be more appropriate?

@wezrule said:
Paul if the code was in the state attached and not initialized, then would these issues be prevented? Because it does cause quite a few, especially for newcomers, and is just annoying in general :P (i would debug through it, but I'm on my phone). Similarly if I wanna move the fpsText I have to do it in the update loop after simpleInit.

I don't think people should have to implement hacks just to do stuff which should be intuitive (i.e setting stuff in simpleInitApp, which did work fine before). If the state attached doesn't/can't work, then perhaps methods to add/remove the flycam, stats etc may be more appropriate?


a) if you do initialization in an app state then there is no problem.
b) the alternative is to go back to the old way where you have simpleInit convenience but no way of removing these things at all except by avoiding SimpleApplication completely.
c) removing these things is _trivial_ and has been covered four or five times on the forum already. But I will go over it here again.

If you want to remove all of the default app states then override the constructor. That's it. If you want to only include some of them... or your own... then you can pass them on the constructor.

If you want to remove on in simpleInitApp() then you just remove the app state:
stateManager.detach(stateManager.getState(FlyCamAppState.class))

The issue is that JME classes traditionally have not been very robust in the realm of initialization order. For example, you can't create a BitmapText without loading a BitmapFont first. It would be nice if you could create one and set the font later... but you can't. So, the FPS text has to be created during the init cycle and simpleInitApp() is called before everything else. Calling the app states first would cause other problems.

One truly easy way around all of this is to have your application extend AbstractAppState instead of SimpleApplication and just create a regular SimpleApplication and attach your app state to it in main()... but there are a few limitations with this approach since handleError(), pause, etc. aren't passed to the AppState.

The current state of things is less convenient than perhaps it should be but more now things that were impossible before are at least possible.
pspeed said:
If you want to remove all of the default app states then override the constructor. That's it. If you want to only include some of them... or your own... then you can pass them on the constructor.

One thing to make this more clear is maybe to change the SimpleApplication template to override the constructor and pass the current default appstates there.
@jmaasing said:
One thing to make this more clear is maybe to change the SimpleApplication template to override the constructor and pass the current default appstates there.


Yeah. Probably right.

A few other things should also happen:

1) FlyCamAppState should be more robust than it is. If you disable the state, it will still do most of its stuff on init. It should wait until it is enabled. This is a good chance to show the general pattern of how to do enable/disable properly. As I recall, changes need to be made to FlyCam too which is why I didn't tackle it at the time I refactored. Basically, if a user disables flyCam in simpleInit then flyCam shouldn't register its input handlers, etc.... and it should leave the cursor visibility alone. It puts the FlyCamAppState in kind of a weird place, though, since it is enabled but the FlyCam isn't. Removing the flyCam reference completely would have been nice but would have broken nearly every app. At any rate, however it's managed, fly cam is overzealous about initialization.

2) StatsAppState should put its StatsView and fpsText under a node created during constructor. That way simpleInit could still move where the text will be, etc.. This is an easier one to do.

Thanks for the detailed explanation Paul. I do like the ability to attach/detach stuff like this very easily. And anything which makes initilisation easier would of course be greatly welcome :). I myself don’t have any problems with it (apart from the stuff mentioned). But for newcomers, it can be frustrating to understand why something put in simpleInit doesn’t do what you’d expect.