3d position in space

Started by
12 comments, last by Buckeye 8 years, 11 months ago

Hello.

I need to know the position x,y,z on the ground when I press the mouse.

I found something:


XMMATRIX P = mCam.Proj();
// Compute picking ray in view space.
float vx = (+2.0f*sx/mClientWidth - 1.0f)/P(0,0);
float vy = (-2.0f*sy/mClientHeight + 1.0f)/P(1,1);
// Ray definition in view space.
XMVECTOR rayOrigin = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
XMVECTOR rayDir = XMVectorSet(vx, vy, 1.0f, 0.0f);

If I did understand it traces a ray.So I guess I'm half way.But I don't know where I go now.

Please help me Obiwan,you're my only hope.

Thanks.

Directx11(skd jun 2010),Visual studio 2013,c++,Window7

Advertisement

Perhaps not half-way, but you're starting out correctly by converting the screen position at the mouse click to a "ray" in world coordinates.

Assuming what you call "ground" is a mesh of triangles, you're trying to determine the position in that mesh under the mouse position. As you seem to understand, that's calling "picking." You can google for further information. E.g., "pick triangle," "directx 11 picking," and various combinations of those terms.

From where you are, the next step is to determine the triangles in the ground mesh that that ray intersects. There's quite a bit of processing to do that.

Briefly:

- set a variable (e.g.) minDistance = FLT_MAX.

- for every triangle in the mesh you want to pick, determine if the ray intersects that face (triangle)

- if so, calculate the barycentric coordinates of that intersection.

- from those barycentric coordinates, calculate the world position of the intersection.

- calculate the distance from that point to the ray origin.

- if that distance is less than minDistance:

- save the (x,y,z) position calculated from the barycentric coords

- set minDistance to that calculated distance

If any intersection was found, the saved (x,y,z) position is the one you seek. If you need it, minDistance provides the distance from the camera to the picked point.

There are several approaches to speed up the process, particularly in the step determining if the ray intersects the triangle.

However, for starters, I recommend you take a look at a tutorial for picking such as this link. When you get that picking algorithm correct, if you need to speed up the process, look at ways to cull triangles before calculating the barycentric coords.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Hello.

Isn't a mesh, just a imaginary floor at the position y=0,maybe I'm gonna create it with 6 vertexes.

I don't want to find the position of a mesh but the mouse pointer on the floor.

Thanks.

Ensure RayDir.y <> 0. I.e., ensure the ray direction is not parallel to the ground (no solution.) Then:

position = RayOrigin - (RayOrigin.y/RayDir.y) * RayDir;

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Hello

It seems to work but there an issue,I gave a mesh the position(position.x,position.y,position.z),the x position seems to be correct but the z is like reversed.When I click on the bottom of the window it moves away and when I click the top it comes closer.

Thanks.

I suggest you try debugging your code. First: determine if the conversion equations are correct. That is, when you click on known positions around the "floor," do you get the correct results**? If so, move the camera around and check that the equations work for various positions/rotations of the camera. If you don't, determine what needs to be changed. If they are correct, determine where the problem occurs with mesh positioning/rendering.

** By correct results, I mean that when you click near a known point, e.g., (5, 0, 7), that the position you calculate is very close to (5, 0, 7). Set a breakpoint in your code at the appropriate place and examine the runtime values you calculate, write out debug messages with the values to your IDE output window, or write the values to a console window - choose your favorite method for verifying values.

EDIT:


Compute picking ray in view space.

Just noticed that. Unproject your mouse positions to world space.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Positions aren't good.it's worst if I move the camera.


Positions aren't good.it's worst if I move the camera.

As previously suggested:


If you don't [get correct results], determine what needs to be changed.

For a computer program to run correctly, both the data and code must be correct. To give you an idea what you'll have to do, read through this article for methods to debug your program. You'll need to check that you correctly get the mouse position. If the mouse position is correct, then check that the equations you use to convert the mouse position produce the correct results.


Unproject your mouse positions to world space.

Did you revise your code as suggested?

EDIT: To help you along a bit, a common method to get the ray origin and ray direction is:

[pseudo-code]

rayOrigin = unproject( mouse.x, mouse.y, 0 ); // get the world position at the near plane of the projection

rayDir = unproject( mouse.x, mouse.y, 1 ); // get the world position at the far plane - N.B., this is a point, not the direction

rayDir = rayDir - rayOrigin; // the direction is from the near plane to the far plane

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Hello.I'm so lost.


XMMATRIX P = camProjection;

XMVECTOR rayOrigin;
XMVECTOR rayDir;
XMVECTOR screenpoint = XMVectorSet(Mouse.x, Mouse.y, 0.0f, 0.0f);//Mouse.x=300 Mouse.y=200
rayOrigin = XMVector3Unproject(screenpoint, viewport.TopLeftX,viewport.TopLeftY,
viewport.Width,viewport.Height,viewport.MinDepth,viewport.MaxDepth,camProjection,camView,World);
		
screenpoint = XMVectorSet(Mouse.x,Mouse.y, 1.0f, 0.0f);
rayDir = XMVector3Unproject(screenpoint,viewport.TopLeftX,viewport.TopLeftY,
viewport.Width,viewport.Height,viewport.MinDepth,viewport.MaxDepth,camProjection,camView,World);
//*Breakpoint to see results
rayDir = rayDir - rayOrigin;

rayOrigin = {m128_f32=0x03e4f900 {-1.#IND0000, -1.#IND0000, -1.#IND0000, -1.#IND0000} m128_u64=0x03e4f900 {18428729679490842624, ...} ...}

rayDir = {m128_f32=0x0404fa00 {-1.#IND0000, -1.#IND0000, -1.#IND0000, -1.#IND0000} m128_u64=0x0404fa00 {18428729679490842624, ...} ...}

These are NaNs. That means either the unproject function is at fault (unlikely) or the input values are bad (degenerate viewport, degenerate transformations, parameter mixup...).

This topic is closed to new replies.

Advertisement