OK so I am trying to fire a Ray at a disc and getting the interection of the two. Well actually, I'm firing it at a plane that sits on the surface of the disc.
My world initialisation is as follows:
1. I read the disc model file from a .x file.
2. I use bounding sphere to retrieve the model centre so I can shift the centre of the disc to the origin.
3. The disc then appears at the origin with the faces of the disc parallel to the x = 0 plane requiring rotation in Y to see the face of it or moving cam position to the x-axis and looking at the origin. I chose the latter. The diameter of the disc by the way, is 150 units.
So my draw code looks like this.
| Vector3 eyePosition = new Vector3(1000.0f, 0.0f, 0.0f); //move to positive x-axis |
| |
| float aspectRatio = GraphicsDevice.Viewport.AspectRatio; |
| |
| Matrix world = Matrix.CreateTranslation(-1.0f * modelCenter); //move to origin before drawing (this happens after use clicking) |
| |
| Matrix view = Matrix.CreateLookAt(eyePosition, Vector3.Zero, new Vector3(0.0f,1.0f,0.0f)); //say where to look at |
| |
| Matrix projection = Matrix.CreatePerspectiveFieldOfView(0.2f, aspectRatio, 990.0f, 1010.0f); //perspective matrix |
| |
| MouseState mouse = Mouse.GetState(); |
| |
| if (mouse.LeftButton == ButtonState.Pressed) |
| { |
| Vector3 nearsource = new Vector3((float)mouse.X, (float)mouse.Y, 0f); |
| |
| Vector3 farsource = new Vector3((float)mouse.X, (float)mouse.Y, 1f); |
| |
| Matrix intersectworld = Matrix.CreateTranslation(0.0f, 0, 0); //use origin as reference |
| |
| Vector3 nearPoint = GraphicsDevice.Viewport.Unproject(nearsource, projection, view, intersectworld); |
| |
| Vector3 farPoint = GraphicsDevice.Viewport.Unproject(farsource, projection, view, intersectworld); |
| |
| Vector3 direction = Vector3.Normalize(farPoint-nearPoint); |
| |
| Ray ray = new Ray(nearPoint, direction); |
| |
| Plane testSurface = new Plane(1.0f, 0.0f, 0.0f, 0.0f); //use x=0 plane to test intersection of disc surface plane at origin |
| |
| float? distanceToIntersect = ray.Intersects(testSurface); |
| |
| Vector3 vectorToIntersection = Vector3.Multiply(direction, distanceToIntersect.Value); |
| Vector3 intersectpoint = nearPoint + vectorToIntersection; |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
Now I am nearly 7 times the diameter of the disc away from it and consequently have a very thin field of view. To test that my intersection points were more-or-less right I used the strategy of clicking as close to the centre of the disc as possible. That is, fire a ray down the x-axis effectively. y and z components for nearPoint and farPoint values should then be very close to zero with the x components corresponding to the x-planes that for this situation represent the near and far planes. The x-values return correctly. The y's and z's do not.
A sample of points when clicking the centre of the disc is as follows
nearPoint = {X:10 Y:-157.7261 Z:-907.8282}
farPoint = {X:-10 Y:-160.9125 Z:-926.1682}
As you can see, the y and z values are orders of magnitude greater than what they should be. I can't see anything wrong with my transformations so I don't know what's going on.
In case you are suspicious that the modelCentre offset may have something to with it the value is {X:4.53069 Y:-2.943224 Z:-6.365313} so it's not that either as the offset is way too small.