DirectX - Picking



The traditional method which is needed to perform the action of picking relies on the technique is called ray-casting. The user can shoot a ray from the camera position through the selected point which the aspect of near plane of the required frustum which intersects the resulting ray. The first object intersected by the way is considered as the ray of object which is picked.

We will be creating the Picking Demo project as mentioned in the figure below −

Picking

Here, you can see that only the required part is hand-picked or the picking process is created.

To pick the respective object, the user should convert the selected screen pixel into the mentioned camera’s view space. The screen-space coordinate is used to view the required space with the conversion of pixel position. Now let us focus on the process of picking the ray. The ray starts with the given point and extends the direction until it reaches the point of infinity. The specialized class called SlimDX provides the required position and the maintained direction properties which is referred to as intersection tests with bounding boxes, spheres, triangles and planes.

Normalized Device Coordinates

Normalized device coordinates map the screen with respect to x and y coordinates within the range of [-1,1].

The parameters which are used for transformation into the required world space by transforming the origin to the mentioned direction of vectors include ray with the inverse of camera’s view matrix. The code snippet which can be used is mentioned below −

public Ray GetPickingRay(Vector2 sp, Vector2 screenDims) {
   var p = Proj;
   // convert screen pixel to view space
   var vx = (2.0f * sp.X / screenDims.X - 1.0f) / p.M11;
   var vy = (-2.0f * sp.Y / screenDims.Y + 1.0f) / p.M22;
   var ray = new Ray(new Vector3(), new Vector3(vx, vy, 1.0f));
   var v = View;
   var invView = Matrix.Invert(v);
   var toWorld = invView;
   ray = new Ray(Vector3.TransformCoordinate(ray.Position, toWorld),    
      Vector3.TransformNormal(ray.Direction, toWorld));
   ray.Direction.Normalize();
   return ray;
}

Picking an Object in the 3D Scene

Now we will focus on picking the object with respect to the 3D scene to select a triangle from our car mesh in this example. This changes our OnMouseDown override slightly, consider the code snippet which is mentioned below −

protected override void OnMouseDown(object sender, MouseEventArgs mouseEventArgs) {
   if (mouseEventArgs.Button == MouseButtons.Left) {
      _lastMousePos = mouseEventArgs.Location;
      Window.Capture = true;
   } 
   else if (mouseEventArgs.Button == MouseButtons.Right) {
      Pick(mouseEventArgs.X, mouseEventArgs.Y);
   }
}
Advertisements