Problem with implementing Picking

Hi There

I’m going trough the Hello Picking tutorial and I’ve ran into some trouble. I create a “shootables” node which I call whitePIeces and I traverse the scene graph adding in all the nodes
of interest as I go along. The problem is that when I then add the whitePieces node to the root node all my geometry spatials that were added dissapear.

I probably do not understand the scene graph implementation very well, but I read that when nodes are attached they are implicitly removed if they were already attached. My question is two-fold: Why do the geometries disappear and how can I prevent this from happening?

Thank you in advance

D.

[java]
private void setUpPicking() {
whitePieces = new Node(WHITE_PIECES);
rootNode.attachChild(whitePieces);

    // We visit each node and add the nodes
    // that are pivots for the pieces
    SceneGraphVisitor vis = new SceneGraphVisitor() {
        public void visit(Spatial spatial) {

// System.out.println(spatial.getName());
final String spatialName = spatial.getName();
if (spatialName.equals(WHITE_BISHOP1) || spatialName.equals(WHITE_BISHOP2)
|| spatialName.equals(WHITE_KING)
|| spatialName.equals(WHITE_KNIGHT1)
|| spatialName.equals(WHITE_KNIGHT2)
|| spatialName.equals(WHITE_PAWN_NODE1)
|| spatialName.equals(WHITE_PAWN_NODE2)
|| spatialName.equals(WHITE_PAWN_NODE3)
|| spatialName.equals(WHITE_PAWN_NODE4)
|| spatialName.equals(WHITE_PAWN_NODE5)
|| spatialName.equals(WHITE_PAWN_NODE6)
|| spatialName.equals(WHITE_PAWN_NODE7)
|| spatialName.equals(WHITE_PAWN_NODE8)
|| spatialName.equals(WHITE_QUEEN)
|| spatialName.equals(WHITE_ROOK1)
|| spatialName.equals(WHITE_ROOK2)) {
whitePieces.attachChild(spatial);
}
}
};

    rootNode.depthFirstTraversal(vis);
}

[/java]

[java]
public void simpleInitApp() {
flyCam.setEnabled(false);
inputManager.setCursorVisible(true);
cam.setLocation(new Vector3f(7.0f, 7.0f, 23.5f));

    Spatial scene = assetManager.loadModel("Scenes/board-scene-single-cube/gameScene.j3o");
    scene.setLocalTranslation(Vector3f.ZERO);
    rootNode.attachChild(scene);

    // Set up the camera
    boardCenter = new Vector3f(7.0f, 7.0f, 0.0f);
    cam.setLocation(rootNode.getChild(TOP_CAM).getLocalTranslation());
    cam.lookAt(boardCenter, Vector3f.UNIT_Y);

    // Init the keyboard mappings
    initKeys();

    setUpPicking();
    initMark();
}

[/java]

Maybe try not attaching the whitePieces node until after you’ve done the traversal. As it is now, you will traverse all of the pieces that you added to the whitePieces node which at best is redundant and at worst may confuse whitePieces.attachChild().

Incidentally, I’m curious why you feel the need to do this at all.

Hi pspeed

Thanks for your reply. I’ll give your suggestions a go and see how I get on. You’re probably right; I probably don’t need to do this at all. I want to create a click interface for the chess pieces. When a player clicks a piece, that piece is selected for movement. My chess engine will then return the possible moves for that piece and highlight the board squares available. Now that I think about it, as my scene is not very big, do you think I could just traverse the entire graph (without adding in the extra whitePIeces node) and do ray picking that way? I’ll give it a go.

Thanks again

D.

Hi pspeed

Just checking the collision against the original scene works grand :-). However, this then brings me to the second part of my original question; why do the white pieces disappear from the scene when they are attached to the whitePieces node?

Cheers

D.

@Ps2Fino said: Hi pspeed

Just checking the collision against the original scene works grand :-). However, this then brings me to the second part of my original question; why do the white pieces disappear from the scene when they are attached to the whitePieces node?

Cheers

D.

I still think it might be because you attached them twice in your original code. I’m not sure the code behaves properly if you attach a child to its parent again.

<cite>@pspeed said:</cite> I still think it might be because you attached them twice in your original code. I'm not sure the code behaves properly if you attach a child to its parent again.

Do you mean running the traversal is attaching the pieces twice? This is what confuses me as I was under the impression than calling attachChild() implicitly removed the child if it was previously attached

Cheers

D.

Moving a child from one node to another removes it from the first node. I would expect that to work if moving it from a node to itself but it’s entirely possible its never been tried.

Source code is right there if you want to check what it does tho :smiley:

Hi zarch

Cheers. I’ll have a look :slight_smile:

D.

In the code you posted, you attach the whitePieces node before traversing the scene graph. This means that you will also end up traversing the whitePieces node and all of the children that you already added. So each child you added will be attached to it again and maybe there is a bug.

At any rate, the code is entirely redundant so it would be better to attach the whitePieces node after you’ve done the traversal (as I said in my original answer). At the least, it avoids a lot of unnecessary work by the traverser. At best, it may also fix the problem you had because even if it is a bug in attachChild() it’s a very strange use-case to attach the same child again.

Actually, a quick read of the code for Node.java says you should be able to attach the child again to the same parent without issue. http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/scene/Node.java#234

So there must be some other reason that your geometry is disappearing… but it’s in code that we can’t see. You may need to put together a simple test case.

If could be a problem with modifying the scene graph structure as you traverse it but that’s a pretty weak possibility.

Attaching whitePieces before the traversal was an error. However, first traversing the graph then attaching does not resolve the issue. The use case is a grouping of all the white pieces under a common node. This is so I can send the white piece selected to the back end logic to calculate the available moves for that piece.

@Ps2Fino said: Attaching whitePieces before the traversal was an error. However, first traversing the graph then attaching does not resolve the issue. The use case is a grouping of all the white pieces under a common node. This is so I can send the white piece selected to the back end logic to calculate the available moves for that piece.

They shouldn’t disappear. Something else is wrong that we can’t see. Maybe they lose the translation or scaling of their parent when you move them and so no longer appear where you expect.

Anyway, you don’t have to group them just to do that. Attach a control to the pieces or some user data that indicates what moves they have or something and then just use that when a piece is picked. Personally, I’d just make them a child of the board (if they aren’t already) and then just call collideWith() on the whole board. With a scene as small as yours, rootNode.collideWith() should be fine also.