Object picking on loaded models

Hello,
I’ve readed this tutorial: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_picking
I understand all what I’ve readed there. But I have a problem. The tutorial only explains how to do object picking on geometries which are not loeded but just created with code.
I do the same as what they say in the tutorial:

  • Creating a node containing all objects which should be clickable.
  • Attach an inputMapping to the inputManager (I add a MouseButtonTrigger)
  • Create actionlistener

This is my actionlistener code:

[java]private void mouseAction(String name, boolean isPressed, float tpf) {

if(isPressed) {
    
    if(name.equals("Pick item")) {
	//System.out.println("Mouse left button pressed: " + name);
	
	pickItem();
    }
}
}

[/java]

And this is my picking code:

[java]private void pickItem() {

CollisionResults results = new CollisionResults();

Vector2f click2d = inputManager.getCursorPosition();
Vector3f click3d = cam.getWorldCoordinates(
	new Vector2f(click2d.x, click2d.y), 0f).clone();
Vector3f dir = cam.getWorldCoordinates(
	new Vector2f(click2d.x, click2d.y), 1f).subtractLocal(click3d).normalizeLocal();
Ray ray = new Ray(click3d, dir);
roomItems.collideWith(ray, results);

if (results.size() > 0) {
    System.out.println(results.getCollision(0).getGeometry().getName());
}

[/java]

When I create a simple Geometry like a Box, and (of course) it has a name passed in its constructor, then there are no problems. When I click on the Box, the name of the box will be printed in pickItem().
But when I have a loaded model, for example a blue sofa, and I click on that object, then not the name of the object will be printed, but the name of the material I clicked on. Like Material.003

Code of creating my sofa:
[java]Spatial sofa = assetManager.loadModel(“Models/sofa/sofa.j3o”);
sofa.setLocalTranslation(0.0f, 0.8f, 0.0f);
sofa.setName(“A blue sofa”);
roomItems.attachChild(sofa);
[/java]

You see I also tried to set the name of the loaded sofa.
I think this has to do that loaded objects are always a Spatial. Can anyone help me?

When you load a model put a data on it to say “it’s a loaded model”, something like
[java]your_loaded_spatial.setUserData(“loaded”, true);[/java]

then, when your collision test gives you a geometry use on it a method like this:

[java]
public static Spatial loadedModelOf(Spatial picked)
{
Spatial iter = picked;

while( iter != null && ! Boolean.TRUE.equals(iter.getUserData(“loaded”) )
{
iter = iter.getParent();
}

return iter;
}
[/java]

the root of your problem is : the collision test gives you the collided geometry, but this geometry is a part of the loaded model (a sub-component).

With this method your should retrieve your loaded model. I wrote it here, so there is maybe a bug in it. But i use myself this kind of thing when i need to do picking on complex models.