Search code examples
3dblenderjmonkeyengine

How to check if object is on road?


I am new to game developing and using the jMonkey engine. I started to develop an endless running type game. To run, I have created a map with blender and imported it to jME.

As the screenshot shows, I have added it to a terrain and made some mountains. Now I need to get the exact vector point of map (point A like point on screen shot).

This will help me to detect if the running object is on the map or not. Can someone give me an answer or tell me the alternatives that experts use?

this is the screenshot

UPDATE

I want to detect whether the running object is on the silver color road or not. How can I do that?


Solution

  • A common solution to that problem is to use ray casting, where an imaginary line is tested for intersections with the objects (ground, road) beneath the avatar (the running object).

    Here's an example that uses the mechanics provided by jMonkeyEngine 3:

    public boolean isOnRoad(Vector3f avatarPosition, Geometry road) {
        // Pointing downwards (assuming that the Y-axis is facing upwards in your game)
        Vector3f direction = new Vector3f(0, -1, 0);
    
        // Create a line that starts at 'avatarPosition' and has a direction
        Ray ray = new Ray(avatarPosition, direction);
    
        // Results of the collision test are written into this object
        CollisionResults results = new CollisionResults();
    
        // Test for collisions between the road and the ray
        road.collideWith(ray, results);
    
        // If there is a collision, avatarPosition is above the road
        return results.size() != 0;
    }
    

    You need to pass the position of the avatar to the function.
    avatarPosition = avatar.getLocalTranslation();

    If your road consists of multiple Geometries packed into a Node, you can also pass the Node instead of a single Geometry into the function. collideWith() called on a Node will test all its children.
    The function above might not work correctly if the Node also contains other parts of your Scene.

    The call of road.collideWith(ray, results) will implicitly build a BIH-Tree (Bounding Interval Hierarchy Tree) for the road-Mesh the first time it is used. That will speed up collision tests as it doesn't have to check the ray against every triangle of the road. It will be fast enough to do it in every update cycle.


    Additionally, you can work with the results of the collision test.
    This will return the exact point of the intersection that is closest to the starting point:

    Vector3f p = results.getClosestCollision().getContactPoint();
    

    And with the iterator you can process all collisions separately, sorted from closest to furthest collision:

    Iterator<CollisionResult> it = results.iterator();
    while(it.hasNext())
    {
        CollisionResult collisionResult = it.next();
        Vector3f p    = collisionResult.getContactPoint();
        Geometry geom = collisionResult.getGeometry();
        // Do something with contact point and geometry
    }
    

    More information about collisions:
    http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:collision_and_intersection

    Ray casting is also used to select objects in the 3D Scene with a crosshair or the mouse.
    This is called picking:
    http://hub.jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_picking