bild-3

Simple picking in 3D

bild-3

Thought I’d post this little hack. I picked up the Terzidis book Algorithms for Visual Design (using Processing) and found a version of my own little 3D picking hack and thought that my hack might be ok. I never saw this as anything but a quick hack, but it has helped me alot, still does. I thought that it hopefully could help some people having difficulties solving the picking problem the ”real” (and hard) way. It would have helped me.
Heres the code:

/**
* Selecting_objects_3D – easy way
* by Johan Wastring
*
* Quick and dirty way f picking in 3D if you have less
* than 200 objects in a list. It’s not fancy,
* but it works on small numbers of objects.
* Run sketch and pick with mouse to change the color.
*
*/
import processing.opengl.*;
int numOfShapes = 5;
Shape[] myShapes = new Shape[numOfShapes];
void setup() {
noStroke ();
size (400, 400, OPENGL);
// create your shapes in a list
for (int i = 0; i < numOfShapes; i ++) {
myShapes[i] = new Shape(i*20, 0, 0);
}
}
void draw() {
background(255);
// Call theSelector before you draw your shapes
theSelector();
// draw your shapes
for (int i = 0; i < numOfShapes; i ++) {
myShapes[i].display();
}
// a Camera well placed after all above
camera(
40, 0, -120,
40, 0, 0,
0, 1, 0 );
}
// the nice Selector
void theSelector() {
// SELECTION BY MOUSE
int tolerance = 10; // to make it easy to pick the shape
for ( int i = 0; i < numOfShapes; i ++) {
// get objects screenX coords
float checkX = myShapes[i].getScreenX();
// if it matches the mouseX decently proceed to get Y
if (checkX >= (mouseX-tolerance) && checkX <= (mouseX+tolerance)) {
boolean yes = true;
if (yes == true) {
// get the Y one
float checkY = myShapes[i].getScreenY();
// if that one matches decently with the mouseY do something with that shape
if (checkY >= (mouseY-tolerance) && checkY <= (mouseY+tolerance)) {
// make new cursor indicating selection is possible
cursor(MOVE);
if (mousePressed == true && mouseButton == LEFT) {
// here the action happens if it gets this far
myShapes[i].setSelected(i);
}
}
}
}
}
}
class Shape {
float x, y, z;
boolean isSelected = false;
Shape(float inX, float inY, float inZ) {
x = inX;
y = inY;
z = inZ;
}
void display(){
pushMatrix();
translate(x, y, z);
rotateX(HALF_PI/2);
stroke(255);
if (isSelected == true) {
fill(255, 0, 0);
}
else {
fill(0, 0, 255);
}
box(10);
popMatrix();
}
void setSelected(int i) {
this.isSelected = true;
println(”Got it ” + i);
}
float getScreenX() {
float f = screenX(x, y, z);
return f;
}
float getScreenY() {
float f = screenY(x, y, z);
return f;
}
}