Safe adding of BillboardControl

Hey guys,



I’m trying to add a Billboardcontrol to my Bitmaptext as a unitname but I can’t find a secure way to do it without causing an IllegalStateException.



The gameserver is giving a signal to the clients to add units. So in order to keep it all thread safe I’m doing this in my update method:

[java]

@Override

public void update(float arg0) {

/*

  • The server adds units to this Vector

    */

    if (addUnits.size()>0){

    for (ViewMech e: addUnits){



    completeMapNode.attachChild(e.getMainNode());

    placeUnit(e, e.getUnit().getX(), e.getUnit().getY());

    BillboardControl bbControl = new BillboardControl();

    bbControl.setAlignment(BillboardControl.Alignment.Screen);

    e.getTextNode().addControl(bbControl); //of course this could also be done in the Viewmech class. Same issue though.



    }

    addUnits.removeAllElements();

    }

    }[/java]







    So far so good but as soon as I move the camera over the Bitmaptext this causes an IllegalStateException. Removing the addControl line solves the issue, I can see the Bitmaptext and the game doesn’t crash.



    Does anyone have an idea how to solve this?



    Kaizo





    EDIT Exception:
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: Root Node

Whats the illegal state exception?

Ah sorry. I should’ve added that.




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: Root Node

Thats strange… Guess a local update check is missing somewhere, try adding a e.getTextNode().getWorldTranslation() before adding the control, that should update the node…

Can you provide a test case that reproduces this issue?

Thanks for the fast help!



Its looking like this now :

[java]completeMapNode.attachChild(e.getMainNode());

placeUnit(e, e.getUnit().getX(), e.getUnit().getY());

BillboardControl bbControl = new BillboardControl();

bbControl.setAlignment(BillboardControl.Alignment.Screen);

e.getTextNode().getWorldTranslation();

e.getTextNode().addControl(bbControl);[/java]



But sadly I’m getting the same error.



About the testcase:

That’s quite hard but I will try my best if there’s no other way.

I couldn’t reproduce the issue yet. I tried it by pressing a button in order to represent the adding of units through the server but that didn’t work out. I guess the inputmanager is the problem there.



I have to add that my original code worked with a previous version of JME. It stopped working when I updated to the version from the 7th February.

I should’ve asked earlier but I didn’t really miss the unittext until now :confused: . Maybe that helps a little to figure it out.

This might be a bit off from your plan of adding the unit names but have you tried using the guinode instead of the billboard? On my first game attempt I added target unit info overhead by using the unit position and the function getScreenCoordinates, something like this:

[java]// Offset of 4 on Y axis to make it overhead

targetFrame.setLocalTranslation(cam.getScreenCoordinates(target.getLocalTranslation().add(0, 4, 0)));

// Scale dependent on distancefrom cam to unit

targetFrame.setLocalScale(Math.min(Math.max(1/cam.getLocation().distance(target.getLocalTranslation()) * 24,0.3f), 1));

//TODO: Add check whether unit is in front of camera:

// if (cam.getDirection().distanceSquared(target.getLocalTranslation.subtract(cam.getLocation() >= 2.0f)

// targetFrame.setVisible(true);

// else

// targetFrame setVisible(false);[/java]



Have not tried the last 4 lines yet tho, but it’s a start for you :wink:

@baalgarnaal thats actually an interesting solution. I will definitely test it. thx! maybe I can find the difference between the jme-version Im using now and the older version where it used to work as well.

@baalgarnaal I know this is oldish but I am really interested in your suggestion but don’t understand what targetFrame is.

What is a frame object in the context of jme?

looks like its what ever you want above the unit