Lemur how to make the mouse select the model


I would like to add a circle underneath the model when the mouse clicks on it

/**
 *
 * @author icyboxs
 * 
 */
public class UnitLogic extends BaseAppState{
    
    private static Logger log = Logger.getLogger(UnitLogic.class.toString());
    
    private InputManager inputManager;
    private InputMapper inputMapper;
    private AssetManager assetManager;
    private SimpleApplication simpleApp;
    public CollisionResult results = new CollisionResult();
    @Override
    protected void initialize(Application aplctn) {
        simpleApp = (SimpleApplication) aplctn;
        assetManager = aplctn.getAssetManager();
        inputManager = aplctn.getInputManager();
        T100Unit t100Unit=new T100Unit(simpleApp);
        t100Unit.addT100();
        simpleApp.getRootNode().attachChild(t100Unit.getT100Units());
        
    CursorEventControl.addListenersToSpatial(simpleApp.getRootNode().getChild("T100Units"), new DefaultCursorListener() {

            @Override
            protected void click(CursorButtonEvent event, Spatial target, Spatial capture) {
//        System.out.println("我被点击了:" + target);
//        System.out.println("我被点击了:" + capture);
                //System.out.println("我被点击了:" + event.isPressed());
//        System.out.println(results);
                // System.out.println(scenarioState.mapGrid3D.getCellsizePosition(results.getContactPoint()));
            }

            @Override
            public void cursorButtonEvent(CursorButtonEvent event, Spatial target, Spatial capture) {
                event.setConsumed();
                log.info(event.toString());
                System.err.println(results);
                if (event.isPressed()) {
                
                } else {

                }
            }

            @Override
            public void cursorEntered(CursorMotionEvent event, Spatial target, Spatial capture) {
                // System.err.println(event);//.getCollision().getContactPoint()
            }

            @Override
            public void cursorExited(CursorMotionEvent event, Spatial target, Spatial capture) {

            }

            @Override
            public void cursorMoved(CursorMotionEvent event, Spatial target, Spatial capture) {
                results = event.getCollision();
                
            }
        });
    
    System.err.println(((Node)simpleApp.getRootNode().getChild("T100Units")).getChildren());
    }

    @Override
    protected void cleanup(Application app) {
    }

    @Override
    protected void onEnable() {
    }

    @Override
    protected void onDisable() {
   }
    
}


/**
 *
 * @author icyboxs
 */
public class T100Unit implements ActionListener, AnalogListener{

    /**
     * @return the T100Units
     */
    public Node getT100Units() {
        return T100Units;
    }

    /**
     * @param T100Units the T100Units to set
     */
    public void setT100Units(Node T100Units) {
        this.T100Units = T100Units;
    }


    private Node T100Units = new Node("T100Units");
    private int i=0;
    private SimpleApplication simpleApp;
    
    


public T100Unit(SimpleApplication simpleApp){
this.simpleApp=simpleApp;
}


    public void addT100(){
        
        Node Role = ((Node) simpleApp.getAssetManager().loadModel("Models/model/abc.j3o"));
        // Role.setShadowMode(RenderQueue.ShadowMode.Cast);// 承载阴影

        Role.setLocalScale(10f, 10f, 10f);
        
        
        Role.setName("T100Units_"+i);
        getT100Units().attachChild(Role);
        i++;
    }
    
    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
    
    }

    @Override
    public void onAnalog(String name, float value, float tpf) {
    
    }
}

Role.setName("T100Units_"+i);

I set a unique integer identifier of int i to the model’s Node.

CollisionResult[geometry=mesh.002 (Geometry), contactPoint=(-8.432902, 62.35965, 0.19163513), contactNormal=(-0.01893686, 0.99392277, 0.10843833), distance=242.07271, triangleIndex=6563]

When a collision occurs only a portion (Geometry) can be returned How do I determine which Node this is?

Geometries usually have names, you can use the names as a reference.

Usually, you would setUserData() on the base node of your model. It’s quite common to set the entity ID or something like that.

…then when geometry is clicked, you can move up the parent to find the one with an “entityId” user data.

myModel.setUserData(“entityId”, 123)

…you “can” use the spatial name for this but it’s much more hacky. Any all spatials have a name but not all spatials would have your entity ID… which makes it much easier to find.

2 Likes

Another way to do this (and this could be slightly faster for large scenes where you don’t want to do picking against every other geometry in the scene) is to keep a list of the important game objects that you want to check picking for (like NPCs for example) and loop through the list of NPCs checking for picking collisions with each NPC’s node. This will of course only work if you are keeping lists of your game objects like NPCs and store a reference to their spatial/node along with a getSpatial() method, and it could be easier or it could be more difficult depending on how your game architecture is setup.

1 Like

It also only works if you are doing your own picking instead of letting Lemur do it.

If you have portions of your scene that are never pickable then there are ways to exclude them that don’t require manually managing your own picking.

1 Like

Ok thank you for your replies

I didn’t understand your statement.

                results = event.getCollision();
                results.getGeometry().getParent();

Do you mean I should do this to query his parent Node?

After I try this getParent() return root (Node).

Yes, and that node’s parent, and that node’s parent, and that node’s parent until you find an id.

public static long fetchSpatialId(Spatial spatial) {
    while (spatial != null) {
        Long id = spatial.getUserData("MyId");
        if (id != null) {
            return id;
        }
        spatial = spatial.getParent();
    }
    return -1;
}
1 Like

Okay, so this is how it’s used.
I thought he would automatically go around looking for it :sweat_smile: :rofl:
Thank you for your help !

2 Likes