Issues with ray picking in a 3D space

Started by Akinesis, September 03, 2014, 13:23:41

Previous topic - Next topic

Akinesis

Hello everyone. I'm currently working on an Voxel game in lwjgl an struggling with ray Picking. I've manage to understand the theory of what and how it should work but a lot a point are still not clear to me.

In my programe i've implemented the abcdef's methode found here : http://lwjgl.org/forum/index.php/topic,4867.msg26115.html#msg26115
but math isn't that much my specialty and i'm just lost in how calculate anny with that vector returned.

What i'm doing (or at least what i want to do) is to Cast a ray (a vector) from the center of my 2D screen to the infinity of my 3D matrix, and then calculate collision and stuffs. If i understand well the abcdef's code return a vector ({x , y, z} ?) which go from the coordinate i send (i my case always the center of the screen) to somewhere between 0 and 1/-1 on each axis. Or is it a direction ?

As you can see i'm little confuse, what i have now is the abcdef's and the starting point of the camera but things like camera+(vector*4) not working. Almost working but not.

Thank you for reading and eventually helping, sorry for my bad english it's not my native language.

quew8

What @abcdef's code does is to create a normalized (magnitude/length = 1) vector pointing from the cursor's position into the screen. So yes a direction. The ray you have to test against starts at the camera's position and extends in the direction of the returned vector.

Everything you have said is right so I expect your problem is in your collision detection code.

abcdef

Hi

I can give you a bit of an update on my ray picking experience. What I posted below works but its going to cause you a lot more problems in the long run. The methods are deprecated in modern opengl, and you have to call it every single frame (so not very efficient).

To answer some of your questions

> If i understand well the abcdef's code return a vector ({x , y, z} ?)

Yes, that method returns a standard 3 dimensional vector.

> Or is it a direction ?

It is a direction vector (once normalised), your camera position is the start of the ray.

The below is an alternative method of getting the ray components, I have just listed the concept. This would only need to be called when the camera moves.

Ray start point - Again this is just the camera location
Ray Direction -

To work this out I start of with a unit matrix, for a standard axis setup you would have the below

1 0 0    <- This row contains the right vector
0 1 0    <- This row contains the up vector
0 0 -1   <- This row contains the forward vector (negative because opengl has z axis setup this way)

When I rotate the camera I also rotate this matrix, this means the forward vector should always point in the direction of the camera. The camera position should also always be in the centre of the screen (assuming you have a standard perspective matrix).

At this stage you now have a ray destination and ray direction for a ray going through the middle of the screen (This is all I need in my engine currently). If you want to get a ray going though a different part of the screen then you can just apply some simple trigonometry to work out the new direction.

For intersection this site has a good introduction to it

http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/


Akinesis

Thanks to you two for your responses. I'll run a few test both on my collision method and abcdef idea and i'll keep you in touch.

Akinesis

Double post Sorry, maybe i should have just edit the previous ...

Before starting to fight whit the abcdef's idea (matrix freak me out a little) i've just wanted to illustrated with a short code and a video (yeay ! technology) the strange result i get. Basicly i my mind i do no complicated collision code, in fact i do none, i just compute an x and a z and draw a cube on those coordinate.

Her's my code :

private void setRayCoord(){
		
		float xStart = -(float)Math.ceil(posCam.getX());
                float yStart = -(float)Math.floor(posCam.getY());
		float zStart = -(float)Math.ceil(posCam.getZ());
		
		Vector3f origine = new Vector3f(xStart, yStart, zStart);
		
		ray.x *= 5;
		ray.z *= 5;
		
		ray.x += origine.x;
		ray.z += origine.z;
		
		picker.setPos(ray.x, yStart, ray.z);

	}


Still using the previous methods that i'll change hopefully.
And her's the result :

http://youtu.be/wy4wHkxR6ZQ

quew8

Why are you rounding xStart and zStart up? It seem's to me that could cause a problem like what you are experiencing.

Akinesis

The Math.ceil and Math.floor are to start the origin point at a round number (you don't say !) so the cube i draw will match the alignment of the other cubes. I test to draw it on the specifics coordinates for xStart, yStart and zStart and it work well. as long as i want a wired cube stick around the camera's head.

But maybe i should no round the values before calculating the coordinate of the ray ... i'll try that and edit or post back to tell you about the changes.

EDIT :
I made a few test with and without rounding (up or down) and that change basicly nothing.

I've also try to implant matrix and rotating it with the camera but for now it's not very conclusive.

quew8

Yes. In that case I recommend testing for collision with the raw values and then round up/down.

Akinesis

Ok, so i've made some test and round up the value at the very end when drawing the cube and the result is that it's working gook if i'm looking on a strictly positive direction (x and z positiv).

Otherwise i have this weird elastic movement on the cube. I'll run some test and when i have the answer i'll post back here for futher notice.

P.S: If anybody have an idea, he (or she) is more than welcome.

Akinesis

Hello ! I'm allowing myself to post back here.

I still struggling with the collision. I just can't figuring out where the problem is. I know that my calculs are good (the value that returns are goods at one or sometimes two point close) so the problème must be due to positiv/negativ and to the ceil and floor methodes.

A quick example at the value that this code gave:

Ray.x : 0.89   camera.x : 9.33  outPut.x : 13.79
Ray.z : -0.29  camera.z : 8.55  outPut.z : 7.08

Ray.x : -0.89   camera.x : 9.33  outPut.x : 4.86
Ray.z : +0.29  camera.z : 8.55  outPut.z : 10.03