Jump to content
  • Advertisement
Sign in to follow this  
OppiXP

[SlimDX] Picking a point on a plane

This topic is 3044 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello guys, I am stuck on picking a certain point on a plane which is located anywhere on the z axis of my coordinate system. The coordinate system can be zoomed and rotated by using my chase camera. Here is what it looks like: Coordinate system The problem is that my coordinates seem to be messed up and I cannot figure out why. The camera is rotated and zoomed by setting up the projection and view matrices in this way:

projectionMatrix = Matrix.PerspectiveFovLH(
             (float)Math.PI / 4,
             (float)ClientRect.Width / ClientRect.Height,
             0.001f,
             20f);

Matrix trans = Matrix.Translation(0.0f, 0.0f, camDistance);
Matrix rot = Matrix.Multiply(Matrix.RotationY(camAngleHorizontal), Matrix.Identity);
rot = Matrix.Multiply(Matrix.RotationX(camAngleVertical), rot);
viewMatrix = Matrix.Multiply(trans, rot);
viewMatrix = Matrix.Invert(viewMatrix);



Rotating the camera around my coordinate system works fine. I use this code to determine if a ray intersects a certain plane:

protected override void MouseMove(System.Windows.Forms.MouseEventArgs e)
{
  base.MouseMove(e);
  Plane plane = new Plane(new Vector3(1f, 0, 0), 0);
 
  DX.Instance.SetWorldMatrix(Matrix.Identity, Matrix.Identity);

  Vector3 nearPlane = Vector3.Unproject(new Vector3((float)e.X, (float)e.Y, currentCamDistance), DX.Instance.ViewPort, DX.Instance.CurrentProjectionMatrix, DX.Instance.CurrentViewMatrix, DX.Instance.CurrentWorldMatrix);

  Vector3 farPlane = Vector3.Unproject(new Vector3((float)e.X, (float)e.Y,  20f), DX.Instance.ViewPort, DX.Instance.CurrentProjectionMatrix, DX.Instance.CurrentViewMatrix, DX.Instance.CurrentWorldMatrix);

  Vector3 direction = farPlane - nearPlane;
  direction.Normalize();

  Ray ray = new Ray(nearPlane, direction);
  float distance;

  Console.WriteLine(Ray.Intersects(ray, plane, out distance));
}



Sometimes it seems that the plane is located flat in the upper right corner of the screen... Can please anybody have a look at this and tell me what is wrong? I also tried intersection using a BoundingBox: BoundingBox box = new BoundingBox(new Vector3(0), new Vector3(1)); It seems that the coordinates are not translated correctly. Any help is appreciated! Best Regards OppiXP

Share this post


Link to post
Share on other sites
Advertisement
Hello Buckeye,

thanks for your reply. I tried this but it was not successful. The bounding box still seems to be somewhere on the screen but not where I expect it to be.

Are BoundingBoxes located in Worldspace?

Regards

OppiXP

Share this post


Link to post
Share on other sites
Quote:
I tried this but it was not successful..The bounding box still seems to be somewhere on the screen but not where I expect it to be.

That's not much info to help you with. You haven't posted any code for whatever you're doing with a bounding box, what you expect or what values you're getting.

It sounds like you need to take one step at a time. Pick one of your problems and work on it.

For instance, orient the camera such that your world origin is in the center of the screen (or close). If you unproject the coordinates for the center of the screen, is your camera position + camera-distance*ray-direction close to (0,0,0)?
Quote:
Are BoundingBoxes located in Worldspace?

A BoundingBox is just a structure. It can be used as you see fit.

Share this post


Link to post
Share on other sites
Hi,

maybe I tell you what I want to achieve. The problem is that I have no idea how to make this work correctly.

I am currently working on a 3D view of some measuring data. The user can rotate the camera around the signals and he can change the distance of the camera to the signals. The world's center remains at (0,0,0), only the camera is moved around using the code I posted above. So the camera always looks at (0,0,0) with varying distance. The signals are rendered as linestrips at certain z-positions. The world coordinates never exceed -1 and 1 in any direction. This part works perfectly already. Only one signal can be selected at any time.

The user should now be able to place some markers on the samples of this signal using the mouse as illustrated in the image below:



The code for picking mentioned earlier does not work correctly and I do not understand why. See the near vector: It always returns values between -0.5 and 0.5 regardless how far away the camera is located from the origin. If the camera was moved 5 units back from the center I would assume X coordinates ranging from -5 to 5 when moving the mouse to the left and right edge of the screen and the camera was not rotated around the signals.

If this worked the next idea would be to place a plane at the z position of the selected signal spanning the whole x and y axis and then cast a ray for intersection test with that plane. Is it possible to determine where exactly a ray hit a plane?

Any help is appreciated as I am really stuck on this.

Best regards






Share this post


Link to post
Share on other sites
Quote:
See the near vector: It always returns values between -0.5 and 0.5 regardless .. of the camera position

Are you using (mouseX, mouseY, 0) and (mouseX, mouseY, 1) to unproject the mouse position and get the direction vector?

Also, are you trying to intersect the z-plane? Is so, shouldn't your plane be [(0,0,-1),0]? I'm assuming positive Z looking into the screen in your image. In any case, you can calculate the intersection without that.

Once you get that straightened out, then you can find the point in the plane (this is off the top of my head):

dir = far-near

You want: point(someX, someY, 0) = near+dir*D (a point in the vector under the mouse)

D is some unknown distance from the near plane. You know you want a point for which Z=0.

point = (nearX+dirX*D, nearY+dirY*D, nearZ+dirZ*D)

So nearZ + dirZ*D = 0, or D = -nearZ/dirZ

Substitute D back in nearX+dirX*D, etc. to get the point in the plane.

Share this post


Link to post
Share on other sites
Seems to me to pick a data point, you may be best running a function which finds the closest 3D data point to the 3D mouse ray line segment (line between back and front of screen) at the XY mouse point.

Anyway, if you want a plane intersection,

Define your Slimdx plane [VB.NET]

' define point on plane, and set the up direction
Dim cPlane As Plane = New Plane(New Vector3(X,Y,Z), New Vector3(0, 0, 1))

Unproject the mouse X Y point at the near V3Near and far plane V3Far on the screen. AS Buckeye quotes us "Try unprojecting (x,y,0) for the near plane and (x,y,1) for the far plane"

and then use the following slimdx function.

'find intersection of line and plane
Plane.Intersects(cPlane, v3Near, v3Far, intersectionPoint)

End Function

Share this post


Link to post
Share on other sites
Hey guys,

thanks for your help! I really appreciate it!

I tried Buckeyes hint but again no luck. This is what I have so far:



// The size of the coordinate system was doubled before so I set the world matrix accordingly. The coordinate sytem is now centered.

DX.Instance.SetWorldMatrix(Matrix.Scaling(2f, 2f, 2f), Matrix.Translation(-1, -1, -1));

// Unproject near plane
Vector3 nearPlane = Vector3.Unproject(new Vector3(e.X, e.Y, 0), DX.Instance.ViewPort, DX.Instance.CurrentProjectionMatrix, DX.Instance.CurrentViewMatrix, DX.Instance.CurrentWorldMatrix);

// Unproject far plane
Vector3 farPlane = Vector3.Unproject(new Vector3(e.X, e.Y, 1), DX.Instance.ViewPort, DX.Instance.CurrentProjectionMatrix, DX.Instance.CurrentViewMatrix, DX.Instance.CurrentWorldMatrix);

Vector3 direction = farPlane - nearPlane;
direction.Normalize();

position = new Vector3(
nearPlane.X + direction.X * (-nearPlane.Z / direction.Z),
nearPlane.Y + direction.Y * (-nearPlane.Z / direction.Z),
nearPlane.Z + direction.Z * (-nearPlane.Z / direction.Z));

Console.WriteLine(position);





It seems that the distance and angle of the camera is not taken into account.

If I understand this correctly the position vector should return values at z = 0 which is the center of the coordinate system. So if I move the mouse pointer left and right at this z position with camera angles all zero, position.X should return -1 if I hit the left boundary and 1 if I hit the right boundary but I get values ranging from 0.64 to 0.3.

I think we are getting close but there is still something I did wrong...

The other approach using the plane does not work either.

Regards

OppiXP

[Edited by - OppiXP on February 11, 2010 8:21:49 AM]

Share this post


Link to post
Share on other sites
Quote:
It seems that the distance and angle of the camera is not taken into account.

Hmm. That should be taken care of in the Unproject call using the current matrices. Do you set those before you do the Unproject? And do you use the same world matrix to render the data?

You should have something like:

GetUserData (mouse-click)
SetProjection and World matrix.
CalcClickPosition.
Render data and click position

Share this post


Link to post
Share on other sites
Yes, the view and projection matrices are always stored in my DX singleton as you can see references to it in my code. The world matrix is set explicitely before unprojecting and has the same scale and translation factors used during rendering the axes. Funny thing though if I assign the identity matrix to the view and projection matrices the coordinates are correct, ranging from -1 to 1 in either x and y direction. Maybe there is something wrong in the unproject method in SlimDX?

I have no clue what is going wrong. As far as I understand the whole unproject thing should return coordinates from -1 to 1 as long as I stay inside the "cube" of my coordinate system.

This drives me nuts as I have tried at least 5 different tutorials I found and none of them worked.

Could it be a problem that the distance of the camera to the coordinate system is always negative? The range is from -19 to -1. Maybe the calculation of the view matrix is not correct. Could you please have a look at it?

Many thanks in advance!!!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!