Game Development Reference
In-Depth Information
With the final transformation equations, we can move on to computing the pick-
ing ray that will test for objects picked by the user.
Computing the Picking Ray
A ray can be represented by the parametric equation P(t) = P + t * D, where P is a
point in the ray and D is a vector that provides the direction of the ray. In our sit-
uation, the origin of the ray is also the origin of the view space, so P = (0, 0, 0). If
P is a point on the project window to shoot the picking ray through, then we can
solve for D with the following equation.
The following code is used to compute the picking ray for intersection testing.
private PickingRay ComputePickingRay(Entity entity, int x, int y)
{
float viewportWidth = device.Viewport.Width;
float viewportHeight = device.Viewport.Height;
float projection00 = device.Transform.Projection.M11;
float projection11 = device.Transform.Projection.M22;
float pX = ((( 2.0F * x) / viewportWidth) - 1.0F) / projection00;
float pY = (((-2.0F * y) / viewportHeight) + 1.0F) / projection11;
Matrix invWorldView = Matrix.Identity;
invWorldView.Translate(entity.Position);
invWorldView.Multiply(device.Transform.View);
invWorldView.Invert();
Vector3 rayDirection = new Vector3(pX, pY, 1.0f);
return new PickingRay(rayDirection, invWorldView);
}
After computing the picking ray, we must also transform it into world space to
correctly represent the objects in the scene. Transforming the picking ray to world
space is done in the constructor of the following struct. The transformation matrix
supplied to the constructor is the inverse world-view matrix that was created when
the picking ray was computed. The following code is used to transform the picking
ray into world space so that the ray and the objects are in the same coordinate system.