[SOLVED] Adding Line mesh to Node

Not sure what I’m dong wrong but adding a line mesh to a node and then adding that to the rootNode causes the line to NOT draw.

In my code:
//pickingQuads is a Node full of geometries used to add efficiency to picking (it displays fine when I want it to )
rootNode.attachChild(pickingQuads);

//liveQuads is a node full of geometries that show the game area (works great)
rootNode.attachChild(liveQuads);

//pickingEffects is a Node I want to use to hold picking effects like highlighting a picked object
//createPickingOutline creates the Geometry, attach to pickingEffects Node then attach
//that to rootNode. The Line does not draw…
Picking.pickingEffects.attachChild(GameShapes.createPickingOutline(assetManager));
rootNode.attachChild(Picking.pickingEffects);

//However, it works perfectly fine if I attach the Geometry directly to the rootNode
rootNode.attachChild(GameShapes.createPickingOutline(assetManager));

But I’d like to organize the objects into their own nodes. It works fine for the Triangles meshs why not for the Lines Mesh?

Something is wrong with that… we can’t see what from here, though.

Hardly any magic at all in a Node.

materials issue? are you setting a material on pickingEffects that is being applied to the outline mesh ?

He’d have to be setting it after attachment of the child… which hopefully would have popped into his head as “something else different”.

But I guess it’s best not to assume.

Most likely cause is a weird position for pickingEffects… or NaN transform or something. But I hate having to speculate about code not provided.

Would how you apply Material affect whether or not it displays in the rootNode or a child node? As I mentioned it works fine when applied directly to the rootNode.

Here’s my code for creating the pickingOutline Mesh:

/**
 * Create the mesh for the outline of picked objects.
 * @param assetManager
 * @return 
 * @throws java.lang.Exception 
 */
public static Geometry createPickingOutline(AssetManager assetManager) throws Exception{
    
    try{

        pickOutline.setMode(Mesh.Mode.Lines);

        Geometry geom = new Geometry(Picking.PICKOUTLINE , pickOutline);
        
        Material mat1;
        mat1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat1.setColor("Color", ColorRGBA.Black);
        mat1.getAdditionalRenderState().setLineWidth(3f);
        mat1.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
        geom.setMaterial(mat1);
        geom.setCullHint(Spatial.CullHint.Never);

    return geom;
    
    }catch(Exception e){
      
    }
}

And here is how I’m adding it to Node pickingEffects:

/***
 * Create any nodes needed for the game.
 * @throws java.lang.Exception
*/
public void initNodes() throws Exception{

    //generate quad bounding boxes
    sector.createQuadBoundingBoxes(pickingQuads, 
                                    assetManager);
    
    rootNode.attachChild(pickingQuads);
    rootNode.attachChild(liveQuads);
    
    Picking.pickingEffects.attachChild(GameShapes.createPickingOutline(assetManager));
    rootNode.attachChild(Picking.pickingEffects);

    //rootNode.attachChild(GameShapes.createPickingOutline(assetManager));
    
}

And, declarations if that helps?

public class Picking {


public static final String PICKOUTLINE = "PICKOUTLINE";
public static Node pickingEffects = new Node(PICKOUTLINE);
public static Mesh pickOutline = new Mesh();

In the non-working version, after everything is attached to the scene… add some System.out.println()s for picking outline’s world translation, world rotation, world bounds, etc…

Change:

To:
Spatial outline = GameShapes.createPickingOutline(assetManager);
Picking.pickingEffects.attachChild(outline);
rootNode.attachChild(Picking.pickingEffects);
System.out.println(“translation:” + outline.getWorldTranslation());
…and so on.

But…

Makes me suspicious that your Mesh’s model bound is screwed up… else you wouldn’t have had to do that.

Ok, so I did this:

/***
 * Create any nodes needed for the game.
 * @throws java.lang.Exception
  */
   public void initNodes() throws Exception{

    //generate quad bounding boxes
    sector.createQuadBoundingBoxes(pickingQuads, 
                                    assetManager);
    
    rootNode.attachChild(pickingQuads);
    rootNode.attachChild(liveQuads);
    
    //pickingEffects.attachChild(GameShapes.createPickingOutline(assetManager));
    //rootNode.attachChild(pickingEffects);
    
    //Picking.pickingEffects.attachChild(GameShapes.createPickingOutline(assetManager));
    //rootNode.attachChild(Picking.pickingEffects);
    
    outline = GameShapes.createPickingOutline(assetManager);
    Picking.pickingEffects.attachChild(outline);
    rootNode.attachChild(Picking.pickingEffects);

    //rootNode.attachChild(outline);

    System.out.println("translation:" + outline.getWorldTranslation());
    System.out.println("Rotation:" + outline.getWorldRotation());
    System.out.println("Bound:" + outline.getWorldBound());

    //rootNode.attachChild(GameShapes.createPickingOutline(assetManager));
}

The output is:
translation:(0.0, 0.0, 0.0)
Rotation:(0.0, 0.0, 0.0, 1.0)
Bound:BoundingBox [Center: (0.0, 0.0, 0.0) xExtent: 0.0 yExtent: 0.0 zExtent: 0.0]

At this point the mesh is empty though. On the click event I do:

int lineCount ;  
lineCount = 1; //one line for now

float[] tpa = new float[6 * ( lineCount )];//position array
short[] ibarrayTemp = new short[ 2 * ( lineCount ) ];//index array

//add in the vertices (key is the Vector3f rep centre of quad)
//This draws a big line straight up.
tpa[0] = key.x; 
tpa[1] = key.y;
tpa[2] = key.z;
tpa[3] = key.x + 1; 
tpa[4] = key.y + 50;
tpa[5] = key.z;

//add in the idx's
ibarrayTemp[0] = (short)0;
ibarrayTemp[1] = (short)1;

//load up the data
pickOutline.setBuffer(VertexBuffer.Type.Index, 1, BufferUtils.createShortBuffer(ibarrayTemp));
pickOutline.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(tpa));

System.out.println("translation:" + outline.getWorldTranslation());
System.out.println("Rotation:" + outline.getWorldRotation());
System.out.println("Bound:" + outline.getWorldBound());

Which also gives me:
translation:(0.0, 0.0, 0.0)
Rotation:(0.0, 0.0, 0.0, 1.0)
Bound:BoundingBox [Center: (0.0, 0.0, 0.0) xExtent: 0.0 yExtent: 0.0 zExtent: 0.0]

Should I be initializing the mesh with data when the Geometry is first created? It just seems that there is no difference with what I am doing between adding the Spatial directly to the rootNode and adding the Spatial to a child node and adding the childnode to the rootnode.

On the working code I did try to remove

geom.setCullHint(Spatial.CullHint.Never);

and that did break it. The line no longer drew.

As suspected, you never called updateModelBound() on the Geometry after you changed its mesh… so it wants to be culled from view because it has no size.

You specified CullHint.Never for the Geometry which was why it drew when it was a direct child of the root node. However, when it was the child of the intermediate node then that parent node still has 0 size and will be culled.

Rather than juggling cull hints, you’re better off just letting the geometry have an accurate bounding shape.

2 Likes

Yes, that was it. I didn’t realize a Line mesh would have a bounding volume but I guess a mesh is a mesh. I still get the warning that .updateModelBound() should not need to be called but I did need to call it for my game area meshes as well. I just felt like I was maybe doing something wrong there (kind of like setting cull modes until it works…).
Also remed all cull hints and it works fine.
Thanks!

1 Like

That’s kind of a silly warning… since anyone modifying their mesh would need to call it.

I think it’s a throwback from JME2 that required you to manually do a bunch of stuff all the time that JME3 takes care of automatically.

Impressive catch.

1 Like