Ray collision with terrain

Hello



First of all Happy New Year!



I have been working a lot with jME3 lately, and I like it so much that I decided to make my a game with it as my thesis. Most of my exams are done now, so I decided to update my computer, and also jME3 (had alpha4 - updated to beta). I expected some breakage in the game, and I fixed most of it, but I am having trouble fixing this one:



I have a terrain. I click with the mouse and I create a ray. I check the collision with the terrain. Nothing :frowning:



This is how I create my Ray

[java]

private Ray getMouseRay() {

Vector2f mouseCoords = new Vector2f(inputManager.getCursorPosition());

Vector3f origin = cam.getWorldCoordinates(mouseCoords, 0).normalizeLocal();

Ray mouseRay = new Ray(origin, cam.getWorldCoordinates(mouseCoords, 1).subtractLocal(origin).normalizeLocal());

return mouseRay;

}

[/java]



And this is how I check for collision:

[java]

if (name.equals(“RTSCAM_RightClick”)) {

Ray mouseRay = getMouseRay();

if (terrain != null) {

CollisionResults cr = new CollisionResults();

int r = terrain.collideWith(mouseRay, cr);

System.out.println®;

terrain.collideWith(mouseRay, cr);

if (cr.size() > 0) {

[/java]



The problem is that there are no collisions. Before the update, the code worked. I tried hardcoding the values (maybe the ray was created in a wrong way) but I don’t think thats the case. I am not exactly sure where to look next. Any ideas?



I looked on the forums and I saw other people had problems with ray and terrain intersection, but I didn’t find a solution.



Best regards,

Cristian



PS: the game can be found here: http://battlegrounds.github.com/

Update the SDK.

that didn’t work, I still get 0 collisions. any other suggestions?



also if someone has problems updating the SDK, try changing the settings to use “No Proxy” in Tools > Options > General tab

(that made the update work for me)

You are normalizing your cam location vector, I doubt you actually mean to do so. I was suggesting updating because there were issues with rays that are perpendicular to the terrain but that shouldn’t be the issue in your case.

that is a good point. and I found it really weird when it worked, but it did so I just left it like that



guess its costing me now… maybe if I could actually see the ray going I could fix it. how could I highlight it?



any other things that you think might cause this problem?



the idea is to emulate RTS camera like clicking (like moving a unit in starcraft)

I guess something like this would do the trick:

[java]

Line line = new Line(mouseRay.getOrigin(), mouseRay.getDirection().mult(1000));

Geometry lineG = new Geometry("A very nice line",line);

lineG.setMaterial(someMaterial);

rootNode.attachChild(lineG );

[/java]

http://imgur.com/4xJlK


wow. thats really cool gonna experiment with that for a while. The blue lines are created with the code makeshift posted. while I try to debug the problem, is there anyone else that had an issue similar to mine?
@normen said:
You are normalizing your cam location vector, I doubt you actually mean to do so.


you are correct thats now what used to work. that was some code I was experimenting with

[java]
Vector2f mouseCoords = new Vector2f(inputManager.getCursorPosition());
Ray mouseRay = new Ray(cam.getWorldCoordinates(mouseCoords, 0),
cam.getWorldCoordinates(mouseCoords, 1).subtractLocal(
cam.getWorldCoordinates(mouseCoords, 0)).normalizeLocal());
return mouseRay;
[/java]

this is the original code that worked before the update. sorry for the mixup

EDIT: I got the original idea how to calculate the intersection of the terrain with the ray from here https://wiki.jmonkeyengine.org/legacy/doku.php/starter:hello_mouse_pick_jme2:hello_mousepick

I didn’t make any progress :frowning:



Maybe its a problem with the terrain I am using? The terrain extends TerrainQuad



[java]

RigidBodyControl landscape = new RigidBodyControl(0.0f);

addControl(landscape);

app.getBulletAppState().getPhysicsSpace().add(landscape);

[/java]



does this effect the ray in any way? I also tried something else than a ray, the geometry of the line @makeshift suggested, but still the same result. 0 collisions



I am running out of ideas and reached a point where there is too much guessing. could really need some help from someone with more experience

You want a ray from the character location downwards in -Y direction:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:math_for_dummies

I added wireframe for debugging, I am adding cubes at both ends of the lines (lines are generated from the ray) and I can clearly see that it intersects the terrain. as I said before the code was working before the update. at this point I suspect something is broken. (maybe in my head :slight_smile: )



normen, thank you very much for your help. I will just hardcode the values although I hate doing that - time is of the essence

makeshift, thank you very much for the quick lesson :smiley:



I will keep this thread up to date with the solution, I will hopefully find.

You are extending TerrainQuad?



Make sure the model bounds are updated and that the bounding box has a positive volume (not zero volume).

It’s guessing how ever much experience you have. If you provide a simplified test case, I’m sure someone can figure it out. If not, it might help you to do so:)

ok I finally found something that might help me. terrain.getWorldBound() returns null.



I assume this means that the terrain doesn’t have a bounding box, or that is is null, thus it is trying to intersect with something null. which explains why the ray is placed in the correct position but doesn’t intersect the terrrain.



how to fix this on the other hand eludes me. below, you can see my terrain object, and how it is created. I think the mistake might lie in the constructor.



[java]

/**

*

  • @author cmessel

    */

    public class BattleField extends TerrainQuad {



    public static final String NAME = "terrain";

    public static final int PATCH_SIZE = 9;

    public static final int TOTAL_SIZE = 33;

    private static Vector3f spawnLocation = new Vector3f(13, 3, 16);



    private static float[] generateHeightMap(AssetManager assetManager) {

    AbstractHeightMap heightmap = null;

    Texture heightMapImage = assetManager.loadTexture(

    "Textures/Terrain/splat/mountains512.png");

    heightmap = new ImageBasedHeightMap(

    ImageToAwt.convert(heightMapImage.getImage(), false, true, 0));

    heightmap.load();

    return heightmap.getHeightMap();

    }



    public static Vector3f getSpawnLocation() {

    return spawnLocation;

    }



    public BattleField(Blink app) {

    super(NAME, PATCH_SIZE, TOTAL_SIZE, generateHeightMap(app.getAssetManager()));



    setMaterial(new BattleFieldMaterial(app.getAssetManager()));

    setModelBound(new BoundingBox());

    setLocalTranslation(16f, 0f, 16f);



    List<Camera> cameras = new ArrayList<Camera>();

    cameras.add(app.getCamera());

    TerrainLodControl control = new TerrainLodControl(this, cameras);

    addControl(control);



    RigidBodyControl landscape = new RigidBodyControl(0.0f);

    addControl(landscape);

    app.getBulletAppState().getPhysicsSpace().add(landscape);

    }

    }

    [/java]



    and this is how I add the terrain

    [java]

    public void loadBattleField() {

    //adjustHeight(size, size, queueDistance);

    battleField = new BattleField(app);

    rootNode.attachChild(battleField);

    }

    [/java]



    can anybody spot some mistake I might be doing here?
@Sploreg said:
You are extending TerrainQuad?
Make sure the model bounds are updated and that the bounding box has a positive volume (not zero volume).

.....!??

I read that but I am not sure what it means. how can I ensure it has a positive volume?

If the bounds are zero in volume (say the y value is zero), our collision does not work: the ray does not intersect it then. TerrainQuad should check this as I encountered it with flat terrain. So I doubt it is the issue, but maybe it regressed.

@mess you really, really, really do not want to subclass TerrainQuad like that. None of that code needs to be in terrain quad and was purposefully placed outside it to avoid issues like what you are having.

http://imgur.com/gn5gG



this is the image I use for the height map. yeah its small, but if you take a close look, you can see its not flat. for the terrain quad I add a bounding box like so:



(in the constructor)

[java]

setModelBound(new BoundingBox());

[/java]



I checked the volume of the BoundingBox and yes it is 0. question is… how do I not make it not 0? I tried adding parameters to the BoundingBox but I don’t know what each is supposed to do.



I tried something similar to this but it didn’t work



[java]

BoundingBox bb = new BoundingBox(Vector3f.ZERO, new Vector3f(33, 1, 33);

setModelBound(bb);

[/java]

Just don’t subclass TerrainQuad, you are doing that very wrong and it will cause you no end of headaches, trust me.