/** 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(); }