HUD/guiNode questions

Little confused about how this is managed. It doesn’t seem to be the same as he root node in the sense that if you update a geometry’s mesh… (say… change the width), nothing aside from the visuals of the geometry seems to change (i.e. the “new” area of the geometry is not selectable). This (and a few other things) made me think the guiNode is not managed in the same way the root node is. Sooooo… that being said, how would one fix this issue?

Breakdown of problem:
Custm mesh in a Geometry in a Node in the guiNode
Adjust the vertex buffer of a mesh
Visually, everything looks good.
Try to ray cast against the new portion of the object and the ray hits nothing.

Yes… I am resetting the buffer properly and calling updateBound() in the mesh class.

How do you cast the ray? especially thedirection and the start point?

Um… the ray casting works fine, even after updating the mesh… it just doesn’t hit the new portions of the mesh (as if it is being clipped). I’ve tried all manner of forced updates to bounds… on the mesh, geometry, node and guiNode… notta… but, either way, here is the method of ray casting:

guiRayOrigin.set(x, y, 0f);
CollisionResults results = new CollisionResults();
spatial.collideWith(elementZOrderRay, results);

x and y are the mouse x, y from the event
The direction is preset as it never changes.
after this I parse through the returns based on z-order.

It is definitely being clipped, as I can drag the window from the corner and resize it… as long s it ends at a smaller size than it started, I can reselect the corner and resize it again… if it end at a large size… any portion of the mesh outside the original size is unselecteable.

If I pick up an object that is draggable that is also locked to it’s bounds, I can move it through the entire resized window. I can also select the draggable object again and move it, even it was dropped in the area that is not selectable of the resized panel. So it is specific to… maybe the geometry? I am updating the mesh itself. Is there something I need to do with the geometry to ensure this type of clipping doesn’t happen?

I resize stuff in the gui node all the time. Sounds like you did not recalculate the bounds after adjusting the mesh. How do you change the mesh?

Edit: or the collision data

1 Like


this.setBuffer(Type.Position, 3, verts);
if (updateAll) {
this.setBuffer(Type.TexCoord, 2, coords);
this.setBuffer(Type.Index, 3, indexes);

EDIT: Collision data? >.< How does one do this?

Do I have to call createCollisionData each time?

Lord help me…

prior to updateBounds();

Thanks you!!

I don’t think it matters what order.

In fact, I vote for clearing the collision data in updateBounds and then it will automatically be recreated as needed. I can’t think of a case where the bounds would change but the collision data would stay the same.

@pspeed Oddly enough, after using createCollisionData(), I had to call Geometry.updateModelBound() or the collision data wasn’t reset. Is this normal?

I guess it uses the bound data to do … stuff :slight_smile:

1 Like
@t0neg0d said: @pspeed Oddly enough, after using createCollisionData(), I had to call Geometry.updateModelBound() or the collision data wasn't reset. Is this normal?

Actually, if the mesh is already in Geometry then I think Geometry.updateModelBound is what you should call instead of mesh.updateBound… since updateModelBound calls it.

It’s the collision data that’s a little messy.

1 Like

@normen @pspeed @whoeverknows

Next gui node questions. Is there a global setting for flipping the y coord in the gui? It’s not critical, however… a for instance as to why the reverse would be easier:

Create a window panel…
Add a child panel as a drag bar… the dragbar is set to effect it’s absolute parent… and only resize east/west.
if the nw corner of the screen was 0,0… when resizing the window from the nw corner of the panel, the default behavior of the dragbar would be to stay with the window 's top/left bounds simply due to encapsulation. With the Y coordinate flipped, the bottom of the window reacts this way… making docking panels an absolute must from the get go. I’d prefer to put that off until I finish up the default behavior of recursive resizing.

Anyways… I’m learning a ton going through this exercise about how JME handles things I hadn’t really considered before.

I now have a gui library of my very own… that consists of (so far)
Buttons (standard, toggle &split button–button+arrowed menu)
Menu bar + menus(with submenu behavior)
Radio buttons (and radio button groups)
Check boxes (and check box groups)
Sliders (free floating & stepped)
Labels… notta on text input yet… haven’t really thought about how to do this one
Horizontal and Vertical scroll bars-- buttons, track and (scale to content) thumbs (now I just need to figure out how to do clipping)
And there is a screen class which acts as an input manager and delegates all events.
Also created a subset of event listeners to better organize event types.

All controls are based off of a single element class, which handles standard default behaviors… so make a slider, for instance, was as easy as creating a layer for the track, adding a child layer for the thumb… setting that to movable and locking it to it’s parent’s bounds.

Thanks for the help here! Seriously, I stopped working on my game altogether solely because of my frustration with Nifty. It just would NOT do the things I wanted… no matter how much I hacked the implementation. And I would say I got more out of it than most have, if you recall any of the vids I put up showing the gui of my game.

In my gui, the layouts take care of the top is 0 feel. In other words, components internally size and lay themselves out that way but otherwise act like regular scene graph objects where bottom is 0.

Randomly, you might consider not being so event heavy. In Swing it makes sense because it spends most of its time idle. In JME/3D apps, you already have a constantly churning update loop so for a lot of things it’s better to use some kind of versioned value system.

Here is a for example:

Start with an interface like this:
public interface VersionedObject {
public long getVersion();

public T getObject();

public VersionedReference<T> createReference();    


And here is how “watchers” will look at it:
[java]public class VersionedReference {
private VersionedObject object;
private long lastVersion = -1;

public VersionedReference( VersionedObject<T> object ) {
    this.object = object;
    this.lastVersion = object.getVersion();

public boolean needsUpdate() {
    return lastVersion != object.getVersion();

public boolean update() {
    if( lastVersion == object.getVersion() )
        return false;
    lastVersion = object.getVersion();
    return true;

public T get() {
    return object.getObject();


So, for example, my RangeModel that my slider uses implements VersionedObject. Internally it just increments the version whenever the value changes. Things that care just do something like:

if( modelRef.update() ){
…do some stuff with modelRef.get()

For things many updates, they can update as often as the frame rate anyway and this is considerably lighter-weight. In some cases, it’s better still because you don’t end up sending events that are ultimately redundant. You can increment the version any number of times and the watchers will still just see “something changed”… rather than getting every update event.

Anyway… just a random thing that I thought I’d pop out there.

1 Like


I took a slightly different approach to stiffing events… though I think it may have the same effect as your approach (not as eloquently implemented by any stretch).

None of my elements actually listen for events, only the screen class does this. Since it was already in charge of handling things like mouse focus element and such, the screen determines who should know what passes events based on this. If a child or parent needs to know about the event (based on the type of event), it uses recursive calls to manage updates of elements.

The listener interfaces aren’t truly listeners. They subset the list of abstracted methods for handling events in a sense… i.e. mouse button events, mouse wheel events, mouse movement events, keyboard events and then provide specific handlers for each… left button pressed, left button released, etc. This was more for the reason of not having to check against button type… or having mouse wheel movement jumbled in with mouse movement events.

But… all that said. I can’t wait to play around with the idea you posted! Looks like a really cool way of handling updates.

Oh… speaking of which. Back to the y coord orientation. I know I need to ensure that the y coord is flipped before passing it along to anything that may receive an event. The thing I am unclear as to whether need to change is (being that my element class actually extends Node):

Does the mesh itself need to be reoriented? (i.e. the position buffer working in -y coords)
Or can all these changes be handled with the exact same mesh I am using now?

I’m thinking the mesh needs to change… or the nodes position would still be based off the standard bottom to top y coord (Ok… it’s a hack to try and flip the node… but). Is this correct? Or is there another way to approach this?

All of my nodes and spatials and meshes are in standard orientation. My layouts just work upside down. So when you add a control to row 0 of a spring grid it’s at the top… and the top component positions itself with its top at the top of the outer component.

The constant coordinate conversion will kill you… and this is already a job for layouts anyway.

1 Like


Thanks again for the tip… I was able to resolve the position issue very easily. Since all of my layouts are absolution positioning, relative to the container it is in (i.e. 0,0 is the sw corner of the container object… though I am going to flip placement as well, so everything appears to be top-left oriented), I just grabbed the difference from last height to new height and subtracted it from the Y position of the resized element’s direct children’s y position. Every element below the single direct child layer is not effected. It was a MUCH smaller problem than I originally thought…