| versions | 0095+ |
|---|---|
| contributors | antiplastik |
| started on | 2007-12-05 05:26 |
This method is simple, fast and accurate.
To test if an object has been clicked using a color-buffer, the steps are :
| Scene display | Buffer content |
|---|---|
| |
/** picking code taken from http://processinghacks.com/hacks:picking @author nicolas clavaud */ import processing.opengl.*; class Cube { // variables int id; // id int x, y, z, w; // position (x, y, z) and width (w) color c; // color (in scene, not buffer) // constructor public Cube(int id, int x, int y, int z, int w) { this.id = id; this.x = x; this.y = y; this.z = z; this.w = w; c = color(random(255), 250, 50); } // make the color change public void changeColor() { int r = (int)red(c); int g = (int)green(c); int b = (int)blue(c); c = color(r, 255 - g, b); } // display the cube on screen public void display(PGraphics ecran) { ecran.fill(c); drawCube(ecran); } // draw the cube in the buffer public void drawBuffer(PGraphics buffer) { color idColor = getColor(id); buffer.fill(idColor); drawCube(buffer); } private void drawCube(PGraphics g) { g.pushMatrix(); g.translate(x, y, z); g.box(w); g.popMatrix(); } } PGraphics buffer; // buffer Cube[] cubes; // cubes float a = 0; // angle to make the scene rotate void setup() { // we use OPENGL for display size(200, 200, OPENGL); // buffer is created using applet dimensions buffer = createGraphics(width, height, P3D); // put cubes randomly in the scene cubes = new Cube[10]; for (int i = 0; i < cubes.length; i++) { cubes[i] = new Cube( i, // identifiant -15 + (int)random(30), // position x -15 + (int)random(30), // position y -15 + (int)random(30), // position z 5 + (int)random(15) // taille ); } } void draw() { background(255); camera(-20, -20, 50, 0, 0, 0, 0, 1, 0); rotateY(a); lights(); for (int i = 0; i < cubes.length; i++) { cubes[i].display(this.g); } a += 0.002; if (a > TWO_PI) a -= TWO_PI; } void mouseClicked() { // draw the scene in the buffer buffer.beginDraw(); buffer.background(getColor(-1)); // since background is not an object, its id is -1 buffer.noStroke(); buffer.camera(-20, -20, 50, 0, 0, 0, 0, 1, 0); buffer.rotateY(a); for (int i = 0; i < cubes.length; i++) { cubes[i].drawBuffer(buffer); } buffer.endDraw(); // get the pixel color under the mouse color pick = buffer.get(mouseX, mouseY); // get object id int id = getId(pick); // if id > 0 (background id = -1) if (id >= 0) { // change the cube color cubes[id].changeColor(); } } // id 0 gives color -2, etc. color getColor(int id) { return -(id + 2); } // color -2 gives 0, etc. int getId(color c) { return -(c + 2); }