/** Create a new zone picker. SMT.init() must have been called first. */
 public ZonePicker() {
   renderer = SMT.getRenderer();
   this.picking_context =
       (PGraphics3D)
           SMT.getApplet().createGraphics(renderer.width, renderer.height, PConstants.P3D);
   int SIZEOF_INT = Integer.SIZE / 8;
   buffer = ByteBuffer.allocateDirect(SIZEOF_INT);
   currentColor = START_COLOR;
 }
  /**
   * Get the Zone under the specified coordinates.
   *
   * @param x x coordinate of the specified pixel
   * @param y y coordinate of the specified pixel
   * @return If there is a Zone at the specified coordinates, that zone, otherwise null.
   */
  public Zone pick(int x, int y) {
    // clamp x and y
    if (y >= picking_context.height) y = picking_context.height - 1;
    if (x >= picking_context.width) x = picking_context.width - 1;
    if (y < 0) y = 0;
    if (x < 0) x = 0;

    PGL pgl = picking_context.beginPGL();
    int pixel;
    // force fallback until 2.0b10
    if (!SMT.fastPickingEnabled() || pgl == null) {
      // really slow way(max 70 fps on a high end card vs 200+ fps with readPixels), with loadPixels
      // at the end of render()
      pixel = picking_context.pixels[x + y * picking_context.width];
    } else {
      buffer.clear();
      pgl.readPixels(x, picking_context.height - y, 1, 1, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buffer);
      pixel = buffer.getInt();
    }
    picking_context.endPGL();

    if (zoneMap.containsKey(pixel)) {
      // if mapped it is either a Zone or null (background)
      Zone picked = zoneMap.get(pixel);
      Zone current = picked;
      while (current != null) {
        if (current.stealChildrensTouch) return current;
        current = current.getParent();
      }
      return picked;
    } else return null;
  }
 /** Prepare the picking graphics context for picking */
 public void render() {
   // set up for rendering the pick buffer
   renderer.pushDelegate(picking_context);
   renderer.beginDraw();
   renderer.clear();
   renderer.ortho();
   // render the pick buffer
   SMT.getRootZone().invokePickDraw();
   renderer.endDraw();
   renderer.flush();
   // If fast picking disabled, use loadPixels() which is really slow (max 70 fps on a high end
   // card vs 200+ fps with readPixels) as a backup.
   PGL pgl = renderer.beginPGL();
   if (!SMT.fastPickingEnabled() || pgl == null) renderer.loadPixels();
   renderer.endPGL();
   renderer.popDelegate();
 }