Picking Utility

For newbies who have a hardtime getting picking to work… :slight_smile:

Usage:

// rendering
drawScene();

// picking
Picking.begin();
drawScene();
List<Integer> hits = Picking.end();

Class sourcecode:

import static org.lwjgl.opengl.GL11.*;

import java.util.List;
import java.nio.IntBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.glu.GLU;

public class Picking
{
   private static final IntBuffer hitBuffer = BufferUtils.createIntBuffer(128);

   private static final FloatBuffer matrix = BufferUtils.createFloatBuffer(4 * 4);



   /**
    * BEGIN
    */

   public static final void begin()
   {
      glSelectBuffer(hitBuffer);
      glRenderMode(GL_SELECT);

      // modify proj-mat
      glMatrixMode(GL_PROJECTION);
      glGetFloat(GL_PROJECTION_MATRIX, matrix);
      glLoadIdentity();
      GLU.gluPickMatrix(Mouse.getX(), Mouse.getY(), 1, 1, yourViewportValuesArrayHere);
      glMultMatrix(matrix);
      glMatrixMode(GL_MODELVIEW);
   }



   /**
    * END
    */

   public static final List<Integer> end()
   {
      int hits = glRenderMode(GL_RENDER);

      // restore proj-mat
      glMatrixMode(GL_PROJECTION);
      glLoadMatrix(matrix);
      glMatrixMode(GL_MODELVIEW);

      // process
      return Picking.getNearestNames(hits);
   }



   /**
    * NEAREST NAMES
    */

   private static final List<Integer> getNearestNames(int hits)
   {
      List<Integer> names = new ArrayList<Integer>();

      int absolute_min = Integer.MAX_VALUE;

      for (int i = 0; i < hits; i++)
      {
         // how many names for this hit
         int count = hitBuffer.get();

         // store min distance
         int min = hitBuffer.get();

         // ignore max distance
         hitBuffer.get();

         // found hit that was nearer than previous
         if (min < absolute_min)
         {
            absolute_min = min;

            // remove all previous names
            names.clear();
         }

         // skip: min > absolute_min
         // allow: min == absolute-min
         if (min > absolute_min)
         {
            // skip hit-names if not nearest hit
            hitBuffer.position(hitBuffer.position() + count);

            continue;
         }

         // add names
         for (int j = 0; j < count; j++)
         {
            // read name
            int name = hitBuffer.get();

            // add to names
            names.add(new Integer(name));
         }
      }

      // reset hit-buffer
      hitBuffer.clear();

      return names;
   }
}

I hope I help out at least 1 person with this :slight_smile:

I wrote a picking class myself as well. It’s not as neat as the above, but it’s always good to have a second example :slight_smile:

http://user.cs.tu-berlin.de/~schabby/PickingExample.java

That’s cool from you, very useful for a name based picking.
Thanks.

I see everywhere name and color picking, but I cant find a “calculated ray picking exemple”.
Please, does anyone have a working exemple for ray picking ?
I mean : getting a ray with 2 gluUnProjects and calculating the intersection (x,y,z world coordinates) between an object (ie. the y=0 plane) and the ray comming from the eye (gluLookAt).

Any feedback and/or source input much appreciated :wink: