Raycasting on a terrainQuad

Hi,



I noticed that raycasting ignores terrainquads: when a ray hits a terrainquad, it just acts as if it isn’t there. I tested it on meshes, and then it worked correctely.

Is there a way to check for ray collisions on terrains?

Thats not true. Show your code.

[java]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);

Ray ray = new Ray(click3d, dir);

terrain.collideWith(ray, results);

if (results.size() != 0) {

System.out.println("Collision");

}[/java]



This code only prints Collision when I click on a mesh. It does nothing when I click on a terrain.

What are you doing there? At z-location “0” no proper vector can be determined.



cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f) <— creates a Vector(Float.NaN,Float.NaN,Float.NaN)



https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_picking



Edit: Hm actually it doesn’t (-1 would, I think, based on your frustum settings) but your code still doesn’t make sense to me ^^

Edit2: Normalize the resulting vector.

1 Like

Normalizing the direction vector worked, thanks.

Well, I got it working :slight_smile:

What did you change to get it to work? (in case others have the same problem)

I was going to comment on this thread but digging into the matrix code started to hurt my head :slight_smile: I figure it is because you are at 0,0,0?

Hi, I have added camera at

cam.setLocation(new Vector3f(0f, 0f, 0f));



However, with the same ray casting code as above:

Vector3f click3d = cam.getWorldCoordinates(new Vector2f(click2d.x, click2d.y), 0f).clone();



I am getting the value of click3d as (Nan, Nan, Nan)



The terrain is the scene created in jMonkey in .j3o format.

What should be done in this case?

Also, the camera is set for parallel projection:



private float frustumSize = 9;



cam.setLocation(new Vector3f(0, 0f, 0));

cam.setParallelProjection(true);

float aspect = (float) cam.getWidth() / cam.getHeight();

cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize);



Quaternion iso = new Quaternion().fromAngleAxis(FastMath.DEG_TO_RAD * 35.264f, new Vector3f(1,0,0));

cam.setRotation(iso);

Sorry for the late reply.

Yes, I changed the location of the camera and it started working. But now i m having a different problem, I get no collisions when I create a map in Scene Composer, However I am getting collision if I create an scene in Blender and convert it to j30.

Tried changing the initial position of camera and the player as well, but still not getting collision on the map.

Some snippets of the code used are as below:

For camera:

loat frustumSize = 9f;

cam.setParallelProjection(true);

float aspect = (float) cam.getWidth() / cam.getHeight();

cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize);

cam.setLocation(new Vector3f(0, 10f, 10f));

cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);

flyCam.setEnabled(false);



For Map (Map created in Scene Composer):

worldRoot =(Node)assetManager.loadModel(“Scenes/Map02/Map.j3o”);

worldRoot.setName(“Map”);

worldRoot.setLocalTranslation(Vector3f.ZERO);

rootNode.attachChild(worldRoot);



For character creation:

playerNode = (Node)assetManager.loadModel(“Models/model/model.j3o”);

playerNode.setLocalScale(0.3f);

playerNode.setModelBound(new BoundingBox());

playerNode.updateModelBound();

playerNode.setLocalTranslation(new Vector3f(3.0f, 0.0f, -20.0f));

rootNode.attachChild(playerNode);

cam.setLocation(playerNode.getLocalTranslation());



Code for mouse-click:

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

Ray ray = new Ray(click3d, dir);

rootNode.collideWith(ray, results);

System.out.println("Results size: "+results.size());


> Here i get 0 result :(

I m not sure whats the problem, same is working if i create map in Blender.

The scene composer doesn’t do anything differently to the spatials. So either you have attached it to some other node or your picking is off.

Here is the picking code from the SDK if you want a guaranteed working reference:

[java]

private static CollisionResult pick(Camera cam, Vector2f mouseLoc, Node node) {

CollisionResults results = new CollisionResults();

Ray ray = new Ray();

Vector3f pos = cam.getWorldCoordinates(mouseLoc, 0).clone();

Vector3f dir = cam.getWorldCoordinates(mouseLoc, 0.1f).clone();

dir.subtractLocal(pos).normalizeLocal();

ray.setOrigin(pos);

ray.setDirection(dir);

node.collideWith(ray, results);

CollisionResult result = results.getClosestCollision();

return result;

}[/java]





You can use this node tree printer to see what the scene looks like when you pick.

1 Like

Hi Sploreg, thanks for the reference code, I will try this out in evening when I reach home and let you know how it goes. I like the JME scene composer better than Blender for Terrains, it would be great if this works out.

Yes, that worked :slight_smile:

Thanks alot.