# Ray Picking

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

If you don’t know what normalizing a vector is then you may want to run through that again if you haven’t already.

That’s what I’m passing it. The origin is the tip of the space craft. The direction is the middle of the cross hair.

But you aren’t passing a direction. You are passing the location of the middle of the crosshair. You should go over the length I provide to learn the difference between a location and a direction maybe.

A direction vector is always of length 1.

Oh I see. I need to use trigonometry…

???

Please read the math for dummies link. If you find yourself using trig then you are doing it wrong.

Seriously. If you have a line between two endpoints then it’s as simple as:

dir = end2.subtract(end1).normalize();

This is the fundamental most basicest of the basic fundamental 3D math stuff, though. (Actually, it’s exactly the same in 2D, though.) Please study up on this a little and you will be way faster at achieving your goals.

@memonick

Pick from a mouse click on the screen looks like this:

[java]

Vector3f direction = getCamera().getWorldCoordinates(inputManager.getCursorPosition(), 0);

direction.subtractLocal(getCamera().getLocation()).normalizeLocal();

Ray ray = new Ray(getCamera().getLocation(), direction);

[/java]

Once you’ve got your ray you can use it thus:

[java]

CollisionResults cr = new CollisionResults();

sceneNode.collideWith(ray, cr);

[/java]

Although this should give you the correct result, I assure you it is imperative you know how, why. Read and learn.

Next time I won’t provide code.

I’m really sorry, but after watching the math for dummies three times, I still can’t understand how to normalize the Vector3f in my case. I can’t use the Camera method as I am using a ChaseCamera which stays 10f behind the player.

How to normalize a vector?

Simple:

[java]

vector3.normalize();

[/java]

@memonick said:
I'm really sorry, but after watching the math for dummies three times, I still can't understand how to normalize the Vector3f in my case. I can't use the Camera method as I am using a ChaseCamera which stays 10f behind the player.

Pore over my code above. The answer is right there. The only difference is that I get my initial vector from the screen, you get it from the camera position...
@memonick said:
I'm really sorry, but after watching the math for dummies three times, I still can't understand how to normalize the Vector3f in my case. I can't use the Camera method as I am using a ChaseCamera which stays 10f behind the player.

Three times in this short time? Everything? Maybe you miss a bit from the basics like vectors can be directions or locations or "forces"? The vector for the direction of a spatial has its origin at the spatial position but the direction vector you supply has to origin from 0/0/0, so you have to subtract the position of the spatial beforehand. It has nothing to do with the camera, try to understand the code.

I managed to get the direction to work (it seems so, anyways):

http://i39.tinypic.com/r23m1k.png

Please confirm it is working well - direction is the front one.

However, even if I hit something, it doesn’t say I hit it.

@memonick said:
I'm really sorry, but after watching the math for dummies three times, I still can't understand how to normalize the Vector3f in my case. I can't use the Camera method as I am using a ChaseCamera which stays 10f behind the player.

Or... quoted from my other post:

dir = end2.subtract(end1).normalize();

dir = end2.subtract(end1).normalize();

dir = end2.subtract(end1).normalize();

You have two endpoints... make a direction vector. If you don't know what your endpoints are for the line you want then you will not be able to get very far.

I managed to get that to work (see my last screenshot/post).

Something seems to be wrong with CollisionResults now. Will try to figure that out now.

The debugger is your friend. Don’t forget that.

[java]Vector3f dir = new Vector3f(Main.setup.cross.getLocalTranslation().x, Main.setup.cross.getLocalTranslation().y, Main.setup.cross.getLocalTranslation().z).normalize(); dir.addLocal(Main.Mgeom.getLocalTranslation().x, Main.Mgeom.getLocalTranslation().y+1, Main.Mgeom.getLocalTranslation().z);

System.out.println(dir.length());[/java]

The CollisionResults is working well, but I can’t hit the objects. If I remove normalize(), I can hit some objects. What’s the problem here?

Also, when I output the direction’s length, the output is the y position of the direction.

I got it to work correctly - even if the length is not 1. The only problem I have now is the positioning of the direction, although this is another issue.

@memonick said:
[java]
Vector3f dir = new Vector3f(Main.setup.cross.getLocalTranslation().x,
Main.setup.cross.getLocalTranslation().y,
Main.setup.cross.getLocalTranslation().z).normalize();

System.out.println(dir.length());[/java]

This will not work. It's wrong.

Also, do you realize that the first line is the same thing as:

[java]
Vector3f dir = Main.setup.cross.getLocalTranslation().normalize();
[/java]

Yours go through 5 methods, the above 2.

Please follow naming conventions. Instanced classes should not start with capital letters. It makes things a lot easier for everyone when reading the code. If I'm following convention your "Main.Mgeom" tells me it's a static Class, which I imagine it isn't.

oi @madjack u’ve almost overtaken me, stop helping people!

1 Like

And this line:

Shows a complete misunderstanding of directions and positions.

I think I’m going to give up now. I’ve posted almost the exact solution 4 times now.

@wezrule said:
oi @madjack u've almost overtaken me, stop helping people! :(

You will be assimilated. Uh, crushed. Yeah. Crushed. :P

@memonick
Last hint then you're on your own.

Your answer lies in the first line. Use the first line I pasted. I do use screen coordinates, which are 2d, BUT I convert it to 3d. The rest is pretty much variable change.

I will add to my solution one line because I think that if someone doesn’t understand what a Ray is then it could be confusing on its own:

dir = end2.subtract(end1).normalize();

ray = new Ray(end1, dir);

1 Like