Only certain areas of terrain are ”pickable”

So i’m trying to do some RTS control, and i have a charcter that is a charactercontrol moving all around the map, i try to click on different locations of the map to get him to move there…



one problem i seem to be having is that the whole map doesn’t seem to be clickable, i click some areas and it works (usually areas painted with grass) but all the dirt areas it doesn’t register any collisions with the mouse…



@Sploreg i thought you may know what is going on here… it could be a problem with my code, but it would be strange that it picks up some areas quite nicely, but other areas not at all (i think it may have something to do with the layers but i’m not sure what the deal is)

hmm. Well if you can distill it down to a test case I can maybe see what is going on. But for example the TestModifyTerrainHeight doesn’t seem to run into any issues where it doesn’t pick on some areas, at least not that I have seen. And I haven’t run into it in any other cases, but that doesn’t mean there might not be a problem. If you can produce a test case to show it then I will fix it.

1 Like

Here is a test case… Test.j3o is just a terrain i created by using the terrain editor and taking all the defaults… Funny thing is

Right click disables the fly cam so you can test picking them

you’ll need to “fly” up and look down to see the terrain,

You’ll see you can click the box, but not the terrain… Funny thing, when i had a box above the terrain, it was able to pick the box and the terrain, but not anywhere outside the box…



Hopefully this helps



[java]

/**

  • Can’t pick a terrain

    /

    public class Main extends SimpleApplication {



    private BulletAppState bulletAppState;



    CameraMover camMover;



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {

    Box b = new Box(Vector3f.ZERO, 1, 1, 1); // create cube shape at the origin

    Geometry geom = new Geometry(“Box”, b); // create cube geometry from the shape

    Material mat = new Material(assetManager,

    “Common/MatDefs/Misc/Unshaded.j3md”); // create a simple material

    mat.setColor(“Color”, ColorRGBA.Blue); // set color of material to blue

    geom.setMaterial(mat); // set the cube’s material

    rootNode.attachChild(geom);



    /
    * Set up Physics /

    bulletAppState = new BulletAppState();



    stateManager.attach(bulletAppState);

    //makes the collison shapes visible for debugging purposes

    bulletAppState.getPhysicsSpace().enableDebug(assetManager);



    Spatial terrainSpatial = assetManager.loadModel(“Scenes/Test.j3o”);



    //the landscape is consider part of the enviroment

    rootNode.attachChild(terrainSpatial);

    terrainSpatial.setLocalTranslation(0, 0, 0);



    CollisionShape terrainShape =

    CollisionShapeFactory.createMeshShape((Node) terrainSpatial);

    RigidBodyControl levelCollisonBox = new RigidBodyControl(terrainShape, 0);

    terrainSpatial.addControl(levelCollisonBox);



    TerrainLodControl lodControl = ((Node)terrainSpatial).getControl(TerrainLodControl.class);

    if (lodControl != null)

    lodControl.setCamera(cam);



    // We attach the scene and the player to the rootNode and the physics space,

    // to make them appear in the game world.

    bulletAppState.getPhysicsSpace().add(levelCollisonBox);



    //the keys

    initInput();

    this.flyCam.setMoveSpeed(100f);

    inputManager.setCursorVisible(false);



    //the lighting

    DirectionalLight dl = new DirectionalLight();

    dl.setDirection(new Vector3f(-0.1f, -1f, -1).normalizeLocal());

    rootNode.addLight(dl);

    }



    /
    * Custom Keybinding: Map named actions to inputs. */

    private void initInput() {

    inputManager.addMapping(“LeftClick”, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));

    inputManager.addMapping(“RightClick”, new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));

    inputManager.addListener(actionListener, “LeftClick”);

    inputManager.addListener(actionListener, “RightClick”);

    }



    /**
  • handle inputs

    */

    private ActionListener actionListener = new ActionListener() {

    public void onAction(String name, boolean keyPressed, float tpf) {



    if(name.equals("RightClick") && keyPressed)

    {

    flyCam.setEnabled(!flyCam.isEnabled());

    inputManager.setCursorVisible(!flyCam.isEnabled());

    }

    if(name.equals("LeftClick") && keyPressed)

    {

    System.out.print("LEFT_CLICK");

    CollisionResults results = new CollisionResults();

    // Convert screen click to 3d position

    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);

    // Aim the ray from the clicked spot forwards.

    Ray ray = new Ray(click3d, dir);

    // Collect intersections between ray and all nodes in results list.

    rootNode.collideWith(ray, results);

    // (Print the results so we see what is going on:)

    for (int i = 0; i < results.size(); i++)

    {

    // (For each “hit”, we know distance, impact point, geometry.)

    float dist = results.getCollision(i).getDistance();

    Vector3f pt = results.getCollision(i).getContactPoint();

    String target = results.getCollision(i).getGeometry().getName();

    System.out.println("Selection #" + i + ": " + target + " at " + pt + ", " + dist + " WU away.");

    }

    }

    }

    };

    }

    [/java]

you just haven’t normalized your dir ray

1 Like

Will this fix the problem? i just went back to work so i can’t test it now…



Not sure why this would result in all items except the terrain being pickable

I just tested it and yes it fixes it. If the ray is not normalized then the results are unpredictable. And it probably only rarely picked the terrain because you are inside the terrain’s bounding box when picking

1 Like

Excellent, thanks a bunch… this was giving me all sorts of headaches!!!

ya I am tempted to put a check into the Ray constructor, but normalizing isn’t exactly fast and people might end up doing it twice all the time. Maybe a check to see if it is normalized and a warning message could help.

more importantly i think the wiki where i got this from needs updated so it doesn’t have this problem



https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:mouse_picking?s[]=picking



second code snippet is the picking method i used here, so it will need to have the normalized dir as well

good catch, I just updated it now.