Hi, everybody, I further modified the code above and added GUI elements.
What I want to do are:
1. show the ID number of each point at the centre of each point
2. show the ID number in the "text area" GUI when clicking a point
The problems of the code below are:
1. the text for the ID number was shown somewhere away from the points in the 3D space
2. when a point is clicked, the ID of the point is no longer returned (or a "-1" ID num for background is always returned)
3. only when the gui() function inside the draw() block is disabled, can the ID of point be returned correctly
I assume it might be related to transform matrix due to the use of PeasyCam and ControlP5 library. Or the wrong use of screenX function... But I haven't figured out the reason yet.
So, I'd appreciate if anybody can kindly advise on the source of problem.
Thank you in advance!
- /*----------------------------------------------------------------------------------------
orginial codes:
http://wiki.processing.org/w/Picking_with_a_color_buffer
Thanks for quarks' additional advices!
https://forum.processing.org/topic/how-to-display-xyz-coordinates-of-a-point-in-3d-scene
-----------------------------------------------------------------------------------------*/
import processing.opengl.*;
import controlP5.*; // GUI library
ControlP5 cp5;
Textarea myTextarea;
import peasy.*; // camera library
PeasyCam cam;
PGraphicsOpenGL buffer;
PMatrix3D currCameraMatrix;
PGraphics3D g3;
PFont myFont;
Pt[] pts;
//_____________________________________________________________________________________
void setup(){
size(1000,500,OPENGL);
smooth(8);
cam = new PeasyCam(this,500);
g3 = (PGraphics3D)g;
myFont = createFont("Arial",10);
textFont(myFont);
// buffer is created using applet dimensions
buffer = (PGraphicsOpenGL)createGraphics(width, height, P3D);
// initiate random pts
pts = new Pt[10];
for (int i=0; i<pts.length; i++){
pts[i] = new Pt(i, // pt id
random(-150,150), // pt x
random(-150,150), // pt y
random(-150,150), // pt z
random(20,50) // pt size
);
}
cp5 = new ControlP5(this); // initiate GUI objects
cp5.setAutoDraw(false); // fix controlP5 GUI
// setup a text area GUI
myTextarea = cp5.addTextarea("txt")
.setPosition(800,50)
.setSize(150,100)
.setFont(createFont("arial",12))
.setLineHeight(14)
.setColor(color(128))
.setColorBackground(color(255,100))
.setColorForeground(color(255,100));
;
myTextarea.setText("ID : " + " ");
}
//_____________________________________________________________________________________
void draw() {
background(0);
for (int i=0; i<pts.length; i++){
pts[i].displayPt(this.g);
}
gui();
}
//_____________________________________________________________________________________
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.setMatrix(g.getMatrix());
for (int i=0; i<pts.length; i++) {
pts[i].drawBuffer(buffer);
}
buffer.endDraw();
color pick = buffer.get(mouseX, mouseY); // get the pixel color under the mouse
int id = getId(pick); // get object id
println("object ID : " + id);
myTextarea.setText("ID : " + id);
if (id >= 0) { // if id > 0 (background id = -1)
pts[id].changeColor(); // change pt color
}
}
//_____________________________________________________________________________________
// id 0 gives color -2, etc.
color getColor(int id){
return -(id + 2);
}
//_____________________________________________________________________________________
// color -2 gives 0, etc.
int getId(color pt_color){
return -(pt_color + 2);
}
//_____________________________________________________________________________________
// to make controlP5 GUI always on top of everything else
void gui(){
hint(DISABLE_DEPTH_TEST);
currCameraMatrix = new PMatrix3D(g3.camera);
camera();
cp5.draw();
g3.camera = currCameraMatrix;
hint(ENABLE_DEPTH_TEST);
}
- class Pt{
//______________________________________________________________
// variables
int id; // id
float x, y, z; // position
float pt_size; // pt size
color pt_color; // pt color (in scene, not buffer)
//______________________________________________________________
// constructor
public Pt(int id_, float x_, float y_, float z_, float pt_s_)
{
this.id = id_;
this.x = x_; this.y = y_; this.z = z_;
this.pt_size = pt_s_;
pt_color = color(random(255), random(255), random(255));
}
//______________________________________________________________
public void changeColor() {
int r = (int)red(pt_color);
int g = (int)green(pt_color);
int b = (int)blue(pt_color);
pt_color = color(255-r, 255-g, 255-b);
}
// display the pt on the screen_________________________________
public void displayPt(PGraphics ecran) {
ecran.stroke(pt_color);
drawPt(ecran);
}
// draw pt on buffer_____________________________________
public void drawBuffer(PGraphics buffer) {
color idColor = getColor(id);
buffer.stroke(idColor);
drawPt(buffer);
}
//_______________________________________________________________
private void drawPt(PGraphics g) {
g.strokeWeight(pt_size);
g.point(x,y,z);
g.text(id, screenX(x,y,z), screenY(x,y,z));
}
}